-
opencv 포토샵 도구 만들기영상처리(Opencv) 2022. 4. 16. 23:34
import cv2
import numpy as np
title = 'photo'
half = 50 # 관심 영역 절반 크기
isDragging = False # 드래그 여부 플래그
def liquify(img, x1, y1, x2, y2):
x, y, w, h = x1 - half, y1 - half, half * 2, half * 2 # 대상 영역 좌표와 크기 설정
roi = img[y:y + h, x:x + w].copy() # 관심 영역 설정
result = roi.copy() #관심영역 복사
offset_x1, offset_y1 = x1 - x, y1 - y # 관심영역 기준으로 좌표 재설정
offset_x2, offset_y2 = x2 - x, y2 - y # 관심영역 기준으로 좌표 재설정
# 변환 이전4개의 삼각형 좌표
t1 = [[(0, 0), (w, 0), (offset_x1, offset_y1)], # 상 삼각형 좌표 설정
[[0, 0], [0, h], [offset_x1, offset_y1]], # 좌 삼각형 좌표 설정
[[w, 0], [offset_x1, offset_y1], [w, h]], # 우 삼각형 좌표 설정
[[0, h], [offset_x1, offset_y1], [w, h]]] # 하 삼각형 좌표 설정
# 변환 이후4개의 삼각형 좌표
t2 = [[[0, 0], [w, 0], [offset_x2, offset_y2]], # 상 삼각형 좌표 설정
[[0, 0], [0, h], [offset_x2, offset_y2]], # 좌 삼각형 좌표 설정
[[w, 0], [offset_x2, offset_y2], [w, h]], # 우 삼각형 좌표 설정
[[0, h], [offset_x2, offset_y2], [w, h]]] # 하 삼각형 좌표 설정
for i in range(4):
# 각각의 삼각형 좌표에 대해 어핀 변환 적용
trans= cv2.getAffineTransform(np.float32(t1[i]), np.float32(t2[i]))
warp = cv2.warpAffine(roi.copy(),trans, (w, h), None, flags=cv2.INTER_LINEAR, borderMode=cv2.BORDER_REFLECT_101)
mask = np.zeros((h, w), dtype=np.uint8) # 삼각형 모양의 마스크 생성
cv2.fillConvexPoly(mask, np.int32(t2[i]), (255, 255, 255))
warp = cv2.bitwise_and(warp, warp, mask=mask)
result = cv2.bitwise_and(result, result, mask=cv2.bitwise_not(mask))
result = result + warp # 마스킹 후 합성
img[y:y + h, x:x + w] = result #합성 영상을 원본에 복사
return img
def onMouse(event, x, y, flags, param):
global x1, y1, isDragging, img
if event == cv2.EVENT_MOUSEMOVE: #마우스 움직일 떄
if not isDragging: # 드래그 하지 않을 때
img_draw = img.copy()
#4개의 삼각형 그리기: roi
tri1 = np.float32([[x-half,y+half], [x,y], [x+half,y+half]])
cv2.polylines(img_draw,[tri1.astype(np.int32)],True,(0,255,0),1)
tri2 = np.float32([[x,y], [x+half,y-half], [x + half, y + half]])
cv2.polylines(img_draw, [tri2.astype(np.int32)], True, (0, 255, 0), 1)
tri3 = np.float32([[x-half, y-half], [x,y], [x-half,y+half]])
cv2.polylines(img_draw, [tri3.astype(np.int32)], True, (0, 255, 0), 1)
tri4 = np.float32([[x-half,y-half], [x,y], [x + half, y - half]])
cv2.polylines(img_draw, [tri4.astype(np.int32)], True, (0, 255, 0), 1)
cv2.imshow(title, img_draw)
elif event == cv2.EVENT_LBUTTONDOWN: #왼쪽 마우스 눌렀을 때
isDragging = True # 드래그 시작
x1, y1 = x, y # 드래그 시작된 원래의 위치 좌표 저장
elif event == cv2.EVENT_LBUTTONUP: #왼쪽 마우스 떼기
if isDragging:
isDragging = False # 드래그 끝
liquify(img, x1, y1, x, y) # 드래그 시작 좌표,끝난 좌표로 리퀴파이함수 호출
cv2.imshow(title, img)
if __name__ == '__main__':
img = cv2.imread("face.jpeg")
h, w = img.shape[:2]
cv2.namedWindow(title)
cv2.setMouseCallback(title, onMouse)
cv2.imshow(title, img)
while True:
key = cv2.waitKey(1)
if key & 0xFF == 27:
break
cv2.destroyAllWindows()원본결과
'영상처리(Opencv)' 카테고리의 다른 글
손가락 개수를 이용한 가위바위보 놀이 (0) 2022.04.16