我有一对笛卡尔坐标代表图像中的一条线。我想将此行转换为极坐标形式并将其绘制在图像上。
e.g
cv::Vec4f line {10,20,60,70};
float x1 = line[0];
float y1 = line[1];
float x2 = line[2];
float y2 = line[3];
我希望这行以cv :: Vec2f形式(rho,theta)表示。
照顾rho& theta有所有可能的斜坡。
给出的是图像尺寸:: w和h;
w = image.cols h = image.rows
我怎样才能做到这一点。
N.B:我们还可以假设该线可以是在图像上运行的扩展线。
for (size_t i = 0; i < lines.size(); i++)
{
int x1 = lines[i][0];
int y1 = lines[i][1];
int x2 = lines[i][2];
int y2 = lines[i][3];
float d = sqrt(((y1-y2)*(y1-y2)) + ((x2-x1)*(x2-x1)) );
float rho = (y1*x2 - y2*x1)/d;
float theta = atan2(x2 - x1,y1-y2) ;
if(rho < 0){
theta *= -1;
rho *= -1;
}
linv2f.push_back(cv::Vec2f(rho,theta));
}
当我绘制线条时,上面的方法并没有给我结果我没有得到与原始vec4f形式重叠的线条。
我使用它将vec2f转换为vec4f进行测试:
cv::Vec4f cvtVec2fLine(const cv::Vec2f& data, const cv::Mat& img)
{
float const rho = data[0];
float const theta = data[1];
cv::Point pt1,pt2;
if((theta < CV_PI/4. || theta > 3. * CV_PI/4.)){
pt1 = cv::Point(rho / std::cos(theta), 0);
pt2 = cv::Point( (rho - img.rows * std::sin(theta))/std::cos(theta), img.rows);
}else {
pt1 = cv::Point(0, rho / std::sin(theta));
pt2 = cv::Point(img.cols, (rho - img.cols * std::cos(theta))/std::sin(theta));
}
cv::Vec4f l;
l[0] = pt1.x;
l[1] = pt1.y;
l[2] = pt2.x;
l[3] = pt2.y;
return l;
}
答案 0 :(得分:3)
rho-theta方程有形式
x * Cos(Theta) + y * Sin(Theta) - Rho = 0
我们希望通过两点来表示等式&#39;到rho-theta形式(page 92 in pdf here)。如果我们有
x * A + y * B - C = 0
并且需要三角形式的系数,我们可以将所有方程除以(A,B)系数向量的大小。
D = Length(A,B) = Math.Hypot(A,B)
x * A/D + y * B/D - C/D = 0
请注意(A/D)^2 + (B/D)^2 = 1
- 基本三角函数相等,因此我们可以将A/D
和B/D
视为余弦和正弦角度θ的正弦。
你的线方程是
(y-y1) * (x2-x1) - (x-x1) * (y2-y1) = 0
or
x * (y1-y2) + y * (x2-x1) - (y1 * x2 - y2 * x1) = 0
let
D = Sqrt((y1-y2)^2 + (x2-x1)^2)
so
Theta = ArcTan2(x2-x1, y1-y2)
Rho = (y1 * x2 - y2 * x1) / D
<强>编辑强>
如果Rho为负数,则改变Rho的符号,通过Pi移动Theta
示例:
x1=1,y1=0, x2=0,y2=1
Theta = atan2(-1,-1)=-3*Pi/4
D=Sqrt(2)
Rho=-Sqrt(2)/2 negative =>
Rho = Sqrt(2)/2
Theta = Pi/4
Back substitutuon - 找到与轴的交点
0 * Sqrt(2)/2 + y0 * Sqrt(2)/2 - Sqrt(2)/2 = 0
x=0 y=1
x0 * Sqrt(2)/2 + 0 * Sqrt(2)/2 - Sqrt(2)/2 = 0
x=1 y=0