OpenCV中判斷點在矩形中的方法
目錄
1.問題
如圖1.1所示,有紅色和藍色兩個點,如何判斷點相對於矩形的位置呢?
2.思路
首先,我們知道OpenCV中有一個函式:pointPolygonTest()。它的作用是判斷一個點是否在輪廓中,基本用法如下:
C++: double pointPolygonTest(InputArray contour, Point2f pt, bool measureDist);
當measureDist設定為true時,若返回值為正,表示點在輪廓內部,返回值為負,表示在輪廓外部,返回值為0,表示在輪廓上。
當measureDist設定為false時,若返回值為+1,表示點在輪廓內部,返回值為-1,表示在輪廓外部,返回值為0,表示在輪廓上。
這也就是說,如果我們能夠把RotateRect類的物件表示成輪廓,就可以直接呼叫pointPolygonTest()來進行分析了點的相對位置了。
在這裡,我對RotatedRect的成員進行簡單的梳理:
RotatedRect ():
建構函式:
1.利用浮點引數進行構造:形心、長寬、旋轉角度(x軸逆時針旋轉的方向)
RotatedRect (const Point2f ¢er, const Size2f &size, float angle)
2.利用矩形的任意三個角點進行構造(浮點資料)
RotatedRect (const Point2f
成員函式:
1.返回最小外接矩形
Rect cv::RotatedRect::boundingRect() const
Rect_<float> cv::RotatedRect::boundingRect2f() const
2.儲存矩形的四個角點
void cv::RotatedRect::points(Point2f pts[]) const
3.返回角度、中心點、尺寸
float angle
Point2f center
Size2f size
最後的問題是:給定點的陣列,如何將點的陣列轉化為向量vector?
方法:
//給定點的陣列
Point2f corners[4];
//轉化為向量
Point2f* lastItemPointer = (corners + sizeof corners / sizeof corners[0]);
vector<Point2f> contour(corners, lastItemPointer);
3.程式碼實現
編寫判斷函式如下:
bool DoesRectangleContainPoint(RotatedRect rectangle, Point2f point)
{
//轉化為輪廓
Point2f corners[4];
rectangle.points(corners);
Point2f *lastItemPointer = (corners+sizeof corners/sizeof corners[0]);
vector<Point2f> contour(corners,lastItemPointer);
//判斷
double indicator = pointPolygonTest(contour,point,true);
if (indicator >= 0) return true;
else return false;
}
全部的實驗程式碼如下:
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
bool DoesRectangleContainPoint(RotatedRect rectangle, Point2f point)
{
//轉化為輪廓
Point2f corners[4];
rectangle.points(corners);
Point2f *lastItemPointer = (corners+sizeof corners/sizeof corners[0]);
vector<Point2f> contour(corners,lastItemPointer);
//判斷
double indicator = pointPolygonTest(contour,point,true);
if (indicator >= 0) return true;
else return false;
}
int main()
{
//準備資料
Mat img(200,200,CV_8UC3,Scalar(0));
RotatedRect rRect = RotatedRect(Point2f(100,100),Size(100,50),30);
Point2f rpoints[4];
rRect.points(rpoints);
for (int i = 0; i < 4; i++)
line(img, rpoints[i], rpoints[(i + 1) % 4], Scalar(0, 255, 0));
circle(img, Point(100,100),2,Scalar(255,0,0),-1);
circle(img, Point(165, 130), 2, Scalar(0, 0, 255), -1);
//判斷
bool result1 = DoesRectangleContainPoint(rRect, Point(100, 100));
bool result2 = DoesRectangleContainPoint(rRect, Point(165, 130));
//繪製結果(符合條件的用綠色標註)
if(result1) circle(img, Point(100, 100), 2, Scalar(0, 255, 0), -1);
if (result2) circle(img, Point(165, 130), 2, Scalar(0, 255, 0), -1);
return 0;
}
實驗結果:
4.資料
1.RotatedRect類的基本屬性:
https://docs.opencv.org/3.4.0/db/dd6/classcv_1_1RotatedRect.html
2.陣列轉化為向量的簡單方法: