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

Zet*_*and 5 java opencv

我目前正在尝试检测是否已使用HoughLinesin在图像上部署了平交道口屏障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);

}

}
Run Code Online (Sandbox Code Playgroud)

Ior*_*aur 9

这些线在行矩阵中返回,该矩阵有两列,其中每一行返回极坐标的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;
}
Run Code Online (Sandbox Code Playgroud)

这是一种更简单的方法.它涉及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;
}
Run Code Online (Sandbox Code Playgroud)

  • 行在行而不是列中返回 - 因此在循环中使用 `lines.cols()` 和 `lines.get(i, 0)` (2认同)

小智 1

在 Android 或 Java 中它是相同的 idia。你必须在 for (); 中执行此操作;要在获得起点和终点后获得 theta 和行,您可以对线进行取芯。(core.line)但不要忘记将您从她那里获得值的垫子转移到其他人。之后>>释放垫子。希望这对你有帮助