图像细化与轮廓操作

目录

1、图像细化

2、轮廓检测

3、轮廓信息统计

4、轮廓外接多边形

1、图像细化

需要安装扩展包

 

//图像细化
int test1()
{
	//中文字进行细化
	Mat img = imread("LearnCV_black.png",IMREAD_ANYCOLOR); 
	if (img.empty())
	{
		cout << "请确认图像文件名称是否正确" << endl;
		return -1;
	}

	//英文字 + 实心圆和圆环细化
	Mat words = Mat::zeros(100,200,CV_8UC1);//创建一个黑色的背景图片
	putText(words,"Learn",Point(30,30),2,1,Scalar(255),2);//添加英文
	putText(words,"OpenCV 4",Point(30,60),2,1,Scalar(255),2);
	circle(words,Point(80,75),10,Scalar(255), - 1);//添加实心圆
	
	circle(words,Point(130,75),10,Scalar(255),3);//添加圆环
	
	//进行细化
	Mat thin1, thin2;
    ximgproc::thinning(img, thin1, 0);//注意类名
	ximgproc::thinning(words,thin2, 0);
	
	//显示处理结果
	imshow("thinl", thin1); 
	imshow("img", img);
	namedWindow("thin2",WINDOW_NORMAL);
	imshow ("thin2", thin2);
	namedWindow("words",WINDOW_NORMAL);
	imshow("words", words);

	waitKey(0);
	return 0;
}

2、轮廓检测

 

 

 

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;
//轮廓检测
int test2()
{
	system("color 02");//更改输出界面颜色

	Mat img = imread("E:/testMap/key.png");
	if (img.empty())
	{
		cout << "请确认图像文件名称是否正确" << endl;
		return -1;
	}
	imshow("原图", img);

	Mat gray, binary;
	cvtColor(img, gray, COLOR_BGR2GRAY);//转化成灰度图
	GaussianBlur(gray, gray, Size(13, 13), 4, 4);//平滑滤波
	threshold(gray, binary, 170, 255, THRESH_BINARY | THRESH_OTSU);//自适应二值化

	//轮廓发现与绘制
	vector<vector<Point>> contours;//轮廓
	vector<Vec4i> hierarchy;//存放轮廓结构变量 Vec4i:里面存放4个整数,如{1,2,3,4}
	findContours(binary, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point());//轮廓检测函数

	//绘制轮廓
	for (int i = 0; i < hierarchy.size(); i++)
	{
		cout << hierarchy[i] << endl;
	}

	for (int t = 0; t < contours.size(); t++)
	{
		drawContours(img, contours, t, Scalar(0, 100, 255), 2, 8);//轮廓绘制函数
		imshow("轮廓检测结果", img);
		waitKey(0);
	}
}
int main()
{
	test2();

	system("pause");
	return 0;
}

3、轮廓信息统计

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

//轮廓信息统计
int test3()
{
	system("color 02");//更改输出界面颜色

	//用四个点表示三角形轮廓
	vector<Point> contour;
	contour.push_back(Point2f(0, 0));
	contour.push_back(Point2f(10, 0));
	contour.push_back(Point2f(10, 10));
	contour.push_back(Point2f(5, 5));

	double area = contourArea(contour);//轮廓面积
	cout << "area =" << area << endl;
	double length0 = arcLength(contour, true);
	double length1 = arcLength(contour, false);
	cout << "length0 =" << length0 << endl;
	cout << "lengthl =" << length1 << endl;
	cout << "图像轮廓面积" << endl;

	Mat img = imread("E:/testMap/key.png");
	if(img.empty())
	{
		cout << "请确认图像文件名称是否正确" << endl;
		return -1;
	}

	Mat gray, binary;
	cvtColor(img, gray, COLOR_BGR2GRAY); //转化成灰度图
	GaussianBlur(gray, gray, Size(3, 3), 3, 3);//平滑滤波
	threshold(gray, binary, 170, 255, THRESH_BINARY);//二值化

	//轮廓检测
	vector<vector<Point>> contours;//轮廓
	vector<Vec4i> hierarchy;//存放轮廓结构变量
	findContours(binary, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point());

	//输出轮廓面积
	for (int t = 0; t < contours.size(); t++)
	{
		double area1 = contourArea(contours[t]);
		cout << "第" << t << "轮廓面积 = " << area1 << endl;
	}

	//输出轮廓长度
	for (int t = 0; t < contours.size(); t++)
	{
		double length2 = arcLength(contours[t], false);
		cout << "第" << t << "轮廓长度 = " << length2 << endl;
	}

	return 0;
}

int main()
{
	test3();

	system("pause");
	return 0;
}

4、轮廓外接多边形

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

//轮廓外接多边形
void drawapp(Mat result, Mat img2)
{
	for (int i = 0; i < result.rows; i++)
	{
		//最后一个坐标点与第一个坐标点连接
		if (i == result.rows - 1)
		{
			Vec2i point1 = result.at<Vec2i>(i);
			Vec2i point2 = result.at<Vec2i>(0);
			line(img2, point1, point2, Scalar(0, 0, 255), 2, 8, 0);
			break;
		}
		Vec2i point1 = result.at<Vec2i>(i);
		Vec2i point2 = result.at<Vec2i>(i + 1);
		line(img2, point1, point2, Scalar(0, 0, 255), 2, 8, 0);
	}
}

int test4()
{
	Mat img = imread("E:/testMap/stuff.jpg");
	if (img.empty())
	{
		cout << "请确认图像文件名称是否正确" << endl;
		return -1;
	}

	Mat img1, img2;
	img.copyTo(img1); //深拷贝用来绘制最大外接矩形
	img.copyTo(img2);//深拷贝用来绘制最小外接矩形
	imshow("img", img);

	//去噪声与二值化
	Mat canny;
	Canny(img, canny, 80, 160, 3, false);
	imshow("", canny);

	//膨胀运算,将细小缝隙填补上
	Mat kernel = getStructuringElement(0, Size(3, 3)); dilate(canny, canny, kernel);

	//轮廓发现与绘制
	vector<vector<Point>> contours;
	vector<Vec4i> hierarchy;
	findContours(canny, contours, hierarchy, 0, 2, Point());//寻找轮廓的外接矩形
	for (int n = 0; n < contours.size(); n++)
	{
		// 最大外接矩形
		Rect rect = boundingRect(contours[n]);
		rectangle(img1, rect, Scalar(0, 0, 255), 2, 8, 0);

		//最小外接矩形
		RotatedRect rrect = minAreaRect(contours[n]); Point2f points[4];
		rrect.points(points);//读取最小外接矩形的四个顶点
		Point2f cpt = rrect.center;//最小外接矩形的中心

		//绘制旋转矩形与中心位置
		for (int i = 0; i < 4; i++)
		{
			if (i == 3)
			{
				line(img2, points[i], points[0], Scalar(0, 255, 0), 2, 8, 0);
				break;
			}
			line(img2, points[i], points[i + 1], Scalar(0, 255, 0), 2, 8, 0);
		}
		//绘制矩形的中心
		circle(img2, cpt, 4, Scalar(255, 0, 0), -8, 0);
	}

	//输出绘制外接矩形的结果
	imshow("max", img1);
	imshow("min", img2);

	cout << "下面是多边形拟合" << endl;
	waitKey(0);

	Mat approx = imread("E:/testMap/stuff.jpg");

	if (approx.empty())
	{
		cout << "请确认图像文件名称是否正确" << endl;
		return -1;
	}

	//边缘检测
	Mat canny2;
	Canny(approx, canny2, 80, 160, 3, false);

	//膨胀运算
	Mat kernel2 = getStructuringElement(0, Size(3, 3));
	dilate(canny2, canny2, kernel2);

	//轮廓发现与绘制
	vector<vector<Point>> contours2;
	vector<Vec4i> hierarchy2;
	findContours(canny2, contours2, hierarchy2, 0, 2, Point());

	//绘制多边形
	for (int t = 0; t < contours2.size(); t++)
	{
		//用最小外接矩形求取轮廓中心
		RotatedRect rrect = minAreaRect(contours2[t]);
		Point2f center = rrect.center;
		circle(approx, center, 2, Scalar(0, 255, 0), 2, 8, 0);

		Mat result;
		approxPolyDP(contours2[t], result, 4, true); //多边形拟合
		drawapp(result, approx);
		cout << "corners : " << result.rows << endl;

		//判断形状和绘制轮廓
		if (result.rows == 3)
		{
			putText(approx, "triangle", center, 0, 1, Scalar(0, 255, 0), 1, 8);
		}
		if (result.rows == 4)
		{
			putText(approx, "rectangle", center, 0, 1, Scalar(0, 255, 0), 1, 8);
		}
		if (result.rows == 8)
		{
			putText(approx, "poly-8", center, 0, 1, Scalar(0, 255, 0), 1, 8);
		}
		if (result.rows > 12)
		{
			putText(approx, "circle", center, 0, 1, Scalar(0, 255, 0), 1, 8);
		}
	}
	imshow("result", approx);

	//输出绘制外接矩形的结果
	imshow(" max", img1);
	imshow("min", img2);
	waitKey(0);
}

int main()
{
	test4();

	system("pause");
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zhang丶&|!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值