Computer >> 컴퓨터 >  >> 프로그램 작성 >> Python

OpenCV를 사용하여 파이썬에서 라인 감지?

<시간/>

이 게시물에서는 Hough 변환이라는 기술을 사용하여 이미지에서 선을 감지하는 방법을 배울 것입니다.

허프 변환?

허프 변환은 수학적 형식으로 해당 모양을 나타낼 수 있는 경우 간단한 모양을 감지하는 특징 추출 방법입니다. 모양이 조금 깨지거나 뒤틀리더라도 어떻게든 감지할 수 있습니다. 라인에서 어떻게 작동하는지 살펴보겠습니다.

"단순한" 모양은 몇 가지 매개변수로 나타낼 수 있는 모양입니다. 예를 들어, 선은 두 개의 매개변수(기울기, 절편)로만 나타낼 수 있고 원에는 중심 좌표와 반지름(x,y, r)의 세 가지 매개변수가 있습니다.

허프 변환을 사용하여 이미지에서 선 감지

선은 방정식 또는 매개변수 형식으로 나타낼 수 있습니다. 여기서 (ρ)는 원점에서 선까지의 수직 거리이고 ϴ는 카운터에서 측정된 이 수직선과 수평축이 이루는 각도입니다. -시계 방향(이 표현은 OpenCV에서 사용됨). 아래 이미지 확인


OpenCV를 사용하여 파이썬에서 라인 감지?

따라서 선이 원점 아래로 지나가면 양의 rho와 180보다 작은 각도가 됩니다. 원점 위로 가는 경우 180보다 큰 각도를 취하는 대신 각도는 180보다 작게 취하고 rho는 음수로 취합니다. 수직선은 0도이고 수평선은 90도입니다.

누적기

모든 선은 이 두 항(ρ,ϴ)으로 나타낼 수 있습니다. 따라서 먼저 2D 배열 또는 누산기(두 매개변수의 값을 유지하기 위해)를 만들고 처음에는 0으로 설정합니다. 여기서 행은 ρ를 나타내고 열은 ϴ를 나타냅니다. 배열의 크기는 필요한 정확도에 따라 다릅니다. 예를 들어 각도의 정확도가 1도가 되어야 하는 경우 180개의 열이 필요하고 ρ는 가능한 최대 거리는 이미지의 대각선 길이이고 ρ는 가능한 최대 거리입니다. 는 이미지의 대각선 길이입니다. 따라서 1픽셀 정확도와 행 수를 취하면 이미지의 대각선 길이가 될 수 있습니다.

중앙에 수평선이 있는 100*100 이미지가 있다고 가정합니다. 선의 첫 번째 점을 선택하면 (x,y) 값을 알 수 있습니다. 이제 방정식에서 값 ϴ=0,1,2,3…180을 pu로 지정하고 얻은 ρ 값을 확인합니다. 모든 (ρ,ϴ) 쌍에 대해 1씩 증가하는 값은 해당 (ρ,ϴ) 셀의 누산기입니다. 이제 누산기에서 다른 셀과 함께 셀 (50,90) =1입니다. 이제 줄의 두 번째 자리를 차지하세요. 첫 번째 지점에서와 동일한 절차를 반복합니다. (ρ,ϴ)에 해당하는 셀의 값을 증가시킵니다. 이번에는 셀 (50,90)=2입니다. 그래서 우리는 실제로 (ρ,ϴ) 값에 투표하고 있습니다. 우리는 라인의 모든 점에 대해 이 프로세스를 계속합니다. 각 지점에서 셀(50,90)이 증가하거나 투표가 증가하는 반면 다른 셀은 투표되지 않을 수 있습니다. 이렇게 하면 결국 cell(50,90)이 최대 표를 갖게 됩니다. 따라서 누적기에서 최대 투표수를 검색하면 값 (50,90)을 얻을 수 있습니다. 즉, 이 이미지에 원점에서 50도 거리에 있고 각도 90도에 선이 있습니다. 이것이 라인에 대한 허프 변환이 작동하는 방식입니다.

OpenCV의 허프 변환

위에서 설명한 모든 것은 OpenCV 함수 cv2.HoughLines()에 캡슐화되어 있습니다. 단순히 ρ가 픽셀로 측정되고 ϴ가 라디안으로 측정되는 (ρ,ϴ) 값의 배열을 반환합니다.

아래는 openCV와 hough line transform을 이용한 line detection 프로그램입니다.

아래는 실제 주차장 이미지이며, 이 이미지에 대해 hough line transform과 OpenCV 라이브러리를 사용하여 라인 감지를 할 것입니다.

OpenCV를 사용하여 파이썬에서 라인 감지?

import cv2
import numpy as np
img = cv2.imread("parkingLot1.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray, 75, 150)
lines = cv2.HoughLinesP(edges, 1, np.pi/180, 30, maxLineGap=250)
for line in lines:
   x1, y1, x2, y2 = line[0]
   cv2.line(img, (x1, y1), (x2, y2), (0, 0, 128), 1)
cv2.imshow("linesEdges", edges)
cv2.imshow("linesDetected", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

결과

OpenCV를 사용하여 파이썬에서 라인 감지?

그리고 감지된 라인-

OpenCV를 사용하여 파이썬에서 라인 감지?