C++ 获取hough线的交点opencv c++;
这与此不同,因为在python中,我们有numpy来解决所有问题。我在C++中编写了一个代码来找到霍夫线的交集。C++ 获取hough线的交点opencv c++;,c++,opencv,C++,Opencv,这与此不同,因为在python中,我们有numpy来解决所有问题。我在C++中编写了一个代码来找到霍夫线的交集。 vector<Point2f> new_intersection(vector<Vec2f> lines) { vector<Point2f> intersections; float m1, c1, m2, c2; float x1, y1, x2, y2; float dx, dy, dx1, dy1;
vector<Point2f> new_intersection(vector<Vec2f> lines) {
vector<Point2f> intersections;
float m1, c1, m2, c2;
float x1, y1, x2, y2;
float dx, dy, dx1, dy1;
for (auto&& i : combinations(lines, 2)) {
Point pt;
float rho = i[0][0], theta = i[0][1];
Point pt1, pt2;
double a = cos(theta), b = sin(theta);
double x0 = a * rho, y0 = b * rho;
pt1.x = cvRound(x0 + 1000 * (-b));
pt1.y = cvRound(y0 + 1000 * (a));
pt2.x = cvRound(x0 - 1000 * (-b));
pt2.y = cvRound(y0 - 1000 * (a));
Point pt3, pt4;
float rho1 = i[1][0], theta1 = i[1][1];
double a1 = cos(theta1), b1 = sin(theta1);
double x01 = a1 * rho1, y01 = b1 * rho1;
pt3.x = cvRound(x01 + 1000 * (-b1));
pt3.y = cvRound(y01 + 1000 * (a1));
pt4.x = cvRound(x01 - 1000 * (-b1));
pt4.y = cvRound(y01 - 1000 * (a1));
dx = pt2.x - pt1.x;
dy = pt2.y - pt1.y;
m1 = dy / dx;
c1 = pt1.y - m1 * pt1.x;
dx1 = pt4.x - pt3.x;
dy1 = pt4.y - pt3.y;
m2 = dy1 / dx1;
c2 = pt3.y - m2 * pt3.x;
if (m1 == m2)
continue;
else{
pt.x = (c2 - c1) / (m1 - m2);
pt.y = m1 * pt.x + c1;
intersections.push_back(pt);
}
}
return intersections;
}
矢量新交点(矢量线){
矢量交点;
浮子m1、c1、m2、c2;
浮球x1、y1、x2、y2;
浮点数dx,dy,dx1,dy1;
用于(自动和输入:组合(行,2)){
点pt;
浮点rho=i[0][0],θ=i[0][1];
pt1、pt2点;
双a=cos(θ),b=sin(θ);
双x0=a*rho,y0=b*rho;
pt1.x=cvRound(x0+1000*(-b));
pt1.y=cvRound(y0+1000*(a));
pt2.x=cvRound(x0-1000*(-b));
pt2.y=cvRound(y0-1000*(a));
pt3、pt4点;
浮点rho1=i[1][0],θ1=i[1][1];
双a1=cos(θ1),b1=sin(θ1);
双x01=a1*rho1,y01=b1*rho1;
pt3.x=cvRound(x01+1000*(-b1));
pt3.y=cvRound(y01+1000*(a1));
pt4.x=cvRound(x01-1000*(-b1));
pt4.y=cvRound(y01-1000*(a1));
dx=pt2.x-pt1.x;
dy=pt2.y-pt1.y;
m1=dy/dx;
c1=pt1.y-m1*pt1.x;
dx1=pt4.x-pt3.x;
dy1=pt4.y-pt3.y;
m2=dy1/dx1;
c2=pt3.y-m2*pt3.x;
如果(m1==m2)
继续;
否则{
pt.x=(c2-c1)/(m1-m2);
pt.y=m1*pt.x+c1;
交叉口。推回(pt);
}
}
返回交叉口;
}
我通过使用简单的数学公式来找到所有直线(不包括平行线)之间的交点。问题是这并不能给出所有正确的交叉点。检查原始图像、hough图像和下面的交点图像
这些是我得到的交点
inter1:[-3345116]
inter2:[163177]
inter3:[-1527115]
inter4:[16487]
inter5:[163116]
区间6:[-2.14748e+09,-2.14748e+09]
公式在数学上是正确的,应该给出正确的分数。你不应该依赖公式
c=y-m*x
,因为这个公式虽然在数学上是正确的,但不能正确表示垂直线(例如theta=0
),所以你的计算要么变得不稳定(由于精度有限,如果直线非常接近垂直)或完全失败,因为m
在pt1.x==pt2.x
时变为无穷大
相反,您应该使用向量计算交点。此计算可能有点复杂,但对于垂直线没有任何问题。使用向量,您可以求解pt1+lambda*(pt2-pt1)=pt3+alpha*(pt4-pt3)
用于lambda
或alpha
,然后将该值放在相应的一侧。在code中,如下所示:
float dx0 = pt2.x - pt1.x;
float dx1 = pt4.x - pt3.x;
float dy0 = pt2.y - pt1.y;
float dy1 = pt4.y - pt3.y;
//Solve for lambda:
float div = (dy0 * dx1) - (dx0 * dy1);
if(abs(div) < EPSILON) { continue; } //lines are parallel
float lambda = (((pt1.x - pt3.x) * dx1) + ((pt1.y - pt3.y) * dy1)) / div;
//put lambda back into pt1 + lambda * (pt2 - pt1) to calculate intersection point:
pt.x = pt1.x + (lambda * dx0);
pt.y = pt1.y + (lambda * dy0);
float dx0=pt2.x-pt1.x;
浮点dx1=pt4.x-pt3.x;
float dy0=pt2.y-pt1.y;
float dy1=pt4.y-pt3.y;
//求解lambda:
浮点div=(dy0*dx1)-(dx0*dy1);
如果(abs(div)
也有一个公式,使用THETA和Rho直接计算,如果你预先假定,
测试<代码> M1= M2假定线是完全平行的,实际上不是这样的,因此一个交叉点被报告得很远。你应该考虑一个阈值在dx
或dx1
非常小时m1
和m2
变得非常不稳定。将候选点推送到向量后,可以过滤掉那些超出图像边界的点。可以打印所有“继续”案例,并找出你自己,为什么他们被跳过意外或是否有一些线根本没有处理。如果他们不是完全平行的话,我希望5条线有20个交点。你能分享(链接到)theta rho公式吗?请看答案中有该公式的数学和代码