컴퓨터로 영상을 판독하기 위해서는 영상 안에 들어 있는 물체들의 속성을 수치화 할 필요가 있다. 물체의 속성을 수치화해야만 쉽게 물체를 인식 할 수 있기 때문이다. 이를 영상 분석(image analysis)이라고 한다. 이런 물체들의 속성으로는 물체의 크기, 물체 외곽선, 직선, 원, 코너 등이 있을 것이다. 영상 분석의 결과는 특정한 수치나 레이블이 된다. 우리가 영상 안에 들어 있는 물체를 인지하려면 영상을 각각의 물체로 나누는 단계(영상 분할), 각 물체를 측정하는 단계(특징 추출), 측정값에 따라 물체를 분류하는 단계(물체 분류) 등이 필요하다.
입력 영상에는 물체를 분류하는데 필요하지 않은 많은 정보가 들어 있다. 따라서 영상 인식의 철번째 단계는 영상에 포함된 중요한 정보만을 남기고 나머지 부분을 생략하여 영상을 단순화하는 것이다. 중요하지 않은 정보를 버리고 에지와 같은 필숮겅니 정보를 추출하는 것을 특징 추출(feature extraction)이라고 한다.
코너는 영상에서 비교적 쉽게 찾을 수 있으면서 개수도 많지 않다. 따라서 코너는 좋은 특징으로 간주될 수 있다.
딥러닝에서는 영상에서 특징을 추출하지 않고 입력 영상의 화소를 분류기의 입력으로 직접 사용하기도 한다.
영상에서 직선을 검출하려면 에지 검출기를 사용할 수 있다. 하지만 일반적으로 에지 데이터의 불완전성으로 인해 완벽한 직선을 얻기는 상당히 힘들다. 이때 사용할 수 있는 기법이 허프변환(Hough transform)이다. 허프 변환은 영상 분석이나 컴퓨터 비전에서 아주 많이 사용되는 특징 추출 기법이다. 이 기법의 목적은 도형의 매개변수 공간에서 투표 절차를 통해 영상 내의 도형을 찾는 것이다. 고전적인 허프 변환은 영상에서 직선만을 찾을 수 있었지만 나중에 원이나 타원, 일반적인 도형을 식별하는 데까지 확장되었다.
src = cv2.imread("../DATA/sudoku.jpg", 0)
dst = cv2.Canny(src, 100, 200)
cdst = cv2.cvtColor(dst, cv2.COLOR_GRAY2BGR)
lines = cv2.HoughLinesP(dst, 1, np.pi/180, 50, 100, 3)
for i in range(len(lines)):
for x1,y1,x2,y2 in lines[i]:
cv2.line(cdst,(x1,y1),(x2,y2),(0,0,255),3)
cv2.imshow("source",src)
cv2.imshow("edge", dst)
cv2.imshow("detected lines", cdst)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.waitKey(1)
허프 변환의 개념을 응용하여 영상에서 원을 검출할 수 있다.
img = cv2.imread("../DATA/separate_coins.jpg", 1)
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img_gray = cv2.GaussianBlur(img_gray, (9,9), 2, 2)
circles = cv2.HoughCircles(img_gray, cv2.HOUGH_GRADIENT, 1, minDist=img_gray.shape[0]//8, param1=200, param2=50, minRadius=0, maxRadius=0)
for i in range(len(circles[0])):
center = (int(np.round(circles[0][i][0])), int(np.round(circles[0][i][1])))
radius = int(np.round(circles[0][i][2]))
cv2.circle(img, center, 3, (0,255,0), -1, 8, 0)
cv2.circle(img, center, radius, (0,0,255), 3, 8, 0)
cv2.imshow("Hough Circle Transform", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.waitKey(1)
3차원 영상 재구성, 영상 매칭, 객체 인식 등의 작업에서 우리는 특징점들을 필요로 한다. 우리가 매칭점을 말할 때 일반적인 의미에서 우리가 쉽게 인식할 수 있는 특성을 말한다. 특징들은 고유하게 인식할 수 있어야한다. 우리가 자주 사용하는 특징에는 에지(edges), 코너(corners), 블로브(Blobs)가 있다.
많이 사용되는 특징점 중의 하나가 바로 코너이다. 코너는 두 에지의 교차점이다 코너에서는 에지의 방향이 바뀌게 된다. 따라서 ㅇ영상의 기울기가 심하게 변하는 지점을 찾으면 코너일 것이다.
src = cv2.imread("../DATA/chessboard_mat.jpg")
src_gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
dst = cv2.cornerHarris(src_gray, 2, 3, 0.04)
dst_norm = cv2.normalize(dst,None, 0, 255, cv2.NORM_MINMAX)
dst_norm_scaled = cv2.convertScaleAbs(dst_norm)
thresh = 150
for j in range(dst_norm.shape[0]):
for i in range(dst_norm.shape[1]):
if(dst_norm[j][i]>thresh):
cv2.circle(src, (i,j), 5, (0,0,255), 2, 8, 0)
cv2.imshow("corner window", src)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.waitKey(1)
img = cv2.imread("../DATA/cartoon_receipt.jpg")
img = cv2.resize(img, (400, 300))
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
corners = cv2.goodFeaturesToTrack(img_gray, 30, 0.01, 10)
corners = np.int0(corners)
for i in corners:
x, y = i[0].ravel()
cv2.circle(img, (x, y), 4, (0,0,255), -1, 20, 0)
cv2.imshow("corner window", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.waitKey(1)