简体   繁体   English

如何在OpenCV(Java)中使用HoughLines检测行?

[英]How to detect lines using HoughLines in OpenCV (Java)?

I'm currently trying to detect whether a level crossing barrier has been deployed on an image using HoughLines in OpenCV . 我目前正在尝试检测是否在OpenCV使用HoughLines在图像上部署了水平交叉障碍。 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". 我以为我的代码会在我的图像上画一条线,只要屏障出现在其中 - 但我得到一条错误消息“Mat数据类型不兼容”。 Can show me how to detect lines in Java with OpenCV? 可以告诉我如何使用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);

}

}

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. 这些线在行矩阵中返回,该矩阵有两列,其中每一行返回极坐标的rho和theta参数。 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. 因此,为了使用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;
}

in Android or Java its the same idia.you must to do it in for (); 在Android或Java中它是相同的idia.you必须在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. 得到的θ和行你得到起点和终点后,可以将核心线(core.line),但不要忘了转移,你得到的值从她到其他垫子。 after this>>release the mat. 在此之后>>释放垫子。 hope thats its help uri enjoy 希望这是它的帮助uri享受

Edit: See lordache's answer which is Java specific. 编辑:请参阅lordache的答案 ,该答案是特定于Java的。

Useful reading: How are two-element vector represented in a OpenCV Mat in Java? 有用的阅读: 如何用Java中的OpenCV Mat表示双元素向量?


Check this tutorial and look for the section "Standard Hough Line Transform". 查看本教程并查找“标准Hough Line变换”部分。

lines should not be a cv::Mat , but a std::vector<cv::Vec2f> lines; lines不应该是cv::Mat ,而是std::vector<cv::Vec2f> lines; that later on you can visualize with a code like the one showed in the link: 稍后您可以使用链接中显示的代码进行可视化:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM