반응형
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)
반응형
공유하기
게시글 관리
구독하기멈춤보단 천천히라도저작자표시 비영리 동일조건