Python/파이썬 OpenCV 공부

[파이썬 OpenCV] 영상에 카툰 필터 적용하기 - cv2.bilateralFilter, cv2.Canny, cv2.bitwise_and

AI 꿈나무 2020. 10. 4. 16:34
반응형

황선규 박사님의 <OpenCV 4로 배우는 컴퓨터 비전과 머신 러닝>, 패스트 캠퍼스 OpenCV 강의를 공부한 내용을 정리해 보았습니다.

 


영상에 카툰 필터 적용하기

 cv2.bilateralFilter, cv2.Canny, cv2.bitwise_and 함수를 이용해서 영상에 카툰 필터를 구현하도록 하겠습니다.

 

1. 카툰 필터 카메라 - cv2.bilateralFiter, cv2.Canny, cv2.bitwise_and()

 카툰 필터는 입력 영상의 색상을 단순화시키고, 에지 부분을 검정색으로 강조하는 방법으로 구현할 수 있습니다.

 

카툰 필터 카메라 구현 단계

(1) 영상을 단순화 합니다. 

 단순화는 양방향 필터 함수인 cv2.bilateralFilter()로 적용할 수 있습니다.

 

(2) 윤곽선 영상을 만듭니다.

 윤곽선 영상은 cv2.Canny()로 구현할 수 있습니다.

 

(3) 단순화된 영상과 윤곽선 영상을 and연산으로 출력하면 카툰 필터 카메라가 완성됩니다.

 and 연산은 cv2.bitwise_and() 함수를 이용합니다.

 

구현 코드

def cartoon_filter(img):
    h, w = img.shape[:2] # 영상의 높이와 넓이 속성 가져오기
    img2 = cv2.resize(img, (w//2, h//2)) # 영상의 크기 축소

 

  영상의 크기를 축소하는 이유는 영상을 축소한 뒤에 양방향 필터를 적용하면 더 좋은 퀄리티의 단순화 효과를 얻을 수 있습니다. 축소된 영상을 출력할 때 확대해서 출력해야 한다는 것을 주의해야 합니다.

 

    blr = cv2.bilateralFilter(img2, -1, 20, 7)
    edge = 255 - cv2.Canny(img2, 80, 12)
    edge = cv2.cvyColor(edge, cv2.COLOR_GRAY2BGR)

 

 cv2.bilaterFilter에서 필터크기는 -1(자동 설정), 시그마 컬러 20, 시그마 7을 주었습니다. 과장된 효과를 위해 높은 시그마를 적용했습니다.

 cv2.Canny는 컬러 영상을 입력으로 넣어도 흑백 영상으로 출력됩니다. 또한 255에서 -를 해주어 흰색과 검정색의 반전 효과를 주었습니다.

 마지막에 흑백 영상을 컬러 영상으로 변환해 주었는데 필요 없는 작업입니다. 단순히 영상에 통일성을 주기 위해 적용했습니다.

 

    dst = cv2.bitwise_and(blr, edge)
    dst = cv2.resize(dst, (w, h), interpolation=cv2.INTER_NEAREST)
    
    return dst

 

 cv2.bitwise_and 함수로 blr 영상과 edge 영상을 and 연산 처리해주었습니다.

 여기서 and 연산의 의미는 Canny영상에서 검은색 부분(윤곽선)은 blr영상에 적용하여 윤곽선을 강하게 주고, Canny영상에서 흰색 부분은 그대로 blr 영상을 가져옵니다.

 

 또한 확대를 할때 interpolation을 지정해주었습니다.

 기본값을 이용하면 자연스러운 영상이 적용되는데 interpolation을 지정한 이유는 카툰 필터에서는 극적인 효과가 필요하므로 지정해주었습니다.

 

카툰 필터 영상 출력 코드

def cartoon_filter(img):
    h, w = img.shape[:2]
    img2 = cv2.resize(img, (w//2, h//2))

    blr = cv2.bilateralFilter(img2, -1, 20, 7)
    edge = 255 - cv2.Canny(img2, 80, 120)
    edge = cv2.cvtColor(edge, cv2.COLOR_GRAY2BGR)
    dst = cv2.bitwise_and(blr, edge) # and연산
    dst = cv2.resize(dst, (w, h), interpolation=cv2.INTER_NEAREST)
                                                                  
    return dst

cap = cv2.VideoCapture(0) # 카메라 오픈.

if not cap.isOpened():
    print('video open failed!')
    sys.exit()
    
while True:                 # 무한 루프
    ret, frame = cap.read() # 웹 카메라의 프레임값 불러오기
    
    if not ret:
        break
    
    frame = cartoon_filter(frame) # 프레임에 카툰 필터 적용
    
    cv2.imshow('frame',frame)
    key = cv2.waitKey(1) # 다음 프레임을 위해서 빠르게 1ms 간격으로 전환
    
    if key == 27: # esc 누르면 종료
        break

cap.release()
cv2.destroyAllWindows()
    

 

카툰 필터 적용 영상

 코드를 실행하면 노트북 카메라의 출력 영상에 카툰 필터가 적용되서 출력됩니다.

 

 신상 보호를 위해 마스크를 착용했습니다. 감사합니다.

 

반응형