一、先看他人的文章

转载的网址是:

https://www.cnblogs.com/jsxyhelu/p/4650151.html

halcon源码:

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中也要这样的结果,就需要自己动手尝试实现。实现过程中我采用了类似的函数名表示敬意。

24位图

// 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();
}

8位图

//connection
std::vector<std::vector<cv::Point>> connection(const cv::Mat& src, cv::Mat& draw)
{draw = cv::Mat::zeros(src.rows, src.cols, CV_8UC1);std::vector<std::vector<cv::Point>>contours;cv::findContours(src, contours, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE);for (int i = 0; i < contours.size(); i++){cv::drawContours(draw, contours, i, cv::Scalar(255));}return contours;
}//select_shape
std::vector<std::vector<cv::Point>> selectShapeArea(const cv::Mat& src, cv::Mat& draw, const std::vector<std::vector<cv::Point>>& contours, int minvalue, int maxvalue)
{std::vector<std::vector<cv::Point>> result_contours;draw = Mat::zeros(src.rows, src.cols, CV_8UC1);for (int i = 0; i < contours.size(); i++){int countour_area = contourArea(contours[i]);if (countour_area > minvalue && countour_area < maxvalue){result_contours.emplace_back(contours[i]);}}for (int i = 0; i < result_contours.size(); i++){drawContours(draw, result_contours, i, cv::Scalar(255), -1);}return result_contours;
}

二、再看我的原创

这里使用OpenCV自带的connectedComponentsWithStats算子,标记连通区域,然后根据面积来过滤想要的区域。

//连通,黑底白图,白色代表有数据,黑色代表没有数据cv::Mat matLabels, matStats, matCentroids;//centroids是质心int nccomps = cv::connectedComponentsWithStats(imageBinary, matLabels, matStats, matCentroids);//连通数目//面积过滤int left = 0;int top = 0;int width = 0;int height = 0;int connArea = 0;std::vector<cv::Rect> vtRect;std::vector<int> vtLabels;for (int i = 1; i < nccomps; i++) //i从1开始,因为0是黑色{left = matStats.at<int>(i, cv::CC_STAT_LEFT); //stats分别是L,T,W,H,Areatop = matStats.at<int>(i, cv::CC_STAT_TOP);width = matStats.at<int>(i, cv::CC_STAT_WIDTH);height = matStats.at<int>(i, cv::CC_STAT_HEIGHT);connArea = matStats.at<int>(i, cv::CC_STAT_AREA);if (connArea > 5000 && connArea < 999999999){vtRect.emplace_back(cv::Rect(left, top, width, height));vtLabels.emplace_back(i);}}cv::Mat imageSelected = Mat::zeros(imageBinary.rows, imageBinary.cols, CV_8UC1);int rowBegin = 0;int rowEnd = 0;int colBegin = 0;int colEnd = 0;int lbl = 0;for (int n = 0; n < vtLabels.size(); n++){rowBegin = vtRect[n].y;rowEnd = vtRect[n].y + vtRect[n].height;colBegin = vtRect[n].x;colEnd = vtRect[n].x + vtRect[n].width;for (int i = rowBegin; i <= rowEnd; i++)//row{uchar* uc_pixel = imageSelected.data + i * imageSelected.step;for (int k = colBegin; k <= colEnd; k++)//col{lbl = matLabels.at<int>(i, k);std::vector<int>::iterator result = std::find(vtLabels.begin(), vtLabels.end(), lbl); //查找1if (result == vtLabels.end()) //没找到{uc_pixel[k] = 0;}else //找到{uc_pixel[k] = 255;}}}}

---

参考文献

选择轮廓(select_shape)

选择轮廓(select_shape) - jsxyhelu - 博客园

opencv的实用研究--分析轮廓并寻找边界点

opencv的实用研究--分析轮廓并寻找边界点 - jsxyhelu - 博客园

如何识别出轮廓准确的长和宽

如何识别出轮廓准确的长和宽 - jsxyhelu - 博客园

OpenCV中的新函数connectedComponentsWithStats使用

OpenCV中的新函数connectedComponentsWithStats使用 - jsxyhelu - 博客园

OpenCV使用FindContours进行二维码定位

OpenCV使用FindContours进行二维码定位 - jsxyhelu - 博客园

使用OpenCV实现Halcon算法(7)选择轮廓,select_shape相关推荐

  1. 使用OpenCV实现Halcon算法(1)亚像素提取边缘,Sub-Pixel Edge Detector

    声明:本篇仅仅是分享网上的开源项目,算法非本人原创.转载文章: <A Sub-Pixel Edge Detector: an Implementation of the Canny/Devern ...

  2. opencv 图像 抠图 算法_opencv提取轮廓与抠图

    自然图像抠图/视频抠像技术梳理(image matting, video matting)-计算机视视觉专题1 图像抠图算法学习 - Shared Sampling for Real-Time Alp ...

  3. 使用OpenCV实现Halcon算法(3)基于轮廓的模板匹配

    声明:本篇仅仅是分享网上的开源项目,算法非本人原创. 〇.算法效果展示 0.1要定位的模板一 找到的匹配 在有污损情况下找到的匹配 0.2要定位的模板2 找到的匹配 一. 理论部分 模板匹配的算法包括 ...

  4. 使用OpenCV实现Halcon算法(4)OpenCV实现边缘模板匹配算法

    声明:本篇仅仅是分享网上的开源项目,算法非本人原创. 本文转自:OpenCV研习社 干货 | OpenCV实现边缘模板匹配算法 - 云+社区 - 腾讯云 干货 | OpenCV实现边缘模板匹配算法 - ...

  5. opencv [c++] OpenCV实现Halcon相关算子算法

    目录 1.Dyn_threshold 动态阈值 2.OpenCV实现 2.Emphasize图像锐化增强处理 3.select_shape()特征筛选 4.opencv访问遍历图像的每一个像素方法 5 ...

  6. 【OpenCV 4开发详解】轮廓发现与绘制

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...

  7. OpenCV(六)之图像轮廓检测

    OpenCV(六)之图像轮廓检测 Contour detection系列 Contour detection-图像金字塔 图像金字塔-高斯金字塔 图像金字塔-拉普拉斯金字塔 Contour detec ...

  8. halcon算法思路_halcon常用算法

    halcon常用算法 1.read_image (Image, F:/image/001.bmp ) 读入图像 2.threshold (Image, region, 100, 200) 阈值分割,获 ...

  9. OpenCV使用 GrabCut 算法进行交互式前景提取

    OpenCV使用 GrabCut 算法进行交互式前景提取 1. 效果图 2. 源码 参考 这篇博客将介绍如何使用Python,OpenCV中的GrabCut 算法来提取图像中的前景,并为此创建一个交互 ...

最新文章

  1. 创建function实现hive表结果导出到mysql
  2. 高斯混合模型理解汇总
  3. opencv python 多帧降噪算法_防抖技术 | OpenCV实现视频稳流
  4. 数据可视化【一】JavaScript学习
  5. java plug机制_插件机制 - OpooPress - 基于 Java 的静态博客生成器
  6. C++对象的赋值和复制
  7. 如何在vs2010中使用SSE指令集
  8. Ubuntu linux下的命令大全
  9. 深度学习——(4)VGG16 图像分类
  10. 【统计学】统计学专业术语
  11. 花几分钟轻松搞定快速排序算法
  12. TensorFlow报错:ValueError The passed save_path is not a valid checkpoint
  13. 使用am start命令启动android apk应用程序
  14. 解惑篇|Docker和 K8s 到底啥关系?想学K8s,必须得先学 Docker 吗?
  15. S3C2410中文芯片手册-11.串口
  16. 原来这就是 UI 设计师的门槛
  17. 【网络】计算机网络-数据链路层 Data Link Layer
  18. paperpass查重
  19. python操作CAD转存dwg文件
  20. 你是资讯控吗?——Web2.0智识管理简册

热门文章

  1. soc芯片和android哪个好,苹果的A11比Android阵营SoC强这么多? - 骁龙845和a11哪个好骁龙845和a11差距到底在哪...
  2. JS_map遍历数组
  3. HashMap嵌套HashMap之遍历
  4. Mysql4_常见函数
  5. 【2019西电网信杯】线上赛部分题wp
  6. 用Python 玩连连看 是什么效果?别霍霍别人了
  7. 华镭操作系统桌面版 RAYS LX
  8. html画圆属性,html 5画圆
  9. qqbot机器人编程实例(一)
  10. 抖音显示服务器审核为什么,抖音上传的视频为什么一直正在审核是违规吗不给显示出来吗...