모자이크 처리1
import cv2
rate = 15 # 모자이크에 사용할 축소비율(1/rate)
win_title = 'mosaic'
img = cv2.imread('./img/taekwonv1.jpg')
while True:
x,y,w,h = cv2.selectROI(win_title, img, False) # 관심영역 선택
if w and h:
roi = img[y:y+h, x:x+w] # 관심영역 지정
roi = cv2.resize(roi, (w//rate, h//rate)) # 1/rate 비율로 축소
roi = cv2.resize(roi, (w,h), interpolation=cv2.INTER_AREA)
img[y:y+h, x:x+w] = roi # 원본 이미지에 적용
cv2.imshow(win_title, img)
else:
break
cv2.destroyAllWindows()
Select a ROI and then press SPACE or ENTER button!
Cancel the selection process by pressing c button!
Select a ROI and then press SPACE or ENTER button!
Cancel the selection process by pressing c button!
포토샵 리퀴파이 도구
import cv2
import numpy as np
win_title = 'Liquify'
half = 50 # 관심영역 절판 크기
isDragging = False # 드래그 여부 플래그
# 리퀴파이 함수
def liquify(img, cx1, cy1, cx2,cy2):
# 대상 영역 좌표와 크기 설정
x, y, w, h = cx1-half, cy1-half, half*2, half*2
# 관심영역 설정
roi = img[y:y+h, x:x+w].copy()
out = roi.copy()
# 관심영역 기준으로 좌표 재설정
offset_cx1,offset_cy1 = cx1-x, cy1-y
offset_cx2,offset_cy2 = cx2-x, cy2-y
# 변환 이전 4개의 삼각형 좌표
tri1 = [[ [0,0], [w,0], [offset_cx1, offset_cy1]], # 상
[ [0,0], [0,h], [offset_cx1, offset_cy1]], # 좌
[ [w,0], [offset_cx1, offset_cy1], [w,h]], # 우
[ [0,h], [offset_cx1, offset_cy1], [w,h]] ] # 하
# 변환 이후 4개의 삼각형좌표
tri2 = [[ [0,0], [w,0], [offset_cx2, offset_cy2]], # 상
[ [0,0], [0,h], [offset_cx2, offset_cy2]], # 좌
[ [w,0], [offset_cx2, offset_cy1], [w,h]], # 우
[ [0,h], [offset_cx2, offset_cy1], [w,h]] ] # 하
for i in range(4):
# 각각의 삼각형 좌표에 대해 어핀 변환 적용
matrix = cv2.getAffineTransform( np.float32(tri1[i]), np.float32(tri2[i]))
warped = cv2.warpAffine( roi.copy(), matrix, (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(tri2[i]), (255,255,255))
# 마스킹 후 합성
warped = cv2.bitwise_and(warped, warped, mask=mask)
out = cv2.bitwise_and(out, out, mask=cv2.bitwise_not(mask))
out = out + warped
# 관심영역을 원본에 합성
img[y:y+h, x:x+w] = out
return img
# 마우스 이벤트 함수
def onMouse(event,x,y,flags,param):
global cx1, cy1, isDragging, img # 전역변수참조
# 마우스 중심점을 기준으로 따라다니기
if event == cv2.EVENT_MOUSEMOVE:
if not isDragging:
img_draw = img.copy()
# 드래그 영역 표시
cv2.rectangle(img_draw, (x-half, y-half), (x+half, y+half), (0,255,0))
cv2.imshow(win_title, img_draw) # 사각형으로 표시된 그림화면 출력
elif event == cv2.EVENT_LBUTTONDOWN:
isDragging = True # 드래그를 하면
cx1, cy1 = x, y # 드래그가 시작된 원래의 위치 좌표 저장
elif event == cv2.EVENT_LBUTTONUP:
if isDragging:
isDragging = False # 드래그 끝나면
liquify(img, cx1, cy1, x, y) # 드래그 시작점과 끝점으로 리퀴파이 적용함수 호출
cv2.imshow(win_title, img)
if __name__ == '__main__':
img = cv2.imread('./img/man_face.jpg')
h, w = img.shape[:2]
cv2.namedWindow(win_title)
cv2.setMouseCallback(win_title, onMouse)
cv2.imshow(win_title, img)
while True:
key = cv2.waitKey(1)
if key & 0xFF == 27:
break
cv2.destroyAllWindows
왜곡 거울 카메라
import cv2
import numpy as np
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 320)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 240)
rows, cols = 240, 320
map_y, map_x = np.indices((rows, cols), dtype=np.float32)
map_mirrorh_x,map_mirrorh_y = map_x.copy(), map_y.copy()
map_mirrorv_x,map_mirrorv_y = map_x.copy(), map_y.copy()
map_mirrorh_x[: , cols//2:] = cols - map_mirrorh_x[:, cols//2:]-1
map_mirrorv_y[rows//2:, :] = rows - map_mirrorv_x[rows//2:, :]-1
map_wave_x, map_wave_y = map_x.copy(), map_y.copy()
map_wave_x = map_wave_x + 15*np.sin(map_y/20)
map_wave_y = map_wave_y + 15*np.sin(map_x/20)
map_lenz_x = 2*map_x/(cols-1)-1
map_lenz_y = 2*map_y/(rows-1)-1
r, theta = cv2.cartToPolar(map_lenz_x, map_lenz_y)
r_convex = r.copy()
r_concave = r
r_convex[r<1] = r_convex[r<1]**2
print(r.shape, r_convex[r<1].shape)
r_concave[r<1] = r_concave[r<1] **0.5
map_convex_x, map_convex_y = cv2.polarToCart(r_convex, theta)
map_concave_x, map_concave_y = cv2.polarToCart(r_concave, theta)
map_convex_x = ((map_convex_x + 1)*cols-1)/2
map_convex_y = ((map_convex_y + 1)*rows-1)/2
map_concave_x = ((map_concave_x + 1)*cols-1)/2
map_concave_y = ((map_concave_y + 1)*rows-1)/2
while True:
ret, frame = cap.read()
mirrorh=cv2.remap(frame,map_mirrorh_x,map_mirrorh_y,cv2.INTER_LINEAR)
mirrorv=cv2.remap(frame,map_mirrorv_x,map_mirrorv_y,cv2.INTER_LINEAR)
wave = cv2.remap(frame, map_wave_x,map_wave_y,cv2.INTER_LINEAR,
None, cv2.BORDER_REPLICATE)
convex = cv2.remap(frame,map_convex_x,map_convex_y,cv2.INTER_LINEAR)
concave = cv2.remap(frame,map_concave_x,map_concave_y,cv2.INTER_LINEAR)
r1 = np.hstack((frame,mirrorh,mirrorv))
r2 = np.hstack((wave,convex,concave))
merged = np.vstack((r1, r2))
cv2.imshow('distorted', merged)
if cv2.waitKey(1) & 0xFF==27:
break
cap.release
cv2.desroyAllWindows()
(240, 320) (59868,)