OpenCV for Ios 学习笔记(4)-标记检测1

系统 1972 0

本文原始地址: OpenCV for Ios 学习笔记(4)-标记检测1

简单的标记经常是以白色块和黑色块构成的规则图形。因为我们预先知道这些因素,所以我们可以很容易检测标记。

如图:

OpenCV for Ios 学习笔记(4)-标记检测1

首先,我们需要找到封闭的轮廓,然后在矩形轮廓里检查我们的标记。

下面是标记监测管道的处理流程:


1.把输入的图像转化成灰度图像。

2.进行二进制阈值操作(Perform binary threshold operation)。

3.检测图像轮廓。

4.搜索可能的标记。

5.检测并解码标记。

6.模拟出标记的三维姿态(形状)。


首先,我们进行 图像灰度化

cvCvtColor

 

    //灰度化

void MarkerDetector::prepareImage(const cv::Mat& bgraMat,cv::Mat& grayscale)

{

    //convert grayscale

    cv::cvtColor(bgraMat, grayscale, CV_BGR2GRAY);

}
  


其次是 图像的二值化 (Image binarization)

 

关于二值化,参考: OpenCV二值化方法

二值化操作将把我们的图像每个像素转换为黑色(零强度)或白色(烈度),首先我们需要找到轮廓,目前有许多种求阀值的方法,但是多有各自的优势和缺点。

其中既简单又快捷的方法是绝对阀值法-结果依赖于像素强度和某些阀值,即如果像素强度大于阀值,其结果将是白(255),否则将是黑(0)。

但是这个方法有个最大的缺点-它依赖于照明和软强度变化(soft intensity changes)。所以更加可取的方法是自适应阀值-最大的不同在于在以被检查的像素为圆心的半径内使用所有像素。使用平均强度来保证更加健壮的角点检测。

OpenCV学习笔记-自适应阈值化

 

    void MarkerDetector::performThreshold(const cv::Mat& grayscale,cv::Mat& thresholdImg)

{

    //输入图像

    //输出图像

    //使用 CV_THRESH_BINARY 和 CV_THRESH_BINARY_INV 的最大值

    //自适应阈值算法使用:CV_ADAPTIVE_THRESH_MEAN_C 或 CV_ADAPTIVE_THRESH_GAUSSIAN_C 

    //取阈值类型:必须是下者之一

    //CV_THRESH_BINARY,

    //CV_THRESH_BINARY_INV

    //用来计算阈值的象素邻域大小: 3, 5, 7, ...

    //

    cv::adaptiveThreshold(grayscale, thresholdImg, 255, cv::ADAPTIVE_THRESH_GAUSSIAN_C, cv::THRESH_BINARY_INV, 7, 7);

}
  


轮廓检测

 

这个函数的输出是一个一个多边形的集合,每个多边形多代表一个可能的轮廓。在这个方法中,我们忽略了尺寸小于minContoursPointAllowed的多边形,因为我们认为它们要么不是有效的轮廓,要么实在太小,不值得去检测它们。


    void MarkerDetector::findContours(const cv::Mat &thresholdImg, std::vector<std::vector<cv::Point>> &contours, int minContoursPointAllowed)

{

    //所有的轮廓

    std::vector<std::vector<cv::Point>> allContours;

    

    //输入图像image必须为一个2值单通道图像

    //检测的轮廓数组,每一个轮廓用一个point类型的vector表示

    //轮廓的检索模式

    /*

     CV_RETR_EXTERNAL表示只检测外轮廓

     CV_RETR_LIST检测的轮廓不建立等级关系

     CV_RETR_CCOMP建立两个等级的轮廓,上面的一层为外边界,里面的一层为内孔的边界信息。如果内孔内还有一个连通物体,这个物体的边界也在顶层。

     CV_RETR_TREE建立一个等级树结构的轮廓。具体参考contours.c这个demo

     */

    //轮廓的近似办法

    /*

     CV_CHAIN_APPROX_NONE存储所有的轮廓点,相邻的两个点的像素位置差不超过1,即max(abs(x1-x2),abs(y2-y1))==1

     CV_CHAIN_APPROX_SIMPLE压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标,例如一个矩形轮廓只需4个点来保存轮廓信息

     CV_CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS使用teh-Chinl chain 近似算法

     offset表示代表轮廓点的偏移量,可以设置为任意值。对ROI图像中找出的轮廓,并要在整个图像中进行分析时,这个参数还是很有用的。

     */

    cv::findContours(thresholdImg, allContours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);

    contours.clear();

    for (size_t i = 0; i < allContours.size(); i++)

    {

        int size = allContours[i].size();

        if (size > minContoursPointAllowed)

        {

            contours.push_back(allContours[i]);

        }

    }

}
  


下面是我们检测到的轮廓:

OpenCV for Ios 学习笔记(4)-标记检测1


阈值

阈值就是临界值,在PS中的阈值,实际上是基于图片亮度的一个黑白分界值,默认值是50%中性灰,即128,亮度高于128(<50%的灰)的会变白,低于128(>50%的灰)的会变黑(可以跟滤镜中的其它――高反差保留,再用阈值效果会更好)


注:该学习笔记主要翻译自Mastering OpenCV with Practical Computer Visi

 

 

OpenCV for Ios 学习笔记(4)-标记检测1


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论