美文网首页halcon视觉专栏深度学习-推荐系统-CV-NLPOpenCv
从Halcon到OpenCV(一):select_shape算子

从Halcon到OpenCV(一):select_shape算子

作者: coolTigers | 来源:发表于2019-12-10 23:56 被阅读0次

    select_shape算子是一个功能十分强大的算子,算子原型如下:

    select_shape(Regions: SelectedRegions: Features, Operation, Min, Max:)
    

    select_shape算子的功能是计算Regions中所有输入region的特征(Features),如果计算的特征在[Min,Max]区间内,则会将每一个符合要求的region(Operation = ‘and’)或者至少一个符合要求的region(Operation = 'or')复制到SelectedRegions中。


    图片1.png

    Regions:输入区域,比如connection算子的输出;
    SelectedRegions:筛选后的输出区域;
    Features:特征,常见的有:'area', 'row', 'column'等,详细内容请查询halcon算子region_features;
    Operation: 'and' 或者 'or',and是输出所有符合要求的region,'or'是只输出一个符合要求的region即可
    Min:特征的阈值下限,闭区间;
    Max:特征的阈值上限,闭区间;
    假如有如下halcon代码:

    connection(src, region)
    select_shape(region, selected_regions, 'area', 'and', min, max)
    

    对应的OpenCV代码实现如下:

    Mat labels, stats, centroids;
    connectedComponentsWithStats(src, labels, stats, centroids);
    // 相当于halcon中的select_shape算子
    selectShapeAccordingArea(labels, stats, centroids, min, max);
    

    其中selectShapeAccordingArea函数实现如下:

    enum CONNECTIONS_STATS {
        X = 0,
        Y,
        WIDTH,
        HEIGHT,
        AREA,
        STATS_INDEX_MAX
    };
    void selectShapeAccordingArea(Mat& labels, Mat& stats, Mat& centroids, int min, int max)
    {
        // 更新stats, centroids
        Mat tempStats, tempCentroids;
        vector<int> index;
        // 从1开始,不计算背景连通域
        for (int i = 1; i < stats.rows; ++i) { 
            int area = stats.row(i).at<int>(0, AREA);
            if (area >= min & area <= max) {
                tempStats.push_back(stats.row(i));
                tempCentroids.push_back(centroids.row(i));
                index.push_back(i);
            }
        }
        stats = tempStats;
        centroids = tempCentroids;
        // 更新labels
        Mat mask(labels.size(), CV_8UC1, Scalar(0));
        for (int i = 0; i < stats.rows; ++i) {
            int rectX = stats.row(i).at<int>(0, X);
            int rectY = stats.row(i).at<int>(0, Y);
            int rectWidth = stats.row(i).at<int>(0, WIDTH);
            int rectHeight = stats.row(i).at<int>(0, HEIGHT);
    
            Rect roi(rectX, rectY, rectWidth, rectHeight);
            mask(roi) = (labels(roi) == index[i]);  
        }
        Mat tempLabels;
        labels.copyTo(tempLabels, mask);
        labels = tempLabels;
    }
    

    下面进行验证:

    #include <opencv2/opencv.hpp>
    #include <iostream>
    #include <vector>
    using namespace std;
    using namespace cv;
    int main()
    {
        Mat src(5,5,CV_8UC1, Scalar(0));
        src.at<uchar>(0, 3) = 255;
        src.at<uchar>(1, 3) = 255;
        src.at<uchar>(0, 4) = 255;
        src.at<uchar>(4, 4) = 255;
        cout << "src: \n" << src << endl;
        Mat labels, stats, centroids;
        connectedComponentsWithStats(src, labels, stats, centroids);
        cout << "before, labels: \n" << labels << endl;
        cout << "before, stats: \n" << stats << endl;
        cout << "before, centroids: \n" << centroids << endl;
    
        selectShapeAccordingArea(labels, stats, centroids, 3, 4);
        cout << "after, labels: \n" << labels << endl;
        cout << "after, stats: \n" << stats << endl;
        cout << "after, centroids: \n" << centroids << endl;
    
        waitKey(0);
        return 0;
    }
    

    输出结果如下:


    image.png

    从输出结果来看,面积为一的连通域已经被过滤,labels矩阵中只剩下一个连通域,stats和centroids矩阵都保留了对应连通域的特征。

    相关文章

      网友评论

        本文标题:从Halcon到OpenCV(一):select_shape算子

        本文链接:https://www.haomeiwen.com/subject/xesngctx.html