将cv :: Vec4f行转换为cv :: Vec2f

时间:2017-01-05 18:55:01

标签: opencv geometry

我有一对笛卡尔坐标代表图像中的一条线。我想将此行转换为极坐标形式并将其绘制在图像上。

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;
}

1 个答案:

答案 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/DB/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