본문 바로가기
Open CV

opencv c++ Hough 확률적 라인 변환

by 빈이쥬 2023. 1. 17.

​​높은 수준의 정확도를 유지하면서 알고리즘의 계산 비용을 줄이도록 설계된 허프 라인 변환의 변형이다.

 

이미지에서 점을 무작위로 샘플링하고 이 점을 사용하여 Hough 공간의 선에 투표하는 방식으로 작동한다.

이렇게 하면 처리해야 하는 포인트 수가 줄어들어 라인 감지 프로세스가 더 빨라질수 있다.

 

확률적 허프 라인 변환은 이미지에서 점의 샘플만 가져오기 때문에 기존 허프 라인 변환보다 빠르지만 이미지의 일부 라인이 누락될 수 있기 때문에 클래식 허프 라인 변환만큼 정확하지 않을 수 있다.

 

적용하는 함수는 다음과 같다. 

 

HoughLinesP(src, lines, rho, theta, threshold, minlineLength, maxLineGap)

 

  • src – 8비트, 단일 채널 이진 입력이미지
  • lines – 라인 출력 벡터. 각 라인은 요소 4개를 가진 벡터로 표시됨. 여기서 (x1,y1) 및 (x2,y2)는 감지된 각 선분의 끝점이다.
  • rho - 거리 해상도(픽셀 단위 0~1 실수)
  • theta – 각도 분해능 𝜃 (라디안 단위 0~180)
  • threshold - 임계값 만나는 점의 기준 숫자가 작으면 많은 선이 검출되지만 정확성이 떨어짐
  • minLineLength - 선의 최소 길이
  • maxLineGap - 같은 선 사이에 허용되는 최대 간격

소스코드

1. cvtColor() 함수를 사용하여 회색조로 변환한다.

2. Canny() 함수를 사용하여 Canny 에지 감지를 수행한다.

3. HoughLinesP( ) 함수를 사용하여 확률적 Hough 변환을 수행한다.

 

#include <opencv2/opencv.hpp>
#include <iostream>
#include <opencv2/imgproc.hpp>

using namespace cv;
using namespace std;

int main(int argc, char* argv[])
{
    
    string url = "http://192.168.0.123";
    
    // Open the default camera
    VideoCapture cap(url);

    // Check if the camera is opened
    if(!cap.isOpened())
    {
        cout << "Error opening camera" << endl;
        return -1;
    }
 
    // Capture frames from the camera in a loop
    while(true)
    {
        // Capture a frame
        Mat frame;
        cap >> frame;
        
        // Check if the frame is empty
        if(frame.empty())
        {
            cout << "Empty frame" << endl;
           break;
        }
//      Convert the image to grayscale
        Mat gray;
        cvtColor(frame,gray,COLOR_RGB2GRAY);
        imshow("gray", gray);

//        Canny edge detection
        Mat edges;
        Canny(gray, edges, 100, 100);
        imshow("edges", edges);
        
        // Perform Probabilistic Hough line transformation
        vector<Vec4i> lines;
        HoughLinesP(edges, lines, 1, CV_PI/180, 50, 50, 10);

        // Draw the lines on the image
        Mat result = frame.clone();
        for(size_t i = 0; i < lines.size(); i++) {
            Vec4i l = lines[i];
            line(result, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(255,255,255), 2);
        }

        imshow("Hough Lines", result);
        // Press 'q' to exit the loop
        if(waitKey(1) == 'q')
        {
            break;
        }
    }

    // Release the camera
    cap.release();

    return 0;
}

 

 

소스코드 리뷰

Canny(): 이 함수는 이미지에서 Canny 에지 감지를 수행한다.

첫 번째 인수는 입력 이미지,

두 번째 인수는 출력 이미지,

세 번째 및 네 번째 인수는 각각 가장자리의 하한 및 상한 임계값이다.

Mat edges;
Canny(gray, edges, 100, 100);

 

 

HoughLinesP(): 확률적 Hough 라인 변환을 수행한다

첫 번째 인수는 입력 이미지,

두 번째 인수는 이미지의 시작점(x1, y1)과 끝점(x2, y2)으로 표시되는 라인의 출력 벡터

세 번째 인수는 거리 해상도(픽셀),

네 번째 인수는 각도 해상도(라디안), 값이 낮을수록 해상도가 높아져 라인 감지가 더 정확해지지만 느려진다

다섯 번째 인수는 선의 임계값이며, 충분하지 않은 선을 필터링하는 데 사용된다. 값이 높을수록 더 적은 선이 감지됨

여섯번째 인수는 선의 최소 길이로 너무 짧아서 유효한 차선으로 간주되지 않는 선을 필터링함

일곱번째 인수는 선의 최대 간격. 끝점 사이 간격이 너무 큰 선을 필터링 함

 

vector<Vec2f> :  부동 좌표가 있는 4D 벡터 모음을 저장하는 변수이다.

vector<Vec4i> lines;
HoughLinesP(edges, lines, 1, CV_PI/180, 50, 50, 10);

 

  • line(): 이미지에 선을 그린다. 첫 번째 인수는 입력 이미지, 두 번째 및 세 번째 인수는 각각 선의 시작점과 끝점, 네 번째 인수는 선의 색상, 다섯 번째 인수는 선의 두께이다. 색상 - 255, 255, 255(흰색) 선의 두께 - 2
Mat result = frame.clone();
for(size_t i = 0; i < lines.size(); i++) {
	Vec4i l = lines[i];
    line(result, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(255,255,255), 2);
}

 

 

출력