求两个矩形之间的最小距离

正在参与的工程里有一个小功能是求两个矩形之间的最小距离。大致翻了一下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;
}

绘制的实验图像:

最小距离计算执行结果如下,与预期的结果相同。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章