点与轮廓的距离及位置关系
函数原型
double pointPolygonTest( InputArray contour, Point2f pt, bool measureDist );
- contour: 所需检测的轮廓对象
- pt: Point2f 类型的pt, 待判定位置的点
- measureDist: 是否计算距离的标志, 当其为true时, 计算点到轮廓的最短距离, 当其为false时, 只判定轮廓与点的位置关系, 具体关系如下:
①返回值为-1, 表示点在轮廓外部
②返回值为0, 表示点在轮廓上
③返回值为1, 表示点在轮廓内部
代码
///计算点到轮廓的距离与位置关系
Mat srcImg = imread("D:\\1\\00.png");
imshow("src", srcImg);
cvtColor(srcImg, srcImg, CV_BGR2GRAY);
threshold(srcImg, srcImg, 100, 255, CV_THRESH_BINARY);
imshow("threshold", srcImg);
vector<vector<Point>> contours;
vector<Vec4i> hierarcy;
findContours(srcImg, contours, hierarcy, CV_RETR_TREE, CV_CHAIN_APPROX_NONE);
//输出轮廓数目
cout<<"contours.size()="<<contours.size()<<endl;
//输出轮廓的每个坐标
for(int i=0; i<contours.size(); i++)
{
for(int j=0; j<contours[i].size(); j++)
{
cout<<"("<<contours[i][j].x<<","<<contours[i][j].y<<")"<<endl;
}
}
double a0 = pointPolygonTest(contours[0], Point(212, 184), true);
double b0 = pointPolygonTest(contours[0], Point(212, 184), false);
cout<<"a0="<<a0<<endl;
cout<<"b0="<<b0<<endl;
waitKey(0);
运行结果
轮廓的矩
轮廓矩的介绍
计算函数原型
Moments moments( InputArray array, bool binaryImage = false );
array: 输入参数, 可以是光栅图像或二维数组
binaryImage:默认值false, 非零像素取其本身值, 若为true, 则非零像素取1
返回值: Moments类的对象, 返回对应的轮廓的空间矩/中心矩和归一化中心矩(最高3阶), 如下:
代码
Mat srcImg = imread("d:\\1\\00.png");
imshow("src", srcImg);
cvtColor(srcImg, srcImg, CV_BGR2GRAY);
threshold(srcImg, srcImg, 100, 255, CV_THRESH_BINARY);
imshow("threshold", srcImg);
vector<vector<Point>> contours;
vector<Vec4i> hierarcy;
findContours(srcImg, contours, hierarcy, CV_RETR_TREE, CV_CHAIN_APPROX_NONE);
cout<<"contours.size()="<<contours.size()<<endl;
Moments moment0 = moments(contours[0], false);
cout<<moment0.m00<<endl;
waitKey(0);
运行结果
形状匹配—比较两个形状或轮廓间的相似度
函数原型—matchShapes()
double matchShapes( InputArray contour1, InputArray contour2,
int method, double parameter );
- contour1: 所需比较的轮廓1
- contour2: 所需比较的轮廓2
- method: 轮廓比较的方法
- parameter: 比较方法的特殊参数(目前不支持)
注意
matchShapes()函数比较轮廓相似度是基于Hu矩来计算的, 结果越小相似度越高。
Hu矩是归一化中心矩的线性组合, 是为了获取图像某个特征的矩函数(对应变化如平移、缩放、旋转、镜像)
应用实例
代码
Mat srcImg = imread("D:\\1\\1.jpg"); //读取模板图像
imshow("src", srcImg);
cvtColor(srcImg, srcImg, CV_BGR2GRAY);
threshold(srcImg, srcImg, 100, 255, CV_THRESH_BINARY);
vector<vector<Point>> contours;
vector<Vec4i> hierarcy;
findContours(srcImg, contours, hierarcy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
Mat srcImg2 = imread("D:\\1\\2.jpg"); //读取待测试图片
imshow("src2", srcImg2);
Mat dstImg = srcImg2.clone();
cvtColor(srcImg2, srcImg2, CV_BGR2GRAY);
threshold(srcImg2, srcImg2, 100, 255, CV_THRESH_BINARY);
vector<vector<Point>> contours2;
vector<Vec4i> hierarcy2;
findContours(srcImg2, contours2, hierarcy2, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
while(1)
{
for(int i=0; i<contours2.size(); i++)
{
double matchRate = matchShapes(contours[0], contours2[i], CV_CONTOURS_MATCH_I1, 0.0);
cout<<"index="<<i<<"---"<<setiosflags(ios::fixed)<<matchRate<<endl;
if(matchRate<=0.1)
drawContours(dstImg, contours2, i, Scalar(0, 255, 0), 2, 8);
imshow("dst", dstImg);
char key = waitKey();
if(key==27)
break;
}
break;
}
waitKey(0);
运行结果
知识点讲解
1.
Mat srcImg = imread("D:\\1\\1.jpg"); //读取模板图像
imshow("src", srcImg);
cvtColor(srcImg, srcImg, CV_BGR2GRAY);
threshold(srcImg, srcImg, 100, 255, CV_THRESH_BINARY);
vector<vector<Point>> contours;
vector<Vec4i> hierarcy;
findContours(srcImg, contours, hierarcy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
模板图像和待测图像的处理方式必须相同