如何在 OpenCV (Java) 中使用 HoughLines 检测线条?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29493267/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to detect lines using HoughLines in OpenCV (Java)?
提问by Zetland
I'm currently trying to detect whether a level crossing barrier has been deployed on an image using HoughLines
in OpenCV
. I thought my code would draw a line on my image, so long as the barrier appears in it - but instead I get an error message saying "Mat data type is not compatible". Can show me how to detect lines in Java with OpenCV?
我目前正在尝试使用HoughLines
in检测是否在图像上部署了平交障碍OpenCV
。我以为我的代码会在我的图像上画一条线,只要障碍出现在其中 - 但我收到一条错误消息,说“Mat 数据类型不兼容”。可以告诉我如何使用 OpenCV 检测 Java 中的行吗?
public class DetectLines {
public static void main(String args[]) {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
Mat eventless = Highgui.imread("files/eventless.png");
Mat barrier = Highgui.imread("files/barrier/lc-00201.png");
Mat difference = new Mat();
Mat lines = new Mat();
Core.absdiff(eventless, barrier, difference);
Mat grey = new Mat();
Imgproc.cvtColor(difference, grey, Imgproc.COLOR_BGR2GRAY);
Imgproc.HoughLines(grey, lines, 5.0, 4.0, 7);
Imshow ims1 = new Imshow("Lines");
ims1.showImage(lines);
}
}
回答by Iordache Laur
The lines are returned in the lines matrix, which has two columns in which each line returns the rho and theta parameters of the polar coordinates. These coordinates refer to the distance between the top-left corner of the image and the line rotation in radians, respectively. So, in order to use the show method you must create a Mat that will represent the lines using the line coordinates.
行在行矩阵中返回,该矩阵有两列,其中每行返回极坐标的 rho 和 theta 参数。这些坐标分别是指图像左上角和以弧度为单位的线旋转之间的距离。因此,为了使用 show 方法,您必须创建一个 Mat 来表示使用线坐标的线。
public Mat getHoughTransform(Mat image, double rho, double theta, int threshold) {
Mat result = Image.getInstance().getImage().clone();
Mat lines = new Mat();
Imgproc.HoughLines(image, lines, rho, theta, threshold);
for (int i = 0; i < lines.cols(); i++) {
double data[] = lines.get(0, i);
double rho1 = data[0];
double theta1 = data[1];
double cosTheta = Math.cos(theta1);
double sinTheta = Math.sin(theta1);
double x0 = cosTheta * rho1;
double y0 = sinTheta * rho1;
Point pt1 = new Point(x0 + 10000 * (-sinTheta), y0 + 10000 * cosTheta);
Point pt2 = new Point(x0 - 10000 * (-sinTheta), y0 - 10000 * cosTheta);
Imgproc.line(result, pt1, pt2, new Scalar(0, 0, 255), 2);
}
return result;
}
And this is a easier way to do it. It involve the Imgproc.HoughLinesP method.
这是一种更简单的方法。它涉及到 Imgproc.HoughLinesP 方法。
public Mat getHoughPTransform(Mat image, double rho, double theta, int threshold) {
Mat result = Image.getInstance().getImage().clone();
Mat lines = new Mat();
Imgproc.HoughLinesP(image, lines, rho, theta, threshold);
for (int i = 0; i < lines.cols(); i++) {
double[] val = lines.get(0, i);
Imgproc.line(result, new Point(val[0], val[1]), new Point(val[2], val[3]), new Scalar(0, 0, 255), 2);
}
return result;
}
回答by reffael i
in Android or Java its the same idia.you must to do it in for (); to get the theta and row after you get start point and the end point ,you can core the line.(core.line) but dont forget to transfer the mat that you get the values from her to other. after this>>release the mat. hope thats its help u. r.i enjoy
在 Android 或 Java 中,它具有相同的 idia。您必须在 for () 中执行此操作;要在获得起点和终点后获得 theta 和行,您可以对线进行核心处理。(core.line)但不要忘记将您从她那里获得值的垫子转移到其他地方。在此之后>>松开垫子。希望这是它的帮助 uri 享受
回答by Antonio
Edit: See lordache's answerwhich is Java specific.
编辑:请参阅lordache 的答案,这是特定于 Java 的。
Useful reading: How are two-element vector represented in a OpenCV Mat in Java?
有用的阅读:如何在 Java 中的 OpenCV Mat 中表示二元素向量?
Check this tutorialand look for the section "Standard Hough Line Transform".
检查本教程并查找“标准霍夫线变换”部分。
lines
should not be a cv::Mat
, but a std::vector<cv::Vec2f> lines;
that later on you can visualize with a code like the one showed in the link:
lines
不应该是 a cv::Mat
,而是 a std::vector<cv::Vec2f> lines;
,稍后您可以使用链接中显示的代码进行可视化:
for( size_t i = 0; i < lines.size(); i++ )
{
float rho = lines[i][0], theta = lines[i][1];
Point pt1, pt2;
double a = cos(theta), b = sin(theta);
double x0 = a*rho, y0 = b*rho;
pt1.x = cvRound(x0 + 1000*(-b));
pt1.y = cvRound(y0 + 1000*(a));
pt2.x = cvRound(x0 - 1000*(-b));
pt2.y = cvRound(y0 - 1000*(a));
line( cdst, pt1, pt2, Scalar(0,0,255), 3, CV_AA);
}