我有2个轮廓A和B,我想检查它们是否相交。 A和B都是cv :: Point类型的向量,并且具有不同大小
要检查交叉点,我试图执行 bitwise_and 。这是一个例外,因为输入的大小不同。我该如何解决 ?
编辑:
附图应该可以更好地了解这个问题。汽车由蓝色轮廓跟踪,障碍物由粉红色轮廓跟踪。我需要检查交叉点。
答案 0 :(得分:11)
一种简单但可能不是最有效(??)的方法是使用drawContours
创建两个图像:一个具有汽车轮廓,另一个具有障碍轮廓。
然后and
他们在一起,任何仍然是积极的点将是交叉点。
一些伪代码(我使用Python接口,所以不能正确使用C ++语法,但它应该足够简单,你可以转换):
import numpy as np # just for matrix manipulation, C/C++ use cv::Mat
# find contours.
contours,h = findContours( img, mode=RETR_LIST, method=CHAIN_APPROX_SIMPLE )
# Suppose this has the contours of just the car and the obstacle.
# create an image filled with zeros, single-channel, same size as img.
blank = np.zeros( img.shape[0:2] )
# copy each of the contours (assuming there's just two) to its own image.
# Just fill with a '1'.
img1 = drawContours( blank.copy(), contours, 0, 1 )
img2 = drawContours( blank.copy(), contours, 1, 1 )
# now AND the two together
intersection = np.logical_and( img1, img2 )
# OR we could just add img1 to img2 and pick all points that sum to 2 (1+1=2):
intersection2 = (img1+img2)==2
如果我看intersection
,我会得到一张图像,其中轮廓相交,其他地方为0。
或者,您可以使用drawContours( blank.copy(), contours, 0, 1, thickness=-1 )
填写整个轮廓(不仅仅是轮廓,还可以填充内部),然后intersection
图像将包含轮廓之间的交叉。
答案 1 :(得分:0)
如果您首先对矢量进行排序,使用几乎任何一致的排序标准,那么您可以直接在矢量上使用std::set_intersection
。如果轮廓与图像尺寸相比较短,则这可能比接受的答案更快。
答案 2 :(得分:0)
我发现Clipper库对于这些目的非常有用。 (将cv::Point
的向量转换为Clipper Path
对象非常简单。)
答案 3 :(得分:0)
C ++经过测试的代码,基于math.coffee的答案:
vector< Point> merge_contours(vector <Point>& contour1, vector <Point>& contour2, int type){
// get work area
Rect work_area = boundingRect( contour1 ) | boundingRect( contour2 );
Mat merged = Mat::zeros(work_area.size(), CV_8UC1);
Mat contour1_im = Mat::zeros(work_area.size(), CV_8UC1);
Mat contour2_im = Mat::zeros(work_area.size(), CV_8UC1);
//draw
vector<vector<Point> > shifted1;
shifted1.push_back(shift_contour(contour1, work_area.tl()));
drawContours( contour1_im, shifted1, -1, 255, -1);
vector<vector<Point> > shifted2;
shifted2.push_back(shift_contour(contour2, work_area.tl()));
drawContours( contour2_im, shifted2, -1, 255, -1);
//imshow("contour1 debug", contour1_im);
//imshow("contour2 debug", contour2_im);
if( type == 0 )
// intersect
bitwise_or( contour1_im, contour2_im, merged);
else
// unite
bitwise_and( contour1_im, contour2_im, merged);
//imshow("merge contour debug", merged);
// find
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
findContours(merged,contours,hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));
if(contours.size() > 1){
printf("Warn: merge_contours has output of more than one contours.");
}
return shift_contour(contours[0], work_area.tl() * -1);
}