网站首页 > 技术文章 正文
使用C++、opencv查找轮廓的内切圆
相关API:
double threshold(InputArray src, OutputArray dst, double thresh,double maxval, int type)
threshold()函数的作用是根据阈值对图像进行二值化
第一个参数,InputArray类型的src,输入数组,填单通道,8或32位浮点类型的Mat即可。
第二个参数,OutputArray类型的dst,函数调用后的运算结果存在这里,即这个参数用于存放输出结果,且和第一个参数中的Mat变量有一样的尺寸和类型。
第三个参数,double类型的 thresh,阈值的具体值。
第四个参数,double类型的 maxval,当第五个参数阙值类型type取CV_THRESH_BINARY或 CV_THRESH_BINARY_INV时阈值类型时的最大值。
第五个参数,int类型的type,阙值类型。threshold函数支持的对图像取阈值的方法由其确定,具体用法见下图。
更多的阈值操作可查看博客:https://blog.csdn.net/u012566751/article/details/77046445
void findContours( InputOutputArray image, OutputArrayOfArrays contours, OutputArray hierarchy, int mode, int method, Point offset = Point() )
findContours()函数用于查找图像中的轮廓
第一个参数, InputArray类型的 Image,输入图像,即源图像,填Mat类的对象即可,且需为8位单通道图像。图像的非零像素被视为1,0像素值被保留为0,所以图像为二进制。我们可以使用 compare()、 inrange()、threshold()、 adaptivethreshold()、 canny()等函数由灰度图或彩色图创建二进制图像。此函数会在提取图像轮廓的同时修改图像的内容。
第二个参数, OutputArrayOfArrays类型的 contours、检测到的轮廓、函数调用后的运算结果存在这里。每个轮廓存储为一个点向量,即用 point类型的 vector表示。
第三个参数, OutputArray类型的 hierarchy,可选的输出向量,包含图像的拓扑信息。其作为轮廓数量的表示,包含了许多元素。每个轮廓 contours[i]对应4个 hierarchy元素 hierarchy[i][0]~hierarchy[i][3],分别表示后一个轮廓、前一个轮廓、父轮廓、内嵌轮廓的索引编号。如果没有对应项,对应的 hierarchy值设置为负数。
第四个参数,int类型的mode,轮廓检索模式,取值如下所示。
标识符 | 含义 |
RETR_EXTERNAL | 表示只检测最外层轮廓。对所有轮廓,设置hierarchy[i][2]=hierarchy[i][3]=-1. |
RETR_LIST | 提取所有轮廓,并且放置在list中。检测的轮廓不建立等级关系 |
RETR_CCOMP | 提取所有轮廓,并且将其组织为双层结构( two-level hierarchy:顶层为连通域的外围边界,次层为孔的内层边界) |
RETR_TREE | 提取所有轮廓,并重新建立网状的轮廓结构 |
第五个参数,int类型的method,为轮廓的近似办法,取值如下所示。
标识符 | 含义 |
CHAIN_APPROX_NONE | 获取每个轮廓的每个像素,相邻的两个点的像素位置差不超过1,即max(abs(x1-x2), abs(y2-y1))==1 |
CHAIN_APPROX_SIMPLE | 压缩水平方向,垂直方向,对角线方向的元素,只保留该方向 的终点坐标,例如一个矩形轮廓只需4个点来保存轮廓信息 |
CHAIN_APPROX_TC89L1, CHAIN_APPROX_TC89_KCOS | 使用Teh-Chinl链逼近算法中的一个 |
第六个参数, Point类型的offset,每个轮廓点的可选偏移量,有默认值Point()。对ROl图像中找出的轮廓,并要在整个图像中进行分析时,这个参数便可排上用场。
关于此函数更详细的用法可参考博客:https://blog.csdn.net/keith_bb/article/details/70185209
void drawContours(InputOutputArray image, InputArrayOfArrays contours, int contourIdx, const Scalar& color, int thickness=1, int lineType=8, InputArray hierarchy=noArray(), int maxLevel=INT_MAX, Point offset=Point() )
drawContours()函数一般配合 findContours()函数使用,作用是画出findContours()函数找到的轮廓。
第一个参数, InputArray类型的 image,目标图像,填Mat类的对象即可。
第二个参数, InputArrayOfArrays类型的 contours,所有的输入轮廊。每个轮廓存储为一个点向量,即用 point类型的 vector表示。
第三个参数,int类型的 contourldx,轮廓绘制的指示变量。如果其为负值则绘制所有轮廓。
第四个参数, const Scalar&类型的color,轮廓的颜色。
第五个参数, int thickness,轮廓线条的粗细度,有默认值1。如果为负值或CV_FILLED表示填充轮廓内部。
第六个参数,int类型的 line Type,线条的类型,有默认值8,即8连通线型。还可取4和LINE_AA,分别代表4连通线型和抗锯齿线型。
第七个参数, InputArray类型的 hierarchy,可选的层次结构信息,有默认值noArray()。
第八个参数,int类型的 maxLevel,表示用于绘制轮廓的最大等级,有默认值INT_MAX。
第九个参数, Point类型的 offset,可选的轮廓偏移参数,用指定的偏移量offset=(dx,dy)偏移需要绘制的轮廓,有默认值 Point()。
double pointPolygonTest(InputArray contour, Point2f pt, bool measureDist)
pointPolygonTest()函数作用是判断一个点是否在轮廓内。
第一个参数,InputArray类型的contour,是输入的轮廓。
第二个参数,Point2f类型的pt,即要进行判断的二维点。
第三个参数,bool类型的measureDist,当设置为true时,返回实际距离值。若返回值为正,表示点在多边形内部,返回值为负,表示在多边形外部,返回值为0,表示在多边形上。当measureDist设置为false时,返回 -1、0、1三个固定值。若返回值为+1,表示点在多边形内部,返回值为-1,表示在多边形外部,返回值为0,表示在多边形上。
代码中用threshold()函数对源图像进行二值化,所以要求源图像较为简单,可以通过灰度阈值二值化,否则需要另外对图像进行分割处理。代码如下:
#include "stdafx.h"
#include <iostream>
#include <opencv2/opencv.hpp>
#include <math.h>
using namespace cv;
using namespace std;
int main()
{
//读取图像
Mat src_image = imread("D:\\1.jpg");
if (!src_image.data)
{
cout << "src image load failed!" << endl;
return -1;
}
namedWindow("原图", WINDOW_NORMAL);
imshow("原图", src_image);
/*此处高斯去燥有助于后面二值化处理的效果*/
Mat blur_image;
GaussianBlur(src_image, blur_image, Size(15, 15), 0, 0);
imshow("GaussianBlur", blur_image);
/*灰度变换与二值化*/
Mat gray_image, binary_image;
cvtColor(blur_image, gray_image, COLOR_BGR2GRAY);
threshold(gray_image, binary_image, 30, 255, THRESH_BINARY | THRESH_TRIANGLE);
imshow("binary", binary_image);
/*形态学闭操作*/
Mat morph_image;
Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
morphologyEx(binary_image, morph_image, MORPH_CLOSE, kernel, Point(-1, -1), 2);
imshow("morphology", morph_image);
//查找外轮廓
vector< vector<Point> > contours;
vector<Vec4i> hireachy;
findContours(binary_image, contours, hireachy, CV_RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
//画出找到的轮廓
Mat result_image = Mat::zeros(src_image.size(), CV_8UC3);
drawContours(result_image, contours, -1, Scalar(0, 0, 255), 1, 8, hireachy);
//在每个轮廓中查找内切圆并画出来
for (size_t t = 0; t < contours.size(); t++)
{
//查找内切圆
int dist = 0;
int maxdist = 0;
Point center;
for (int i = 0; i<src_image.cols; i++)
{
for (int j = 0; j<src_image.rows; j++)
{
dist = pointPolygonTest(contours[t], Point(i, j), true);
if (dist>maxdist)
{
maxdist = dist;
center = Point(i, j);
}
}
}
//画出内切圆
circle(result_image, center, maxdist, Scalar(0, 255, 255));
}
//显示结果
namedWindow("轮廓图",WINDOW_NORMAL);
imshow("轮廓图", result_image);
waitKey(0);
return 0;
}
源图像(用三张图拼成一张):
?
二值化后图像:
?
结果图:
?
部分参考:https://www.cnblogs.com/jsxyhelu/p/6830093.html
毛星云 《OpenCV3编程入门》
猜你喜欢
- 2024-10-12 智能监测:皮带输送系统堵料问题的解决方案
- 2024-10-12 Python-OpenCV 10. 图像边缘算法 opencv边缘识别
- 2024-10-12 Net AI学习笔记系列第五章 net教程
- 2024-10-12 深度学习和神经网络——图像读取和显示
- 2024-10-12 十三句Python搞定找茬游戏 找茬游戏规则
- 2024-10-12 「深度学习」手把手教你用PythonOpenCV物体识别-识别水果
- 2024-10-12 python代码实现OpenCV 轮廓近似原理
- 2024-10-12 OpenCV找出图片中的圆并标注圆心 opencv检测圆代码
- 2024-10-12 分享3个干货满满的Python实战项目,点赞收藏
- 2024-10-12 OpenCV(28)——凸包 opencv轮廓凹凸
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- oraclesql优化 (66)
- 类的加载机制 (75)
- feignclient (62)
- 一致性hash算法 (71)
- dockfile (66)
- 锁机制 (57)
- javaresponse (60)
- 查看hive版本 (59)
- phpworkerman (57)
- spark算子 (58)
- vue双向绑定的原理 (68)
- springbootget请求 (58)
- docker网络三种模式 (67)
- spring控制反转 (71)
- data:image/jpeg (69)
- base64 (69)
- java分页 (64)
- kibanadocker (60)
- qabstracttablemodel (62)
- java生成pdf文件 (69)
- deletelater (62)
- com.aspose.words (58)
- android.mk (62)
- qopengl (73)
- epoch_millis (61)
本文暂时没有评论,来添加一个吧(●'◡'●)