目录
1、图像细化
2、轮廓检测
3、轮廓信息统计
4、轮廓外接多边形
需要安装扩展包
//图像细化
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;
}
#include
#include
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> contours;//轮廓
vector 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;
}
#include
#include
using namespace cv;
using namespace std;
//轮廓信息统计
int test3()
{
system("color 02");//更改输出界面颜色
//用四个点表示三角形轮廓
vector 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> contours;//轮廓
vector 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;
}
#include
#include
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(i);
Vec2i point2 = result.at(0);
line(img2, point1, point2, Scalar(0, 0, 255), 2, 8, 0);
break;
}
Vec2i point1 = result.at(i);
Vec2i point2 = result.at(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> contours;
vector 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> contours2;
vector 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;
}