[blog 算法原理]选择轮廓(select_shape)
2015-07-16 06:05
375 查看
选择轮廓(select_shape) Halcon是一款运用广泛的图像识别和处理软件。在肤浅的接触中,它的轮廓选择算子(select_shape)给予我很深的印象。结果是往往几行代码就能够产生很好的效果: 比如要得到这样的结果
只需要
结果如下,这段代码中还有一个问题,就是计算轮廓圆的性质的方法,我这里采用的是自己想出来的方法,似乎不是很完善,需要进一步找到资料才修正。
来自为知笔记(Wiz)
只需要
read_image (Image1, 'F:/未来项目/钢管识别/FindTube/FindTube/1.jpg') rgb1_to_gray (Image1, GrayImage) threshold (GrayImage, Regions, 43, 111) connection (Regions, ConnectedRegions) select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 150, 666) select_shape (SelectedRegions, SelectedRegions1, 'circularity', 'and', 0.45, 1)当然Halcon是在背后做了许多工作的。 几行代码中,比较重要的是算子就是"select_shape"。这个算子的参数很多,我也就比较熟悉这两种。 如果我想在Opencv中也要这样的结果,就需要自己动手尝试实现。实现过程中我采用了类似的函数名表示敬意。
// selectshape.cpp : 选择轮廓 // by: jsxyhelu(1755311380) #include "stdafx.h" #include <iostream> #include "opencv2/core/core.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" using namespace std; using namespace cv; #define VP vector<Point> //用VP符号代替 vector<point> RNG rng(12345 ); //带有上下限的threshold void threshold2(Mat gray,Mat& thresh,int minvalue,int maxvalue) { Mat thresh1; Mat thresh2; threshold(gray,thresh1,43,255, THRESH_BINARY); threshold(gray,thresh2,111,255,THRESH_BINARY_INV); thresh = thresh1 & thresh2; } //寻找并绘制出联通区域 vector<VP> connection2(Mat src,Mat& draw) { draw = Mat::zeros(src.rows,src.cols,CV_8UC3); vector<VP>contours; findContours(src,contours,CV_RETR_LIST,CV_CHAIN_APPROX_SIMPLE); for (int i=0;i<contours.size();i++) { Scalar color = Scalar(rng.uniform(0,255),rng.uniform(0,255),rng.uniform(0,255)); drawContours(draw,contours,i,color,-1); } return contours; } //select_shape vector<VP> selectShapeArea(Mat src,Mat& draw,vector<VP> contours,int minvalue,int maxvalue) { vector<VP> result_contours; draw = Mat::zeros(src.rows,src.cols,CV_8UC3); for (int i=0;i<contours.size();i++) { int countour_area = contourArea(contours[i]); if (countour_area >minvalue && countour_area<maxvalue) { result_contours.push_back(contours[i]); } } for (int i=0;i<result_contours.size();i++) { Scalar color = Scalar(rng.uniform(0,255),rng.uniform(0,255),rng.uniform(0,255)); drawContours(draw,result_contours,i,color,-1); } return result_contours; } //计算轮廓的圆的特性 float calculateCircularity(VP contour) { Point2f center; float radius = 0; minEnclosingCircle((Mat)contour,center,radius); //以最小外接圆半径作为数学期望,计算轮廓上各点到圆心距离的标准差 float fsum = 0; float fcompare = 0; for (int i=0;i<contour.size();i++) { Point2f ptmp = contour[i]; float fdistenct = sqrt((float)((ptmp.x - center.x)*(ptmp.x - center.x)+(ptmp.y - center.y)*(ptmp.y-center.y))); float fdiff = abs(fdistenct - radius); fsum = fsum + fdiff; } fcompare = fsum/(float)contour.size(); return fcompare; } //select_shape vector<VP> selectShapeCircularity(Mat src,Mat& draw,vector<VP> contours,float minvalue,float maxvalue) { vector<VP> result_contours; draw = Mat::zeros(src.rows,src.cols,CV_8UC3); for (int i=0;i<contours.size();i++) { float fcompare = calculateCircularity(contours[i]); if (fcompare >=minvalue && fcompare <=maxvalue) { result_contours.push_back(contours[i]); } } for (int i=0;i<result_contours.size();i++) { Scalar color = Scalar(rng.uniform(0,255),rng.uniform(0,255),rng.uniform(0,255)); drawContours(draw,result_contours,i,color,-1); } return result_contours; } int _tmain(int argc, _TCHAR* argv[]) { Mat src; Mat gray; Mat thresh; Mat draw_connection; Mat draw_area; Mat draw_circle; vector<VP>contours_connection; vector<VP>contours_area; vector<VP>contours_circle; vector<VP>contours_tmp; //read_image (Image1, 'F:/未来项目/钢管识别/FindTube/FindTube/1.jpg') src = imread("1.jpg"); //rgb1_to_gray (Image1, GrayImage) cvtColor(src,gray,COLOR_BGR2GRAY); //threshold (GrayImage, Regions, 43, 111) threshold2(gray,thresh,43,111); //connection (Regions, ConnectedRegions) contours_connection = connection2(thresh.clone(),draw_connection); //select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 150, 666) contours_area = selectShapeArea(thresh.clone(),draw_area,contours_connection,150,666); //select_shape (SelectedRegions, SelectedRegions1, 'circularity', 'and', 0.45, 1) contours_circle = selectShapeCircularity(thresh.clone(),draw_circle,contours_area,1,6); //显示结果 imshow("src",src); imshow("thresh",thresh); imshow("draw_connection",draw_connection); imshow("draw_area",draw_area); imshow("draw_circle",draw_circle); waitKey(); }
结果如下,这段代码中还有一个问题,就是计算轮廓圆的性质的方法,我这里采用的是自己想出来的方法,似乎不是很完善,需要进一步找到资料才修正。
来自为知笔记(Wiz)
相关文章推荐
- [blog 项目实战派]压板识别项目分析
- 关于cocos2dx开发中的图片资源的一些小技巧
- Android apk 反编译
- APKTOOL的使用心得
- Hot Keywords
- Word中带圈数字
- 黑马——Objective-C学习笔记<十>:分类和协议
- CMOS 工艺
- 一个男人关心的东西 决定了他的层次
- MySQL 显示表字段及注释等信息
- UEFI下安装系统常见问题
- shops
- shops
- ThinkPHP3.2.2 session设置不生效问题
- onethink 搬家注意事项
- 80后的互联网北漂:你的未来在哪?
- 百度员工 离职总结
- 正确理解ThreadLocal类
- The kth largest element in max-heap 最大堆的第k大元素
- servlet--多线程问题及java内存模型