OpenCV的常用与形状形状描述相关函数及用法示例
OpenCV提供了提供了多种用于形状描述和分析的函数。这些函数能够帮助你提取图像中的形状特征,进行形状匹配、识别和分析。下面介绍一些常用的形状描述函数:
轮廓检测函数findContours()
findContours()函数用于在二值图像中查找轮廓。有两个原型函数,如下:
该函数已在前面的博文中详细介绍过,这里就不再做介绍了。
轮廓近似函数approxPolyDP()
approxPolyDP()
用于对轮廓进行多边形近似。其原型如下:
approxPolyDP()函数参数:
curve
存储在 std::vector 或 Mat 中的 2D 点的输入向量
approxCure 近似的结果。类型应与输入曲线的类型匹配。
epsilon 指定近似精度的参数。这是原始曲线与其近似曲线之间的最大距离。
close 如果为 true,则近似曲线是闭合的(其第一个和最后一个顶点是连接的)。否则,它不会闭合。
轮廓面积函数contourArea()
contourArea()计算轮廓的面积。其原型如下:
contourArea()函数参数:
contour 2D 点(轮廓顶点)的输入向量,存储在 std::vector 或 Mat 中。
oriented 定向区域标志。如果为 true,则该函数根据轮廓方向(顺时针或逆时针)返回带符号的面积值。使用此功能,您可以通过获取区域的符号来确定轮廓的方向。默认情况下,该参数为 false,表示返回绝对值。
轮廓面周长函数arcLength()
arcLength() 计算轮廓的周长。 其原型如下:
arcLength() 函数参数:
curve 存储在 std::vector 或 Mat 中的 2D 点的输入向量
closed 指示曲线是否闭合的标志。
最小外接圆函数 minEnclosingCircle()
minEnclosingCircle()函数找到轮廓的最小外接圆。其原型如下:
minEnclosingCircle()函数参数:
point 2D 点的输入向量,存储在 std::vector<> 或 Mat 中
center 输出圆的中心点
radius 输出圆的半径
轮廓最小矩形函数boundingRect()
boundingRect()函数计算包含轮廓的最小(直立)矩形。其原型如下:
boundingRect()函数参数 array 为输入灰度图像或2D点集,存储在std::vector或Mat中。
轮廓最小外接矩形函数minAreaRect()
minAreaRect()查找包围输入 2D 点集的最小区域的旋转矩形。其原型如下:
minAreaRect()函数参数 point为2D 点的输入向量,存储在 std::vector<> 或 Mat 中。
凸包函数convexHull()
convexHull()
函数计算轮廓的凸包。其原型如下:
convexHull()函数参数:
point
输入 2D 点集,存储在 std::vector 或 Mat 中。
hull
输出凸包。它要么是索引的整数向量,要么是点的向量。在第一种情况下,包元素是原始数组中凸包点的从 0 开始的索引(因为凸包点集是原始点集的子集)。在第二种情况下,外壳元素就是凸包点本身。
clockwise
方向标志。如果为 true,则输出凸包按顺时针方向排列。否则,它是逆时针方向。假定的坐标系的 X 轴指向右侧,Y 轴指向上方。
returnPoints
操作标志。对于矩阵,当标志为 true 时,函数返回凸包点。否则,它返回凸包点的索引。当输出数组为 std::vector 时,该标志被忽略,并且输出取决于向量的类型:std::vector<int> 意味着 returnPoints=false,std::vector<Point> 意味着 returnPoints=true。
形状匹配函数matchShapes()
matchShapes()函数
比较两个形状之间的相似度。其原型如下:
matchShapes()函数参数:
contour1
第一个轮廓或灰度图像。
contour2
第二个轮廓或灰度图像。
method 比较方法,参见ShapeMatchModes:
parameter 方法特定的参数(现在不支持)。
Hu矩函数HuMoments()
HuMoments()Hu矩是一组用于形状识别的七个不变矩。其原型函数有两个,如下:
moments()函数参数:
array 光栅图像(单通道、8 位或浮点 2D 数组)或 2D 点(Point 或 Point2f)的数组( 1×N 或 N×1 )。 binaryImage 如果为 true,则所有非零图像像素均被视为 1。该参数仅用于图像。
binaryImage 如果为 true,则所有非零图像像素均被视为 1。该参数仅用于图像。
以上函数用法示例
新建一个控制台应用程序,在源程序中加入如下代码:
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int main()
{
Mat src = imread("1.png");
if (src.empty())
{
cout << "Cann't open image!" << endl;
return -1;
}
imshow("Src1", src);
Mat dst, dst1;
cvtColor(src, dst1, COLOR_BGR2GRAY);
GaussianBlur(dst1, dst, Size(7, 7), 0);
threshold(dst, dst, 40, 200, THRESH_BINARY_INV);
//imshow("Dst", dst);
//findConturs
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
findContours(dst, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
//approxPolyDP
vector<Point> approx;
for (size_t i = 0; i < 5; i++)
{
approxPolyDP(contours[i], approx, arcLength(contours[0], true) * 0.005, true);
polylines(src, approx, true, Scalar(0, 0, 255), 2);
}
//contourArea() and rcLength()
float pl = arcLength(contours[0], 1);
float a1 = contourArea(contours[0], 1);
cout << "Conturs1 perimeters: " << pl << endl;
cout << "Conturs1 is area: " << a1 << endl;
//moments(),HuMoments()
Moments m = moments(contours[6]);
double hu[7];
HuMoments(m, hu);
cout << m.mu20 << endl;
cout << m.mu11 << endl;
cout << m.mu02 << endl;
cout << m.mu30 << endl;
cout << m.mu21 << endl;
cout << m.mu12 << endl;
cout << m.mu03 << endl;
cout << hu << endl;
//boundingRect()
Rect rec1 = boundingRect(contours[7]);
rectangle(src, rec1, Scalar(0, 0, 255), 2);
//minEnclosingCircle
Point2f center;
float radius;
minEnclosingCircle(contours[8], center, radius);
circle(src, center, radius, Scalar(0, 255, 0), 2);
//minEnclosingCircle
vector<Point2f> mTr;
vector<Point> mTr1;
vector<vector<Point>> plg;
minEnclosingTriangle(contours[11], mTr);
for (int i = 0; i < 3; i++)
{
Point p1;
p1.x = mTr[i].x;
p1.y= mTr[i].y;
mTr1.push_back(p1);
}
plg.push_back(mTr1);
polylines(src, plg, 1, Scalar(0, 255, 255), 2);
//minAreaRect()
vector<Point2f> pf;
vector<Point> ps;
RotatedRect rec2 = minAreaRect(contours[9]);
rec2.points(pf);
if (pf.empty())
{
cout << "pf is empty" << endl;
}
else
for (int i = 0; i < pf.size(); i++)
{
Point p;
p.x = (int)(pf[i].x);
p.y = (int)(pf[i].y);
ps.push_back(p);
}
vector<vector<Point>> conturs_r;
conturs_r.push_back(ps);
drawContours(src, conturs_r, -1, Scalar(255, 0, 0), 2);
//convexHull
vector<Point> hull;
vector<vector<Point>> conturs_h;
convexHull(contours[10], hull);
conturs_h.push_back(hull);
drawContours(src, conturs_h, -1, Scalar(255, 255, 0), 2);
//matchShapes
double md = matchShapes(contours[0], contours[1], CONTOURS_MATCH_I2,1);
cout << "md = " << md << endl;
md = matchShapes(contours[0], contours[0], CONTOURS_MATCH_I2, 1);
cout << "md1 = " << md << endl;
imshow("Dst1", src);
waitKey(0);
}
试运行,结果如下:
OpenCV形状描述函数就介绍到这里,例程源代码已上传到CSDN,下载链接为:
https://download.csdn.net/download/billliu66/89897345