图像轮廓提取算法(Opencv基于C++实现)

本文主要实现了图像的轮廓提取,首先先给出直观的轮廓实现结果:

0. 实现结果如下:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1. 打开图像代码

注意图片存放路径不能出现中文,不然会报错!

	CString defaultDir = _T("请选择路径"); //设置默认打开文件夹
	CString fileFilter = _T("文件(*.jpg;*.bmp)|*.jpg;*.bmp|All File (*.*)|*.*||"); //设置文件过滤
	CFileDialog fileDlg(true, defaultDir, _T(""), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, fileFilter, NULL);
	//弹出选择文件对话框

	if (fileDlg.DoModal() == IDOK)
	{
    
    
		filePath = fileDlg.GetPathName();//得到完整的文件名和目录名拓展名  
		CString filename = fileDlg.GetFileName();
	}
	char * A = CStringToChar(filePath); //CString转换Char
	Mat image = imread(A, 1);
	imshow("image", image);

2. 轮廓提取函数

寻找轮廓函数:findContours()

//函数原型:
void findContours//提取轮廓,用于提取图像的轮廓
(
InputOutputArray image,//输入图像,必须是8位单通道图像,并且应该转化成二值的
OutputArrayOfArrays contours,//检测到的轮廓,每个轮廓被表示成一个point向量
OutputArray hierarchy,//可选的输出向量,包含图像的拓扑信息。其中元素的个数和检测到的轮廓的数量相等
int mode,//说明需要的轮廓类型和希望的返回值方式
int method,//轮廓近似方法
Point offset = Point()
)

绘制轮廓函数: drawContours()

//函数原型:
void drawContours//绘制轮廓,用于绘制找到的图像轮廓
(
 InputOutputArray image,//要绘制轮廓的图像
 InputArrayOfArrays contours,//所有输入的轮廓,每个轮廓被保存成一个point向量
 int contourIdx,//指定要绘制轮廓的编号,如果是负数,则绘制所有的轮廓
 const Scalar& color,//绘制轮廓所用的颜色
 int thickness = 1, //绘制轮廓的线的粗细,如果是负数,则轮廓内部被填充
 int lineType = 8, /绘制轮廓的线的连通性
 InputArray hierarchy = noArray(),//关于层级的可选参数,只有绘制部分轮廓时才会用到
 int maxLevel = INT_MAX,//绘制轮廓的最高级别,这个参数只有hierarchy有效的时候才有效
                                          //maxLevel=0,绘制与输入轮廓属于同一等级的所有轮廓即输入轮廓和与其相邻的轮廓
                                          //maxLevel=1, 绘制与输入轮廓同一等级的所有轮廓与其子节点。
                                          //maxLevel=2,绘制与输入轮廓同一等级的所有轮廓与其子节点以及子节点的子节点
 Point offset = Point()
)

3. 代码实现

完整的C++与Opencv代码实现如下:

#include "opencv/highgui.h"
#include "opencv/cv.h"
using namespace cv;

void main()
{
    
    
	// TODO:  在此添加控件通知处理程序代码
	CString defaultDir = _T("请选择路径"); //设置默认打开文件夹
	CString fileFilter = _T("文件(*.jpg;*.bmp)|*.jpg;*.bmp|All File (*.*)|*.*||"); //设置文件过滤
	CFileDialog fileDlg(true, defaultDir, _T(""), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, fileFilter, NULL);
	//弹出选择文件对话框

	if (fileDlg.DoModal() == IDOK)
	{
    
    
		filePath = fileDlg.GetPathName();//得到完整的文件名和目录名拓展名  
		CString filename = fileDlg.GetFileName();
	}
	char * A = CStringToChar(filePath); //CString转换Char
	Mat image = imread(A, 1);
	imshow("image", image);

	Mat gray;
	cvtColor(image, gray, CV_BGR2GRAY);
	GaussianBlur(gray, gray, Size(3, 3), 3, 3);
	Mat img;
	threshold(gray, img, 100, 255, THRESH_BINARY);
	imshow("二值", img);
	vector<vector<Point>> contours;
	vector<Vec4i> hierarchy;
	findContours(img, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_NONE);
	Mat resultImage = Mat::zeros(img.size(), CV_8UC3);
	drawContours(resultImage, contours, -1, CV_RGB(0, 20, 180),3);
	imshow("resultImage", resultImage);

}

猜你喜欢

转载自blog.csdn.net/weixin_44478077/article/details/124675362