컴퓨터비전 중 Segmentation태스크와 관련한 프로젝트를 진행하다 마주친 문제 중 하나를 작성해보려고 한다.
미리 말하자면 세그멘테이션 모델의 인퍼런스 결과인 마스크 사진과 원본을 합성하는 내용을 다룬다.
케글이나 데이콘같은 Competition이야 이미지 분류의 경우 f1 score, 세그멘테이션 같은 경우 mIoU같은 metric을 평가지표로 모델의 성능을 평가하는데 초점을 두지만 실제로 AI를 활용한 서비스에서는 모델 인퍼런스의 결과를 활용하는 것도 중요하다.
이미지분류같은 경우 다른 테스크에 비해 간단해 초보자도 조금만 찾아보면 쉽게 실제 서비스에 적용할 수 있으나 Object Detection, Segmentation같은 경우 초보자가 인퍼런스 결과를 활용하기가 쉽지 않다.
글쓴이의 경우 차량외관 사진에 대하여 파손을 탐지하는 프로젝트를 진행하였다.
아래와 같은 차량 사진에 대하여 세그멘테이션 모델로 인퍼런스를 하고 마스크 사진을 얻었다.
결과로는 아래와 같은 형태의 이미지를 얻을 수 있고, plt와 같이 시각화를 도와주는 라이브러리를 사용해 표시하면 인퍼런스된 결과에 해당하는 부분은 노란색으로 나머지는 보라색으로 보이는 것을 볼 수 있다.
해당이미지는 pseudo color로 실제색상이 아닌 시각화를 용도로 나타내어지는 색상이다
힘들게 AI모델도 만들고 어찌저찌 인퍼런스까지는 했는데 이제 이걸 사용하려다 난관에 부딫쳤다.
첫 번째로, 먼저 시도한 것은 cv2라이브러리를 통한 합성이다.
원본 사진과는 채널이 달라서 합칠 수 없다.
다음은 plt라이브러리로 똑같은 칸에 원본사진과 인퍼런스된 사진을 띄우고 투명도 조절을 통해 사진을 합쳐보았다.
fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(16, 10))
ax[0].imshow(org_img)
ax[0].axis('off')
ax[1].imshow(org_img.astype('uint8'), alpha=0.9)
ax[1].imshow(img_output, alpha=0.5)
위와 같은 코드로 사진을 표시하면 아래와 같은 결과가 나온다, 왼쪽은 원본사진 오른쪽은 원본과 인퍼런스된 이미지를 합친 후 투명도 조절을 통해 어느 정도 결과를 얻은 사진이다.
다음은 cm.Reds와 같이 다른 컬러맵으로 색깔을 변경하고 마찬가지로 진행하면 위처럼 이상한 보라색 대신 봐줄만은 하다
그러나 원본사진과 비교했을 때 내가 원치않는 부분까지 투명도가 조절이 된다는 것과 두장을 넘어서 까지는 합성이 불가능하다는 한계점이 있다.
(하려면 할 수는 있지만 계속해서 투명도가 높아지는 방법을 사용해야해서 좋은 결과를 얻기는 힘들다)
나 같은 경우 차량의 스크래치, 파손, 찌그러짐 총 3가지의 종류 모델 인퍼런스결과를 원본에 합성하여 나타내고 싶었고 여러가지를 시도해본 결과 다음과 같은 방법을 사용하여 원본사진을 인퍼런스된 사진과 합성하였다.
즉, 인퍼런스된 결과물 3장이 각자 다른 색상이길 원했고 이를 원본사진과 합성하는 것이 목표였다
1. 모델로 인퍼런스한 결과를 먼저 컬러채널로 변경해준다.
output = np.array(input, dtype=np.uint8)
output = cv2.cvtColor(output, cv2.COLOR_GRAY2BGR)
2. 다음은 색상을 변경해준다, 난 원하는 색상으로 변경을 위해서 직접 RGB값을 찾고 이에 맞춰 마스킹 된 부분(1로 존재하는 부분)을 해당 RGB컬러로 변경하였다.
def convert_to_pink(arr):
pink = [240, 15, 135]
for i in range(512):
for j in range(512):
if(arr[i][j][0] == 1):
arr[i][j] = pink
return arr
def convert_to_blue(arr):
blue = [75, 150, 200]
for i in range(512):
for j in range(512):
if(arr[i][j][0] == 1):
arr[i][j] = blue
return arr
def convert_to_black(arr):
black = [64, 64, 64]
for i in range(512):
for j in range(512):
if(arr[i][j][0] == 1):
arr[i][j] = black
return arr
위에서 흑백 -> 컬러채널로 변경한 이미지를 conver_to_색상같은 함수에 넣어 변환을 하면 아래와 같은 결과가 나온다
이렇게 변환된 사진은 아래와 같이 cv2의 add라이브러리를 사용해 합성이 가능하다
cv2.add(원본사진, 변환된사진)
이와같은 방법을 이용하면 아래처럼 인퍼런스 된 결과물을 자유자재로 원본사진과 합성할 수 있다.
프로젝트에서는 세가지 모델의 인퍼런스 결과물을 각각 핑크색, 파란색, 검은색으로 변경한 뒤 cv2.add를 사용하여 합치는 방법을 이용하였고 아래와 같은 결과를 얻을 수 있었다.
관련된 코드의 전체본은 아래 레포지토리의 inference.py와 Utils에 존재한다.
'⌨Programming > Python' 카테고리의 다른 글
파이썬 환경변수 설정으로 보안관리하기 (0) | 2023.04.01 |
---|---|
파이썬 global & nonlocal 키워드 (0) | 2022.10.02 |
파이썬으로 S3 bucket의 다양한 정보를 가져와보자(오브젝트 url, 생성시간 etc...) (0) | 2022.06.19 |
[python, 파이썬] sum 함수를 이용한 차원축소 및 병합 (0) | 2022.05.29 |
파이썬 JSON파일 다루기(읽기, 쓰기, 수정) (0) | 2022.04.20 |