正在参与的工程里有一个小功能是求两个矩形之间的最小距离。大致翻了一下OpenCV,貌似没看到现成的函数,那就自己写一个好了。
一个画面中,两个矩形的几何关系大致可分为如下几种,以C1为参考,分别是:
(1) 不相交,但在X或Y轴方向上有部分重合坐标,比如矩形1和2,此时,最小距离为两个矩形之间的最小平行距离或垂直距离,如图中红色箭线D12所示。
(2) 不相交,在X和Y轴方向上均无重合坐标,比如矩形1和3,此时最小距离为两矩形距离最近的两个顶点之间的距离,如图中红色箭线D13。
(3) 相交,此时距离为负数,如矩形1和4。
为了实现以上几何关系,写了个小函数:
int min_distance_of_rectangles(Rect rect1, Rect rect2)
{
int min_dist;
//首先计算两个矩形中心点
Point C1, C2;
C1.x = rect1.x + (rect1.width / 2);
C1.y = rect1.y + (rect1.height / 2);
C2.x = rect2.x + (rect2.width / 2);
C2.y = rect2.y + (rect2.height / 2);
// 分别计算两矩形中心点在X轴和Y轴方向的距离
int Dx, Dy;
Dx = abs(C2.x - C1.x);
Dy = abs(C2.y - C1.y);
//两矩形不相交,在X轴方向有部分重合的两个矩形,最小距离是上矩形的下边线与下矩形的上边线之间的距离
if((Dx < ((rect1.width + rect2.width)/ 2)) && (Dy >= ((rect1.height + rect2.height) / 2)))
{
min_dist = Dy - ((rect1.height + rect2.height) / 2);
}
//两矩形不相交,在Y轴方向有部分重合的两个矩形,最小距离是左矩形的右边线与右矩形的左边线之间的距离
else if((Dx >= ((rect1.width + rect2.width)/ 2)) && (Dy < ((rect1.height + rect2.height) / 2)))
{
min_dist = Dx - ((rect1.width + rect2.width)/ 2);
}
//两矩形不相交,在X轴和Y轴方向无重合的两个矩形,最小距离是距离最近的两个顶点之间的距离,
// 利用勾股定理,很容易算出这一距离
else if((Dx >= ((rect1.width + rect2.width)/ 2)) && (Dy >= ((rect1.height + rect2.height) / 2)))
{
int delta_x = Dx - ((rect1.width + rect2.width)/ 2);
int delta_y = Dy - ((rect1.height + rect2.height)/ 2);
min_dist = sqrt(delta_x * delta_x + delta_y * delta_y);
}
//两矩形相交,最小距离为负值,返回-1
else
{
min_dist = -1;
}
return min_dist;
}
测试一下:
#include <iostream>
#include <vector>
#include <math.h>
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
using namespace std;
using namespace cv;
int main()
{
// 创建一个空白背景
Mat img(Size(1000, 1000), CV_8UC3, Scalar(255, 255, 255));
// 三个矩形,1和2、1和3分别代表两种位置关系
Rect rect1(200,200,300,300);
Rect rect2(600,100,300,200);
Rect rect3(700,600,100,100);
Rect rect4(100,400,200,200);
//绘制在背景图像上
rectangle(img, rect1, Scalar(255, 0, 0), -1);
rectangle(img, rect2, Scalar(0, 255, 0), -1);
rectangle(img, rect3, Scalar(0, 0, 255), -1);
rectangle(img, rect4, Scalar(0, 255, 255), -1);
imshow("img", img);
waitKey(0);
imwrite("rects.bmp", img);
//开始计算距离
int min_dist_12 = min_distance_of_rectangles(rect1, rect2);
int min_dist_13 = min_distance_of_rectangles(rect1, rect3);
int min_dist_14 = min_distance_of_rectangles(rect1, rect4);
cout << "Minimun distance between rect1 and rect2 is: " << min_dist_12 << endl;
cout << "Minimun distance between rect1 and rect3 is: " << min_dist_13 << endl;
cout << "Minimun distance between rect1 and rect4 is: " << min_dist_14 << endl;
return 0;
}
绘制的实验图像:
最小距离计算执行结果如下,与预期的结果相同。