我正在使用OpenCV 3.2。
我想提取并绘制此图像中的所有行。
为此,我首先获得图像的轮廓。例如,我使用Canny算法,双阈值100(低)和200(高)。
Mat image = cv::imread(<image_path>, cv::IMREAD_GRAYSCALE);
cv::Mat contours;
cv::Canny(image, contours, 100, 200);
然后,我将HoughLines函数调用为1像素和π/ 45弧度的分辨率。我只想要那些长度至少为60像素的线条。
std::vector<cv::Vec2f> lines;
cv::HoughLines(canny, lines, 1, CV_PI/45, 60);
这会返回一个向量lines
,其中rho p
和theta θ
参数位于所需行的Hough空间中。众所周知,通过轮廓像素(x_i, y_i)
的线是:
p = x_i cos(θ) + y_i sin(θ)
我们知道p
和θ
,因此我们知道此行中的所有像素。要计算的两个简单点是A
x_i = 0
和B
y_i = 0
。
A = (0, p / sin(θ))
B = (p / cos(θ), 0)
让我们用蓝色的line函数绘制它们。
cv::cvtColor(image, image, CV_GRAY2BGR);
for (unsigned int i = 0; i < lines.size(); ++i) {
float p = lines[i][0];
float theta = lines[i][1];
cv::Point a(0, static_cast<int>(p / std::sin(theta)));
cv::Point b(static_cast<int>(p / std::cos(theta)), 0);
cv::line(image, a, b, cv::Scalar(255, 0, 0));
}
结果是它只画了6行,总共14行。如您所见,仅绘制与图像的第0行和第0列相交的那些线。同样,那些在图像边界中有A
和B
点的线。其余的线条在图像外面有这些点。
如何以简单的方式绘制所有线条?我可以计算获得的行的所有像素并绘制它们(我们知道它们),但我想通过最小化代码行和使用OpenCV api来绘制它们。