dstQuad 배열에는 미리 정의한 A4용지 크기의 네 모서리 좌표를 저장 (A4 용지 크기: 210x297cm)
srcQuad 점들로부터 dstQuad 점들도 이동하는 투시 변환 계산
계산된 투시 변환 행렬을 이용하여 영상을 투시 변환하여 화면 출력
import sys
import numpy as np
import cv2
def drawROI(img,corners):
cpy=img.copy()
c1=(192,192,255) #1번컬러
c2=(128,128,255) #2번컬러
for pt in corners:
cv2.circle(cpy,tuple(pt),25,c1,-1,cv2.LINE_AA)
cv2.line(cpy,tuple(corners[0]),tuple(corners[1]),c2,2,cv2.LINE_AA)
cv2.line(cpy,tuple(corners[1]),tuple(corners[2]),c2,2,cv2.LINE_AA)
cv2.line(cpy,tuple(corners[2]),tuple(corners[3]),c2,2,cv2.LINE_AA)
cv2.line(cpy,tuple(corners[3]),tuple(corners[0]),c2,2,cv2.LINE_AA)
disp=cv2.addWeighted(img,0.7,cpy,0.3,0) #연산속도가 느림
return disp
#return cpy
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('name.jpg')
src=cv2.resize(src,(1080,720))
if src is None:
print('Image open failed')
sys.exit()
#입력영상 크기 및 출력영상 크기
h,w= src.shape[:2]
dw=500
dh=round(dw*297/210) #A4용지 크기: 210x297cm
#모서리 점들의 좌표, 드래그 상태 여부
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] #4개의 점중 어떤 점을 드래그 하고 있는지 상태정보
#모서리점, 사각형 그리기
disp=drawROI(src,srcQuad)
cv2.imshow('img',disp)
cv2.setMouseCallback('img',onMouse)
while True:
key=cv2.waitKey()
if key==13: #enter 키
cv2.destroyWindow('img')
break
elif key==27:
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)
cv2.waitKey()
cv2.destroyAllWindows()