참고 출처 : https://076923.github.io/posts/Python-opencv-28/
https://opencv-python.readthedocs.io/en/latest/doc/25.imageHoughLineTransform/imageHoughLineTransform.html
https://ko.wikipedia.org/wiki/%ED%97%88%ED%94%84_%EB%B3%80%ED%99%98
직선 검출 알고리즘
: 허프 변환(Hough Transform)을 활용 (위 출처의 이론적인 설명이 자세하게 나와 있습니다 )



위의 사진처럼 3개의 점에 대해서 원점에서 각 점까지의 거리를 𝜃, r로 표현할 수 있다.

이 곡선은 각 점(x, y)에 대해서 r=xsinθ+ycosθ을 만족한다.
허프 변환은 OpenCV의 cv2.HoughLines() 함수로 구현되어 있다.
void cv::HoughLines ( InputArray image, //검출 이미지 OutputArray lines, //line 반환 double rho, //거리 r (0 ~ 1) double theta, //각도 𝜃 (단위 : 라디안) int threshold, //임계값(문턱치)(숫자가 작을수록 많은 선 검출, 정확도 하락) double srn = 0, //srn과 stn은 멀티 스케일 허프 변환에 사용, 선 검출에서는 사용X double stn = 0, double min_theta = 0, //검출을 위해 사용할 최소 최대 각도 double max_theta = CV_PI ) //Python: //lines = cv.HoughLines( image, rho, theta, threshold[, lines[, srn[, stn[, min_theta[, max_theta]]]]] )
threshold : 같은 직선에 몇개의 점이 등장해야 직선으로 판단할 지에 대한 최소 갯수
srn과 stn : 거리와 각도에 대한 약수를 의미한다. 두 값이 모두 0이면 표준 허프 변환이 적용되고 하나라도 0이 아니라면 멀티 스케일 허프 변환이 적용된다.
이에 대한 예제 코드와 사용되는 이미지는 076923.github.io/posts/Python-opencv-28/ 에서 참고하여 사용하였다.
그리고 코드는 colab환경(python)에서 진행하였다.


Canny edge 검출기
: 낮은 검출 오류율, 에지 위치 오류 최소화, 단일 응답(하나의 edge에서 하나의 화소만 edge로 검출)
1. 가우시안 필터링을 통한 잡음 제거
2. 에지 크기와 방향 계산 -> Sobel filter를 사용

3. 비최대치 억제(non-maximum suppression)
- 주변의 edge와 비교해서 더 큰 크기를 가지기 않는 edge를 제거
즉, 주변보다 더 큰 크기를 갖는 edge만 남긴다. 주변은 에지의 방향에 따라 결정된다.
ex) 90도 기준 예시
(y, x-1) | (y, x) | (y, x+1) |
4. 이력 문턱치 처리(hysteresis thresholding)
- 두 개의 문턱치(큰 문턱치, 작은 문턱치)를 사용하여 처리 수행
큰 문턱치보다 큰 크기를 갖는 edge 살리고 작은 문턱치보다 작은 크기의 edge 제거
큰 문턱치와 작은 문턱치 사이의 edge는 큰 문턱치보다 큰 크기를 갖는 edge들과 연결되어 있으면 살아남고 그렇지 않으면 제거된다.


line은 거리와 각도로 반환되기 때문에 이것을 활용하여 다시 직선의 방정식 형태로 구성 후 이미지 위에 표현해준다.
x=rcosθ, y=rsinθ을 활용하여 x0, y0의 좌표를 구한다.
허프 변환 함수는 가장 직선일 가능성이 높은 거리와 각도를 검출해주기 때문에 (x0, y0)을 직선의 방정식 선분을 따라 평행이동 시켜 선을 그려주게 된다.
! 여기서 원점의 기준이 이미지 중앙인지 아니면 모서리 한부분인지는 정확히 알지 못하겠다.
(x1, y1), (x2, y2)를 구해줄 때 사용하는 식에서 scale은 그림 끝에서 끝까지 그리기 위한 큰 수로 꼭 위의 코드처럼 구하지 않아도 되고 임의로 큰 수를 넣어도 상관없다고 이해했다. a와 -b를 곱해줌으로써 (x1, y1), (x2, y2)이 (x0, y0)을
평행이동한 점으로 계산해주게 된다.

따라서 이렇게 진행한 결과 사진은 아래와 같다.

이 알고리즘을 보안하여 나온 것으로 점진성 확률적 허프 변환도 있다고 한다.
'study > 영상처리 & opencv' 카테고리의 다른 글
[영상처리] 2D변환 - Rigid Transformation (0) | 2021.01.27 |
---|---|
[영상처리] RANSAC 알고리즘 (0) | 2021.01.21 |
OpenCV(Open Source Computer Vision Library) (0) | 2020.12.27 |
[javascript/python] colab에서 웹캠 실행하기 (7) | 2020.09.08 |
[opencv] imread(), imshow(), imwrite(), matplotlib 왕기초 (0) | 2020.09.06 |