问题就是这么说,
我知道函数Line()
,它在两点之间绘制线段。
我需要使用线段的两个点绘制线 NOT 线段。
[EN:根据以前发布的问题编辑作为问题的答案]
我使用了你的解决方案,它在水平线上表现不错,但我在垂直线上仍然遇到问题。
例如,下面的示例使用点[306,411]和[304,8](紫色)和绘制线(红色),在600x600像素的图像上。你有什么小费吗?
答案 0 :(得分:8)
我认为这是一个非常古老的问题。我有完全相同的问题,我使用了这个简单的代码:
double Slope(int x0, int y0, int x1, int y1){
return (double)(y1-y0)/(x1-x0);
}
void fullLine(cv::Mat *img, cv::Point a, cv::Point b, cv::Scalar color){
double slope = Slope(a.x, a.y, b.x, b.y);
Point p(0,0), q(img->cols,img->rows);
p.y = -(a.x - p.x) * slope + a.y;
q.y = -(b.x - q.x) * slope + b.y;
line(*img,p,q,color,1,8,0);
}
首先,我计算线段的斜率,然后将线段“延伸”到图像的边界。我计算线的新点,它位于x = 0和x = image.width。点本身可以在Image之外,这是一种讨厌的技巧,但解决方案非常简单。
答案 1 :(得分:6)
您需要编写一个函数来自己完成。我建议你把你的线放在ax + + + c = 0形式,然后将它与图像的4个边相交。请记住,如果你在[a b c]形式中找到一条线,那么找到它与另一条线的交叉点只是两者的交叉积。图像的边缘将是
top_horizontal = [0 1 0];
left_vertical = [1 0 0];
bottom_horizontal = [0 1 -image.rows];
right_vertical = [1 0 -image.cols];
另外,如果你对点之间的距离有所了解,你也可以在每个方向的线上选择很远的点,我不认为传递给Line()的点需要在图像上。< / p>
答案 2 :(得分:4)
我遇到了同样的问题,发现在2.4.X OpenCV上有一个known bug,已经为新版本修复了。
对于2.4.X版本,解决方案是在使用cv::clipLine()
这里有一个我自己做的功能,可以在2.4.13 OpenCV上正常工作
void Detector::drawFullImageLine(cv::Mat& img, const std::pair<cv::Point, cv::Point>& points, cv::Scalar color)
{
//points of line segment
cv::Point p1 = points.first;
cv::Point p2 = points.second;
//points of line segment which extend the segment P1-P2 to
//the image borders.
cv::Point p,q;
//test if line is vertical, otherwise computes line equation
//y = ax + b
if (p2.x == p1.x)
{
p = cv::Point(p1.x, 0);
q = cv::Point(p1.x, img.rows);
}
else
{
double a = (double)(p2.y - p1.y) / (double) (p2.x - p1.x);
double b = p1.y - a*p1.x;
p = cv::Point(0, b);
q = cv::Point(img.rows, a*img.rows + b);
//clipline to the image borders. It prevents a known bug on OpenCV
//versions 2.4.X when drawing
cv::clipLine(cv::Size(img.rows, img.cols), p, q);
}
cv::line(img, p, q, color, 2);
}
答案 3 :(得分:1)
这个答案来自pajus_cz的回答,但有所改进。
我们有两点,我们需要得到线方程 y = mx + b
才能绘制直线。
我们需要获得两个变量
1- 斜率(m)
2- b ,可以使用我们在计算斜率b = y - mx
之后的两个点中的任何给定点通过线方程检索。
void drawStraightLine(cv::Mat *img, cv::Point2f p1, cv::Point2f p2, cv::Scalar color)
{
Point2f p, q;
// Check if the line is a vertical line because vertical lines don't have slope
if (p1.x != p2.x)
{
p.x = 0;
q.x = img->cols;
// Slope equation (y1 - y2) / (x1 - x2)
float m = (p1.y - p2.y) / (p1.x - p2.x);
// Line equation: y = mx + b
float 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::line(*img, p, q, color, 1);
}