常州上位机培训

常州机器视觉培训

常州机器人培训

江苏和讯自动化设备有限公司欢迎您!
  • 和讯PLC,电工培训中心优势,名师团队一对一教学.
热门课程
联系方式
  • 常州和讯自动化培训中心
  • 常州市新北区太湖东路府琛大厦2号楼307-1室,307-2室(常州万达广场对面)
  • 电话:0519-85602926
  • 手机:15861139266 13401342299
当前位置:网站首页 > 新闻中心 新闻中心
介绍一个OpenCV中的非常有用的函数-常州机器视觉学习,常州上位机学习
日期:2024-3-11 17:01:47人气:  标签:常州机器视觉学习 常州上位机学习

在以前,常用的方法是”是先调用 cv::findContours() 函数(传入cv::RETR_CCOMP 标志),随后在得到的连通区域上循环调用 cv::drawContours() “


比如,我在GOCVHelper中这样进行了实现



//寻找最大的轮廓

    VP FindBigestContour(Mat src){    

        int imax = 0; //代表最大轮廓的序号

        int imaxcontour = -1; //代表最大轮廓的大小

        std::vector<std::vector<Point>>contours;    

        findContours(src,contours,CV_RETR_LIST,CV_CHAIN_APPROX_SIMPLE);

        for (int i=0;i<contours.size();i++){

            int itmp =  contourArea(contours[i]);//这里采用的是轮廓大小

            if (imaxcontour < itmp ){

                imax = i;

                imaxcontour = itmp;

            }

        }

        return contours[imax];

    }

    //寻找并绘制出彩色联通区域

    vector<VP> connection2(Mat src,Mat& draw){    

        draw = Mat::zeros(src.rows,src.cols,CV_8UC3);

        vector<VP>contours;    

        findContours(src.clone(),contours,CV_RETR_LIST,CV_CHAIN_APPROX_SIMPLE);

        //由于给大的区域着色会覆盖小的区域,所以首先进行排序操作

        //冒泡排序,由小到大排序

        VP vptmp;

        for(int i=1;i<contours.size();i++){

            for(int j=contours.size()-1;j>=i;j--){

                if (contourArea(contours[j]) < contourArea(contours[j-1]))

                {

                    vptmp = contours[j-1];

                    contours[j-1] = contours[j];

                    contours[j] = vptmp;

                }

            }

        }



在OpenCV3中有了新的专门的函数 cv::connectedComponents() 和函数 cv::connectedComponentsWithStats()


定义:



int  cv::connectedComponents (

    cv::InputArrayn image,                // input 8-bit single-channel (binary)

    cv::OutputArray labels,               // output label map

    int             connectivity = 8,     // 4- or 8-connected components

    int             ltype        = CV_32S // Output label type (CV_32S or CV_16U)

    );

int  cv::connectedComponentsWithStats (

    cv::InputArrayn image,                // input 8-bit single-channel (binary)

    cv::OutputArray labels,               // output label map

    cv::OutputArray stats,                // Nx5 matrix (CV_32S) of statistics:

                                                          // [x0, y0, width0, height0, area0;

                                                          //  ... ; x(N-1), y(N-1), width(N-1),

                                                           // height(N-1), area(N-1)]

    cv::OutputArray centroids,            // Nx2 CV_64F matrix of centroids:

                                                           // [ cx0, cy0; ... ; cx(N-1), cy(N-1)]

    int             connectivity = 8,     // 4- or 8-connected components

    int             ltype        = CV_32S // Output label type (CV_32S or CV_16U)

    );



其中,新出现的参数


stats:长这样

1.png

分别对应各个轮廓的x,y,width,height和面积。注意0的区域标识的是background


而centroids则对应的是中心点


而label则对应于表示是当前像素是第几个轮廓


例子:


对于图像

1710135211.png

 Mat img = cv::imread( "e:/sandbox/rect.png",0); 

    cv::Mat  img_edge, labels, img_color, stats,centroids;

    cv::threshold(img, img_edge, 128, 255, cv::THRESH_BINARY);

    bitwise_not(img_edge,img_edge);

    cv::imshow("Image after threshold", img_edge);

    int i, nccomps = cv::connectedComponentsWithStats (

        img_edge, labels,

        stats, centroids

        );

    cout << "Total Connected Components Detected: " << nccomps << endl;

    vector<cv::Vec3b> colors(nccomps+1);

    colors[0] = Vec3b(0,0,0); // background pixels remain black.

    for( i = 1; i < nccomps; i++ ) {

        colors[i] = Vec3b(rand()%256, rand()%256, rand()%256);

        if( stats.at<int>(i, cv::CC_STAT_AREA) < 200 )

            colors[i] = Vec3b(0,0,0); // small regions are painted with black too.

    }

    img_color = Mat::zeros(img.size(), CV_8UC3);

    for( int y = 0; y < img_color.rows; y++ )

        for( int x = 0; x < img_color.cols; x++ )

        {

            int label = labels.at<int>(y, x);

            CV_Assert(0 <= label && label <= nccomps);

            img_color.at<cv::Vec3b>(y, x) = colors[label];

        }

    cv::imshow("Labeled map", img_color);

    cv::waitKey();


注意:


1、对于OpenCV来说,白色代表有数据,黑色代表没有数据,所以图像输入之前要转换成”黑底白图“


2、看labels 和 stats,其中第1 2 6 个的面积小于200

3.png

而labels中

4.gif

完全对的上号,结果为

1710135247.png

本文网址:
下一篇:没有资料

相关信息:
版权所有 CopyRight 2006-2017 江苏和讯自动化设备有限公司 电话:0519-85602926 地址:常州市新北区太湖东路府琛大厦2号楼307-1室,307-2室
ICP备14016686号-2 技术支持:常州鹤翔网络
本站关键词:常州电工培训 常州电工证 常州变频器培训 常州触摸屏培训 网站地图 网站标签
在线与我们取得联系