使用Opencv和C ++在垂直方向上绘制两点之间的直线

时间:2017-03-29 15:03:56

标签: opencv image-processing line

我尝试使用两个参考点画一条直线,我在垂直方向上遇到了一些问题。

这是当前的源代码:

cv::Mat img = cv::Mat::zeros(600,600,CV_8UC3);
cv::Point p1(306,41);
cv::Point p2(304,8);

cv::Point p(0,0), q(img.cols, img.rows);
if (p1.x != p2.x) {
    double m = (double) (p1.y - p2.y) / (double) (p1.x - p2.x);
    double b = p1.y - (m * p1.x);
    p.y = m * p.x + b;
    q.y = m * q.x + b;
} else {
    p.x = q.x = p2.x;
    p.y = 0;
    q.y = img.rows;
}

cv::circle(img, p1, 4, cv::Scalar(255,0,255), -1);
cv::circle(img, p2, 4, cv::Scalar(255,0,255), -1);
cv::line(img, p, q, cv::Scalar(0,0,255), 2);

这是以下输出: enter image description here

我做错了什么?

3 个答案:

答案 0 :(得分:3)

我遇到了与2.4.9版本相同的问题。鉴于Miki anwser,它可能已在新版本上修复。

当线斜率太高而且因此与y轴的交点远离原点时,似乎会出现问题。

我测试了引用的观点,以及许多其他人,以下函数处理了这个问题。它基本上计算计算线与图像边界的交点,并返回图像边界中的共线点。

void getLinePointinImageBorder(const cv::Point& p1_in, const cv::Point& p2_in,
                               cv::Point& p1_out, cv::Point& p2_out, 
                               int rows, int cols)
{
    double m = (double) (p1_in.y - p2_in.y) / (double) (p1_in.x - p2_in.x + std::numeric_limits<double>::epsilon());
    double b = p1_in.y - (m * p1_in.x);

    std::vector<cv::Point> border_point;
    double x,y;
    //test for the line y = 0
    y = 0;
    x = (y-b)/m;
    if(x > 0 && x < cols)
        border_point.push_back(cv::Point(x,y));

    //test for the line y = img.rows
    y = rows;
    x = (y-b)/m;
    if(x > 0 && x < cols)
        border_point.push_back(cv::Point(x,y));

    //check intersection with horizontal lines x = 0
    x = 0;
    y = m * x + b;
    if(y > 0 && y < rows)
        border_point.push_back(cv::Point(x,y));

    x = cols;
    y = m * x + b;
    if(y > 0 && y < rows)
        border_point.push_back(cv::Point(x,y));

    p1_out = border_point[0];
    p2_out = border_point[1];
}

答案 1 :(得分:1)

我无法使用您的代码重现错误。此代码(从您的代码中复制和粘贴)效果很好:

#include <opencv2\opencv.hpp>

using namespace std;
using namespace cv;

int main() {

    cv::Mat img = cv::Mat::zeros(600,600,CV_8UC3);
    cv::Point p1(301,49);
    cv::Point p2(303,460);

    cv::Point p(0,0), q(img.cols, img.rows);
    if (p1.x != p2.x) {
        double m = (double) (p1.y - p2.y) / (double) (p1.x - p2.x);
        double b = p1.y - (m * p1.x);
        p.y = m * p.x + b;
        q.y = m * q.x + b;
    } else {
        p.x = q.x = p2.x;
        p.y = 0;
        q.y = img.rows;
    }

    cv::circle(img, p1, 4, cv::Scalar(255,0,255), -1);
    cv::circle(img, p2, 4, cv::Scalar(255,0,255), -1);
    cv::line(img, p, q, cv::Scalar(0,0,255), 2);

    imshow("Result", img);
    waitKey();

    return 0;
}

enter image description here

答案 2 :(得分:1)

这是known bug,现已修复。

因此,在绘制线之前,请更新到最新版本的OpenCV(版本3.2)或使用cv::clipLine(img.size(), p, q);

@sturkmen

的所有学分
相关问题