Computer >> 컴퓨터 >  >> 프로그래밍 >> Java

Java로 구현하는 OpenCV 허프 라인 변환(Hough Line Transform) 완벽 가이드


허프 라인 변환이란?

이미지 속 직선을 검출하고 싶다면 허프 라인 변환(Hough Line Transform)을 활용할 수 있습니다. OpenCV에서는 두 가지 종류의 허프 라인 변환을 제공합니다. 바로 표준 허프 라인 변환(Standard Hough Line Transform)확률적 허프 라인 변환(Probabilistic Hough Line Transform)입니다.

1. 표준 허프 라인 변환 — HoughLines()

표준 허프 라인 변환은 Imgproc 클래스의 HoughLines() 메서드를 통해 적용할 수 있습니다. 이 메서드는 다음과 같은 매개변수를 받습니다.

  • 원본 이미지와, 검출된 선들의 파라미터(r, Φ)를 저장할 벡터를 나타내는 두 개의 Mat 객체

  • r(픽셀 단위)과 Φ(라디안 단위) 파라미터의 해상도를 나타내는 두 개의 double 변수

  • 하나의 선으로 인정하기 위해 필요한 최소 교차점 수를 나타내는 정수값

2. 확률적 허프 라인 변환 — HoughLinesP()

확률적 허프 라인 변환은 Imgproc 클래스의 HoughLinesP() 메서드를 사용합니다(매개변수는 동일). 이 방식은 이미지의 모든 점이 아닌 일부 무작위 점만 분석하기 때문에 연산 속도가 빠르고, 검출된 선분의 시작점과 끝점 좌표를 직접 얻을 수 있다는 장점이 있습니다.

Canny 엣지 검출 — Canny()

허프 변환을 적용하기 전에는 대체로 엣지(윤곽선) 검출이 선행되어야 합니다. Imgproc 클래스의 Canny() 메서드를 사용하면 이미지의 엣지를 검출할 수 있으며, 이 메서드는 다음 매개변수를 받습니다.

  • 원본 이미지와 결과 이미지를 나타내는 두 개의 Mat 객체

  • 임계값(threshold) 두 개를 저장하는 double 변수

Canny 엣지 검출 수행 절차

  1. Imgcodecs 클래스의 imread() 메서드로 원본 이미지를 불러옵니다.

  2. Imgproc 클래스의 cvtColor() 메서드로 그레이스케일 이미지로 변환합니다.

  3. Imgproc 클래스의 blur() 메서드에 커널 값 3을 지정하여 노이즈를 줄입니다.

  4. 블러 처리된 이미지에 Imgproc의 canny() 메서드로 엣지 검출 알고리즘을 적용합니다.

  5. 모든 값이 0인 빈 행렬을 생성합니다.

  6. Mat 클래스의 copyTo() 메서드로 검출된 엣지를 해당 행렬에 복사합니다.

예제 코드

import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javafx.application.Application;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.image.ImageView;
import javafx.scene.image.WritableImage;
import javafx.stage.Stage;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
public class HoughLineTransform extends Application {
   public void start(Stage stage) throws IOException {
      //OpenCV 코어 라이브러리 로드
      System.loadLibrary( Core.NATIVE_LIBRARY_NAME );
      String file ="D:\\Images\\road4.jpg";
      Mat src = Imgcodecs.imread(file);
      //이미지를 그레이스케일로 변환
      Mat gray = new Mat();
      Imgproc.cvtColor(src, gray, Imgproc.COLOR_RGBA2GRAY);
      //엣지 검출
      Mat edges = new Mat();
      Imgproc.Canny(gray, edges, 60, 60*3, 3, false);
      //Canny 결과의 색상 변경
      Mat cannyColor = new Mat();
      Imgproc.cvtColor(edges, cannyColor, Imgproc.COLOR_GRAY2BGR);
      //(canny 결과에서) 허프 라인 검출
      Mat lines = new Mat();
      Imgproc.HoughLines(edges, lines, 1, Math.PI/180, 150);
      for (int i = 0; i < lines.rows(); i++) {
         double[] data = lines.get(i, 0);
         double rho = data[0];
         double theta = data[1];
         double a = Math.cos(theta);
         double b = Math.sin(theta);
         double x0 = a*rho;
         double y0 = b*rho;
         //이미지 위에 선 그리기
         Point pt1 = new Point();
         Point pt2 = new Point();
         pt1.x = Math.round(x0 + 1000*(-b));
         pt1.y = Math.round(y0 + 1000*(a));
         pt2.x = Math.round(x0 - 1000*(-b));
         pt2.y = Math.round(y0 - 1000 *(a));
         Imgproc.line(cannyColor, pt1, pt2, new Scalar(0, 0, 255), 3);
      }
      //행렬을 JavaFX writable 이미지로 변환
      Image img = HighGui.toBufferedImage(cannyColor);
      WritableImage writableImage= SwingFXUtils.toFXImage((BufferedImage) img, null);
      //이미지 뷰 설정
      ImageView imageView = new ImageView(writableImage);
      imageView.setX(10);
      imageView.setY(10);
      imageView.setFitWidth(575);
      imageView.setPreserveRatio(true);
      //Scene 객체 설정
      Group root = new Group(imageView);
      Scene scene = new Scene(root, 595, 400);
      stage.setTitle("Hough Line Transform");
      stage.setScene(scene);
      stage.show();
   }
   public static void main(String args[]) {
      launch(args);
   }
}

입력 이미지

Java로 구현하는 OpenCV 허프 라인 변환(Hough Line Transform) 완벽 가이드

실행 결과

위 코드를 실행하면 다음과 같은 출력 결과를 확인할 수 있습니다.

Java로 구현하는 OpenCV 허프 라인 변환(Hough Line Transform) 완벽 가이드