使用OpenCV实现Halcon算法(7)选择轮廓,select_shape
一、先看他人的文章
转载的网址是:
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相关推荐
- 使用OpenCV实现Halcon算法(1)亚像素提取边缘,Sub-Pixel Edge Detector
声明:本篇仅仅是分享网上的开源项目,算法非本人原创.转载文章: <A Sub-Pixel Edge Detector: an Implementation of the Canny/Devern ...
- opencv 图像 抠图 算法_opencv提取轮廓与抠图
自然图像抠图/视频抠像技术梳理(image matting, video matting)-计算机视视觉专题1 图像抠图算法学习 - Shared Sampling for Real-Time Alp ...
- 使用OpenCV实现Halcon算法(3)基于轮廓的模板匹配
声明:本篇仅仅是分享网上的开源项目,算法非本人原创. 〇.算法效果展示 0.1要定位的模板一 找到的匹配 在有污损情况下找到的匹配 0.2要定位的模板2 找到的匹配 一. 理论部分 模板匹配的算法包括 ...
- 使用OpenCV实现Halcon算法(4)OpenCV实现边缘模板匹配算法
声明:本篇仅仅是分享网上的开源项目,算法非本人原创. 本文转自:OpenCV研习社 干货 | OpenCV实现边缘模板匹配算法 - 云+社区 - 腾讯云 干货 | OpenCV实现边缘模板匹配算法 - ...
- opencv [c++] OpenCV实现Halcon相关算子算法
目录 1.Dyn_threshold 动态阈值 2.OpenCV实现 2.Emphasize图像锐化增强处理 3.select_shape()特征筛选 4.opencv访问遍历图像的每一个像素方法 5 ...
- 【OpenCV 4开发详解】轮廓发现与绘制
本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...
- OpenCV(六)之图像轮廓检测
OpenCV(六)之图像轮廓检测 Contour detection系列 Contour detection-图像金字塔 图像金字塔-高斯金字塔 图像金字塔-拉普拉斯金字塔 Contour detec ...
- halcon算法思路_halcon常用算法
halcon常用算法 1.read_image (Image, F:/image/001.bmp ) 读入图像 2.threshold (Image, region, 100, 200) 阈值分割,获 ...
- OpenCV使用 GrabCut 算法进行交互式前景提取
OpenCV使用 GrabCut 算法进行交互式前景提取 1. 效果图 2. 源码 参考 这篇博客将介绍如何使用Python,OpenCV中的GrabCut 算法来提取图像中的前景,并为此创建一个交互 ...
最新文章
- 创建function实现hive表结果导出到mysql
- 高斯混合模型理解汇总
- opencv python 多帧降噪算法_防抖技术 | OpenCV实现视频稳流
- 数据可视化【一】JavaScript学习
- java plug机制_插件机制 - OpooPress - 基于 Java 的静态博客生成器
- C++对象的赋值和复制
- 如何在vs2010中使用SSE指令集
- Ubuntu linux下的命令大全
- 深度学习——(4)VGG16 图像分类
- 【统计学】统计学专业术语
- 花几分钟轻松搞定快速排序算法
- TensorFlow报错:ValueError The passed save_path is not a valid checkpoint
- 使用am start命令启动android apk应用程序
- 解惑篇|Docker和 K8s 到底啥关系?想学K8s,必须得先学 Docker 吗?
- S3C2410中文芯片手册-11.串口
- 原来这就是 UI 设计师的门槛
- 【网络】计算机网络-数据链路层 Data Link Layer
- paperpass查重
- python操作CAD转存dwg文件
- 你是资讯控吗?——Web2.0智识管理简册
热门文章
- soc芯片和android哪个好,苹果的A11比Android阵营SoC强这么多? - 骁龙845和a11哪个好骁龙845和a11差距到底在哪...
- JS_map遍历数组
- HashMap嵌套HashMap之遍历
- Mysql4_常见函数
- 【2019西电网信杯】线上赛部分题wp
- 用Python 玩连连看 是什么效果?别霍霍别人了
- 华镭操作系统桌面版 RAYS LX
- html画圆属性,html 5画圆
- qqbot机器人编程实例(一)
- 抖音显示服务器审核为什么,抖音上传的视频为什么一直正在审核是违规吗不给显示出来吗...