Opencv8:halcon中select

it2022-05-05  172

Opencv8:halcon中select_shape_proto()的opencv实现【overlaps_abs】

(1)select_shape_proto()函数简介:

          select_shape_proto()是Halcon中函数,用来在区域集合中依据区域与pattern之间的相互关系筛选区域,本文中实现的是我应用较多的overlaps_abs模式,筛选依据为重叠面积的数值。

          其他关于select_shape_proto()函数的相关内容写在另一篇博客中,在此处不赘述。                   

          https://blog.csdn.net/weixin_39504171/article/details/94551925

 

(2)select_shape_proto()函数的实现思路:

         第一步,调用connectedComponents()函数对输入二值图像进行连通域分析,connectedComponents()函数的输出结果将连通域用灰度值形式进行标号,如区域1灰度值均为1,区域2灰度值均为2...;

         第二步,遍历连通域中区域,实现方式为:当提取集合中序号为i的区域时,只需要将connectedComponents()函数的输出结果进行灰度范围为[i,i]的阈值分割即可;

         第三步:对区域与pattern图像做与操作(bitwise_and()),对与操作的结果进行面积判断,如果符合设置的范围,则此区域满足要求。

 

(3)select_shape_proto()的opencv实现:

          重点在于SelectShapeProto()函数,其他相关函数可自行替换,为方便直接复制了自己封装的版本。

#include <opencv2/opencv.hpp> #include <iostream> #include <vector> #include "FunctionsHalcon.h" using namespace cv; using namespace std; 【1】指定范围的阈值分割 Mat ThresholdHalcon(Mat image, int threadmin, int threadmax) { Mat imageResult = Mat::zeros(image.size(), CV_32S); int nr = image.rows; int nc = image.cols; for(int i=0;i<nr;i++) { for (int j=0;j < nc;j++) { if( (image.at<int>(i,j) >= threadmin) && (image.at<int>(i, j)<= threadmax)) { imageResult.at<int>(i, j) = 255; } else { imageResult.at<int>(i, j) = 0; } } } return imageResult; } //【2】二值化,填充模式绘制轮廓 Mat ContoursThreshold(Mat &image,Mat &imageThreshold,vector<vector<Point>> &contours, vector<Vec4i> &hierarchy,int thread1,Scalar&color) { //阈值分割提取轮廓 threshold(image, imageThreshold, thread1, 255, THRESH_BINARY); findContours(imageThreshold, contours, hierarchy, RETR_CCOMP, CHAIN_APPROX_SIMPLE, Point()); //轮廓分级提取,并填充绘制 Mat imageresult = Mat::zeros(image.size(), CV_8UC3); int idx = 0; for (idx = 0; idx >= 0; idx = hierarchy[idx][0]) { //drawContours(imageresult, contours, idx, color, 1, 8, hierarchy); drawContours(imageresult, contours, idx, color, 1); } return imageresult; } //【3】AreaCenter:计算连通域面积 void AreaCenter( const Mat& imageThreshold, vector<int> &area, vector<int> &rows, vector<int> &cols) { Mat labels = Mat::zeros(imageThreshold.size(), CV_32S); Mat stats, centroids; int num_labels = connectedComponentsWithStats(imageThreshold, labels, stats, centroids, 8, 4); for (int i = 1; i < num_labels; i++) { Vec2d pt = centroids.at<Vec2d>(i, 0); int x = stats.at<int>(i, CC_STAT_LEFT); int y = stats.at<int>(i, CC_STAT_TOP); int area1 = stats.at<int>(i, CC_STAT_AREA); area.push_back(area1); rows.push_back(pt[0]); cols.push_back(pt[1]); } } //【4】相互关系轮廓筛选【重叠面积】 void SelectShapeProto(const Mat& thresholdImage, const Mat& PatternImage, Mat &ResultImage, int FeatureMin, int FeatureMax) { Mat labels = Mat::zeros(thresholdImage.size(), CV_32S); int num_labels = connectedComponents(thresholdImage, labels, 8, CV_32S); for (int i = 1; i <= num_labels; i++) { Mat labeli = Mat::zeros(thresholdImage.size(), CV_32S); labeli= ThresholdHalcon(labels, i, i); Mat imageAnd = Mat::zeros(thresholdImage.size(), CV_8UC1); bitwise_and(labeli, PatternImage, imageAnd); Mat And; imageAnd.convertTo(And, CV_8UC1); vector<int> area; vector<int> rows; vector<int> cols; AreaCenter(And, area, rows, cols); int areaIntersection=0; for (auto i = area.begin();i != area.end();i++) { areaIntersection = areaIntersection + *i; } if (FeatureMin < areaIntersection && areaIntersection < FeatureMax) { bitwise_or(labeli, ResultImage, ResultImage); } } } int main(int argc, char *argv[]) { //【1】图像读取 Mat image = imread("8.png", 0); Mat imagepanel = imread("9.png", 0); //【2】图像分割 Mat imageThreshold; vector<vector<Point>>contours; vector<Vec4i>hierarchy; ContoursThreshold(image, imageThreshold,contours, hierarchy, 10, Scalar(255,255,255)); ContoursThreshold(imagepanel, imagepanel, contours, hierarchy, 10, Scalar(255, 255, 255)); //【3】select_shape_proto调用 Mat imageResult = Mat::zeros(imageThreshold.size(), CV_32S); Mat Threshold; imageThreshold.convertTo(Threshold, CV_32S); SelectShapeProto(imagepanel, Threshold, imageResult, 100, 100000000); imageResult.convertTo(imageResult, CV_8UC1); //【4】结果显示 imshow(" window1", image); imshow(" window2", imagepanel); imshow(" window3", imageResult); waitKey(0); return 0; }

 

(4)处理结果:

         ①图片1:源图像

         ②图片2:pattern

         ③图片3:处理结果

        

                        


最新回复(0)