자율주행

OpenCV Hough Transform에 의해 추출된 직선의 속성 확인 : 개인별 과제

coding art 2023. 5. 19. 20:20
728x90
OpenCV에서 휴변환에 따라 line 요소가 구체적으로 어떤 형태로 얻어지는지 인위적인 그림 파일을 만들어 적용해 보자.

그림판을 사용하여 픽셀 해상도가 640 x 480 이 되도록 크기를 정한 후 화면 중앙에 수평선을 그은 후 파일명을 rect_line, 확장자를 jpg 로 저장하자.

아래의 이미지 파일을 다운받아 활용하자.single_line_detection.py 

rect_line.jpg
0.01MB

 

한편 그림판에서 수평선을 긴 직사각형으로 확대한 후 커서를 사용하여 위와 아래 코너의 좌표를 찍어 보면 (0, 238) (0, 242) 좌표 값을 얻을 수 있다.

오른쪽 끝의 좌표는 (639,238) (639, 242) 를 얻을 수 있다.

 

cv2.imread 명령을 사용하여 “rect_line.jpg”를 읽어 img 로 두고 복제하여 dst 로 두자.

Canny 필터 명령에 필요한 밟기의 최대 intensity1000 으로 하한을 400 으로 설정하자. Canny 필터링으로 추출된 직선형 edge 데이터를 사용하여 Hough 변환작업을 하자. (ρ, θ)로 표현되는 Hough 좌표 공간에서 2ρ 값을 뜻한다.

1 import cv2 ; import numpy as np
img = cv2.imread("rect_line.jpg")
dst = np.copy(img)
th1 = 1000 ; th2 = 0.4 * th1
edges = cv2.Canny(img, th1, th2)
print(edges.shape)
edges.shape : (480, 640)

 

cv2.HoughLinesP 명령을 실행하여 lines 로 두고 그 값과 shape을 출력해 보자.

lines 의 출력 값을 보면 그림판에서 커서로 조사했던 값 범위 내에 있으며 수평선의 선 굵기가 249 239 = 3 이 됨을 알 수 있다. 아울러 lineㄴ 의 첫 번째 리스트 데이터는 굵은 수평선의 위부분을 두 번째 리스트 데이터는 아랫 부분을 나타냄을 알 수 있다. 즉 굵기에 해당하는 짧은 쪽은 배제된다는 점에 유의하자.

2 lines = cv2.HoughLinesP(edges, 2, np.pi/180.0, 100, minLineLength=10, maxLineGap=100)
print(lines)
print(lines.shape)
lines : [[[ 0 239 639 239]] [[ 0 242 639 242]]]
lines.shape : (2, 1, 4)

 

아나콘다 spyder 편집기 셸(shell)에서 리스트 데이터로 출력되는 lines 의 속성이 np.array( [⦁⦁⦁]) 와 일치하는지 확인해 보기 위해서 역으로 linex, liney, linexy 를 출력해 동일한 결과가 나오는지 확인해 보자.

3 for line in lines:
print(line.shape)
x1,y1,x2,y2 = line[0]
cv2.line(dst, (x1,y1), (x2,y2), (0,0,255), 1)
linex = np.array([0,239, 639, 239])
print('linex :', linex)
liney = np.array([0, 242, 639, 242])
print('liney :', liney)
linexy = np.array([[[0,239, 639, 239]], [[0, 242, 639, 242]]] )
print('linexy : ', linexy)
(1, 4)
(1, 4)
linex : [ 0 239 639 239]
liney : [ 0 242 639 242]
linexy : [[[ 0 239 639 239]]

 

동알한 결과를 출력함이 확인된다.

출력된 이미지를 참조하자.

 
 

위의 이미지 파일과 아래의 파이선 코드를 다운받아 실행시켜 보자.

 

# single_line_detection.py
import cv2 ; import numpy as np

img = cv2.imread("rect_line.jpg")
dst = np.copy(img)

th1 = 1000 ; th2 = 0.4 * th1
edges = cv2.Canny(img, th1, th2)
print('edges.shape : ', edges.shape)
    
lines = cv2.HoughLinesP(edges, 2, np.pi/180.0, 100, minLineLength=10, maxLineGap=100)
print('lines : ', lines)
print('lines.shape :', lines.shape)

for line in lines: 
    print(line.shape)
    x1,y1,x2,y2 = line[0] 
    cv2.line(dst, (x1,y1), (x2,y2), (0,0,255), 1)
    
linex = np.array([0,239, 639, 239])
print('linex :', linex)
liney = np.array([0, 242, 639, 242])
print('liney :', liney) 
linexy = np.array([[[0,239, 639, 239]], [[0, 242, 639, 242]]] )
print('linexy : ', linexy)

cv2.imshow("Rect and line Geometry", img)
cv2.imshow("Edges", edges)
    
    
while True:
    key = cv2.waitKey(1)
    if key == 27: 
        break
    
cv2.destroyAllWindows()