[AIFFEL] 22.Jan.25 - Exploration, Portrait_Mode_Effect

Deok Jong Moon·2022년 1월 25일
0
post-thumbnail

미니프로젝트

핸드폰의 인물사진 모드 만들어보기

  • D.O.F 원리

    • DSLR은 DOF를 얕게 해서 아웃포커싱을 만드는데 핸드폰은 사실 렌즈 2개로 촬영해서 합성하는 거란다.
    • 핸드폰에서 일반렌즈가 배경 촬영, 망원 렌즈는 인물 촬영 후 배경을 흐리게 해서 합성
  • 오늘의 Image segmentation 간단 개요

    • 이것을 이용하여 하나의 렌즈를 이용한 하나의 사진에서 인물만 따로 배경에서 떼어낼 예정
    • 그리고 배경은 blur 처리
    • 그리고 다시 인물과 blurred 배경 합성
  • Image segmentation

    • 이미지 픽셀 값들에 라벨을 부여해서 특정 라벨 값을 가진 픽셀들만 따로 떼어내는 것
    • 이를 위해 라벨마다 공통적인 특징이 있다고 가정하고 부여함
    • 이 때 라벨은 물리적 거리와 상관 없을 수 있음
    • semantic segmentation
      • 우리가 인식하는 것처럼 물리적인 단위로 라벨을 지정하는 것
    • Instance segmentation
      • 클래스별로 라벨을 지정하는 것에서 한 발짝 더 나아가
      • instance 별로, 즉 같은 클래스 내에서도 다른 인스턴스들은 다른 라벨을 부여받게 해서 구분 가능하게 하는 것
  • watershed segmentation

  • 오늘은 Deeplabv3+ 프레임워크가 이용된 Pixellib의 semantic segmentation 기법을 사용한다.

  • atrous convolution layer

    • Deeplabv3+에서 효과적이라고 하는 layer이다.
    • 뜻은 구멍난 convolution이라고 보면 될 듯하다.
    • 일반적인 convolution보다 디테일한 특징을 얻는 데 효과적이다...?
    • 왜냐하면 spatial dimension of feature map은 유지되는데 receptive field가 더 커져서
    • 다시 얘기하면 Atrous convolution을 활용하면 파라미터 수를 늘리지 않으면서도 receptive field를 크게 키울 수 있다.
    • https://better-tomorrow.tistory.com/entry/Atrous-Convolution
  • 새로운 패키지

    • urllib : 웹에서 데이터 다운로드 받을 때
    • pixellib : semantic segmentation을 편하게 할 수 있게 도와줌

오늘의 진행 순서

  • cv2.imread(path) -> numpy 어레이 반환

    • 확인할 때 plt.imshow()
    • 이 때 cv2.cvtColor(넘파이 어레이, cv2.COLOR_BGR2RGB)) 사용해서 RGB 순으로 본다(OpenCV는 기본적으로 BGR...)
  • segmentation 모델 다운로드

    • urllib.request.urlretrieve(model_url, model_path)하면 url에서 명시된 path로 다운받기 함
  • segmentation 모델 생성
    - model = semantic_segmentation() model.load_pascalvoc_model(model_file)
    - 이 때 pascal voc 데이터로 학습시킨 모델 가져 옴

  • segvalues, output = model.segmentAsPascalvoc(img_path)

    • 위의 코드로 segmentation 돌리면
    • 어떤 물체가 담겼는지와 boolean 마스킹 어레이가 dict에 담겨서 반환되고(segvalues)
    • 마스킹 처리된 어레이(output)가 추가로 반환된다.
  • segmentation된 물체들과, 해당 물체들의 진짜 라벨, 그리고 색상 확인하기

    • colormap은 Pixellib에서 코드를 제공해준다.
    • 근데 이때 색상 값은 BGR 순이라서 해석하려면 RGB로 바꿔야 한다.
    • 예 : colormap[15] >>> array([192, 128, 128])이면
    • seg_color = (128,128,192)로 따로 변수 할당
  • 마스킹 이미지 만들기

    • 이 때 색상(seg_color)을 사용해서 해당 색상으로 된 부분을 마스킹된 이미지(혹은 어레이라고 볼 수 있음)에서 추려낸다.

    • 방법은 (세로, 가로, 채널) shape을 가지던 어레이에

    • 채널 부분에 seg_color를 np.all(output==seg_color, axis=-1)함으로써 어레이를 0과 1이 담긴 (세로, 가로) 2dim 어레이로 만들어 버린다.(이미지로 보면 흰색, 검정색만 나옴)

  • 해당 흰색, 검정색 어레이와 원본 이미지를 잘 섞어서 segmentation이 잘됐는지 확인

  • 이후 원본 이미지는 blur() 함수로 전체 blur 처리

  • 이제 sementation mask와 blur 처리된 사진에 bitwise로 배경만 뽑아내기

    • 이 때 배경을 공통으로 쓰면 됨. 방법으로는
    • sementation mask에서 앞으로 제외할 사람은 검정(0), 배경은 흰(1)로 바꿔주기(cv2.bitwise_not() 사용)
    • 그리고 cv2.bitwise_and()로 공통 부분만 골라내고 사람은 검정색 처리
  • 그리고 np.where()함수를 통해 합성

    • 조건은 마스킹이미지 == 255일 때(배경으로 가정)
    • 참이면 블러 이미지
    • 거짓이면 오리지널 이미지
profile
'어떻게든 자야겠어'라는 저 아이를 닮고 싶습니다

0개의 댓글