正在參與的工程裏有一個小功能是求兩個矩形之間的最小距離。大致翻了一下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;
}
繪製的實驗圖像:
最小距離計算執行結果如下,與預期的結果相同。