簡體   English   中英

如何在OpenCV(Java)中使用HoughLines檢測行?

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

我目前正在嘗試檢測是否在OpenCV使用HoughLines在圖像上部署了水平交叉障礙。 我以為我的代碼會在我的圖像上畫一條線,只要屏障出現在其中 - 但我得到一條錯誤消息“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);

}

}

這些線在行矩陣中返回,該矩陣有兩列,其中每一行返回極坐標的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;
}

這是一種更簡單的方法。 它涉及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;
}

在Android或Java中它是相同的idia.you必須在for(); 得到的θ和行你得到起點和終點后,可以將核心線(core.line),但不要忘了轉移,你得到的值從她到其他墊子。 在此之后>>釋放墊子。 希望這是它的幫助uri享受

編輯:請參閱lordache的答案 ,該答案是特定於Java的。

有用的閱讀: 如何用Java中的OpenCV Mat表示雙元素向量?


查看本教程並查找“標准Hough Line變換”部分。

lines不應該是cv::Mat ,而是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);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM