모자이크 처리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!

opencv

포토샵 리퀴파이 도구

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

opencv

왜곡 거울 카메라

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,)