반응형

Hough Line Transform 구현 원리에 대해서 다룹니다.







유튜브에서 사용한 코드입니다.


import cv2 as cv
import numpy as np
import math
import time


img_original = cv.imread('square.jpg', cv.IMREAD_COLOR)

img_gray = cv.cvtColor(img_original, cv.COLOR_BGR2GRAY)
img_edge = cv.GaussianBlur(img_gray, (5, 5), 0, 0)
img_edge = cv.Canny(img_edge, 50, 150, 3)

height = img_edge.shape[0]
width = img_edge.shape[1]
tmp = min(height, width)
hough_height = int(1.5 * tmp)


accumulator_width = 180
accumulator_height = hough_height * 2
accumulator_size = accumulator_height * accumulator_width


accumulator = np.zeros((accumulator_height, accumulator_width))
table_sin = np.zeros(180)
table_cos = np.zeros(180)
DEG2RAD = np.pi / 180


for angle in range(0,180):
   table_sin[angle] = math.sin(np.radians(angle))
   table_cos[angle] = math.cos(np.radians(angle))


start=time.clock()

for y in range(0,height):
   for x in range(0,width):
       if img_edge.item(y, x) > 0:
           for angle in range(0,180):
               r = int(x * table_cos[angle] + y * table_sin[angle])
               r = r + hough_height # r이 음수인 경우 때문 -r ~ r 범위를 0 ~ 2r 범위로 변경
               accumulator[r, angle] +=1

end=time.clock()
print(end - start)



# accumulator를 이미지화
img_accumulator = np.ones((accumulator_height, accumulator_width, 3), np.uint8)
img_accumulator = img_accumulator * 255

accumulator2 = cv.convertScaleAbs(accumulator,3,5)

start=time.clock()
for r in range(0,accumulator_height):
   for angle in range(0,accumulator_width):

       value = accumulator2[r, angle]

       if value > 0:
           img_accumulator.itemset(r, angle, 0, 255 - value)
           img_accumulator.itemset(r, angle, 1, 255 - value)
           img_accumulator.itemset(r, angle, 2, 255 - value)


end=time.clock()
print(end - start)


start=time.clock()
count = 0
for r in range(0, accumulator_height):
   for angle in range(0,180):

       if accumulator.item(r,angle) > 80: # Hough Line Transform Threshold

           #현재 위치가 local maxima인지 검사
           max = accumulator[r, angle]
           for y in range(-5,6):
               for x in range(-5,6):

                   new_r = r + y
                   new_angle = angle + x

                   if new_angle < 0:
                       new_angle = 180 + new_angle
                   elif new_angle >= 180:
                       new_angle = new_angle - 180

                   if new_r >= 0 and new_r < accumulator_height:
                       if accumulator[new_r, new_angle] > max:
                           max = accumulator[new_r, new_angle]
                           x = y = 6 #local maxima 아님. loop 종료

           if max > accumulator.item(r, angle):
               continue #현재 위치는 local maxima가 아님


           # r = x * cos(theta) + y * sin(theta)
           # x = (r - y * sin(theta)) / cos(theta) # 수직선인 경우
           # y = (r - x * cos(theta)) / sin(theta) # 수평선인 경우


           if angle >= 45 and angle <= 135: # 수직선
               x1 = 0
               x2 = width
               y1 = ((r - hough_height) - x1 * table_cos[angle]) / table_sin[angle]
               y2 = ((r - hough_height) - x2 * table_cos[angle]) / table_sin[angle]

           else: #수평선
               y1 = 0
               y2 = height
               x1 = ((r - hough_height) - y1 * table_sin[angle]) / table_cos[angle]
               x2 = ((r - hough_height) - y2 * table_sin[angle]) / table_cos[angle]


           x1 = int(x1)
           y1 = int(y1)
           x2 = int(x2)
           y2 = int(y2)

           cv.circle(img_accumulator, (angle, r), 5, (255, 0, 0),-1)
           cv.line(img_original, (x1, y1), (x2, y2), (255, 0, 0), 1)
           count += 1

           print("(%d,%d)-(%d,%d), angle=%d, r=%d, accmulator=%d" % (x1,y1,x2,y2,angle,r,accumulator.item(r, angle)))
end=time.clock()
print(end - start)

cv.imshow("img_result", img_original)
cv.imshow("img_gray", img_gray)
cv.imshow("img_edge", img_edge)
cv.imshow("img_accumulator", img_accumulator)
cv.imwrite("img_accumulator.jpg", img_accumulator)


cv.waitKey(0)





OpenCV에서 제공하는 함수 사용 예제입니다.


cv.HoughLinesP



import cv2 as cv
import numpy as np

img = cv.imread('hallway.jpg')
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
edges = cv.Canny(gray,50,150)
lines = cv.HoughLinesP(edges,1,np.pi/180,100,minLineLength=100,maxLineGap=10)

for line in lines:
   x1,y1,x2,y2 = line[0]
   cv.line(img,(x1,y1),(x2,y2),(0,255,0),2)

cv.imshow("result", img)
cv.waitKey(0)



cv.HoughLines


import cv2 as cv
import numpy as np

img = cv.imread('hallway.jpg')
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
edges = cv.Canny(gray,50,150)
lines = cv.HoughLines(edges,1,np.pi/180,200)

for line in lines:
   rho,theta = line[0]
   a = np.cos(theta)
   b = np.sin(theta)
   x0 = a*rho
   y0 = b*rho
   x1 = int(x0 + 1000*(-b))
   y1 = int(y0 + 1000*(a))
   x2 = int(x0 - 1000*(-b))
   y2 = int(y0 - 1000*(a))
   cv.line(img,(x1,y1),(x2,y2),(0,0,255),2)

cv.imshow("result", img)
cv.waitKey(0)



반응형

문제 발생시 지나치지 마시고 댓글 남겨주시면 가능한 빨리 답장드립니다.

도움이 되셨다면 토스아이디로 후원해주세요.
https://toss.me/momo2024


제가 쓴 책도 한번 검토해보세요 ^^

+ Recent posts