✏️ 요즘은 딥러닝에 대해 공부를 하는 중입니다!
그중에서 최근 opencv(cv2)
를 이용하여 ,
이미지/영상에 필터를 입히고, 다양한 변환을 하는 방법에 대해 배웠는데 굉장히 재미있었습니다!ㅎㅎ
공간에서의 기하학적 변환에는 translation
, affine
, Euclidean
, similarity
, projective
등이 있으며, 이러한 다양한 변환을 opencv를 통해 구현할 수 있는데요.
이미지를 이동시키고, 확대/축소, 회전시키고, 대칭 변환을 하는등 다양한 변환이 가능합니다.
뿐만 아니라, 이를 응용하여 어파인 변환과 투시변환도 가능한데요.
문서를 스캔해주는 어플을 다들 써보신 적이 있을 것 같은데, 이렇게 왜곡된 형태를 직사각형 형태로 똑바로 펴주는 원리가 이러한 투시변환의 원리였다는 것을 깨달을 수 있었습니다.
이를 응용하여 친구와 카톡을 하다가 친구가 보낸 루피 이모티콘을 보고 루피의 찌그러진 얼굴을 펴줄 수 있을까? 하는 궁금증이 생겨 직접 시도해보았습니다!
(사실 오늘 글을 쓰게 된 이유ㅋㅋㅋ)
과연 결과는...! (두구두구두구)
하하하하😂😂😂
얼굴 형태는 그래도 예쁜 형태가 되었지만, 한번의 시술(?)로는 이목구비마저 예쁘게 원위치 시켜줄 수는 없었습니다...🥲
좀 더 레벨업을 하여 기술을 연마한 뒤에 다시 수술을 집도해보는 것으로 하겠습니다!
import sys import numpy as np import cv2 def drawROI(img, corners): cpy = img.copy() c1 = (192, 192, 255) c2 = (128, 128, 255) for pt in corners: cv2.circle(cpy, (int(pt[0]), int(pt[1])), 25, c1, -1, cv2.LINE_AA) cv2.line(cpy, (int(corners[0][0]), int(corners[0][1])), (int(corners[1][0]), int(corners[1][1])), c2, 2, cv2.LINE_AA) cv2.line(cpy, (int(corners[1][0]), int(corners[1][1])), (int(corners[2][0]), int(corners[2][1])), c2, 2, cv2.LINE_AA) cv2.line(cpy, (int(corners[2][0]), int(corners[2][1])), (int(corners[3][0]), int(corners[3][1])), c2, 2, cv2.LINE_AA) cv2.line(cpy, (int(corners[3][0]), int(corners[3][1])), (int(corners[0][0]), int(corners[0][1])), c2, 2, cv2.LINE_AA) disp = cv2.addWeighted(img, 0.3, cpy, 0.7, 0) return disp def onMouse(event, x, y, flags, param): global srcQuad, dragSrc, ptOld, src if event == cv2.EVENT_LBUTTONDOWN: for i in range(4): if cv2.norm(srcQuad[i] - (x, y)) < 25: dragSrc[i] = True ptOld = (x, y) break if event == cv2.EVENT_LBUTTONUP: for i in range(4): dragSrc[i] = False if event == cv2.EVENT_MOUSEMOVE: for i in range(4): if dragSrc[i]: dx = x - ptOld[0] dy = y - ptOld[1] srcQuad[i] += (dx, dy) cpy = drawROI(src, srcQuad) cv2.imshow('img', cpy) ptOld = (x, y) break src = cv2.imread('../data/루피2.png') if src is None: print('Image open failed!') sys.exit() h, w = src.shape[:2] dw = 300 dh = round(dw * 200 / 200) srcQuad = np.array([[30, 30], [30, h-30], [w-30, h-30], [w-30, 30]], np.float32) dstQuad = np.array([[0, 0], [0, dh-1], [dw-1, dh-1], [dw-1, 0]], np.float32) dragSrc = [False, False, False, False] disp = drawROI(src, srcQuad) cv2.imshow('img', disp) cv2.setMouseCallback('img', onMouse) while True: key = cv2.waitKey() if key == 13: # Enter break elif key == 27: # esc cv2.destroyWindow('img') sys.exit() pers = cv2.getPerspectiveTransform(srcQuad, dstQuad) dst = cv2.warpPerspective(src, pers, (dw, dh), flags=cv2.INTER_CUBIC) cv2.imshow('dst', dst) while True: if cv2.waitKey()==27: break cv2.destroyAllWindows()