어떤 이미지에서 100 이상을 노이즈로 정의하고 이미지의 주요 특징값인 60~80의 값으로 채워 넣을땐 어떻게 해야할까?

< 일반 파이썬의 zip *을 이용한 방법 > 

# 각 이미지가 가지는 일반적인 범위
img_range = np.arange(60, 80 + 1) 

# !00 이상인 인덱스를 얻어오고
white_index = np.where(img > 100)

# 각 인덱스에 랜덤하게 (60~80) 숫자를 넣어줌.
for i, j, k in zip(*white_index):
    img[i][j][k] = np.random.choice(img_range, 1)

 

위와 같은 코드로 할 수 있다. 

하지만 2번째 코드와 3번째 코드를 보면 함수의 내부 코드까지 더해져 이중 for-loop가 남발하게 되어 속도가 매우매우 느려지게 된다.

따라서 위와같은 방법은 좋지 않은 방법이며 masking방법을 이용하여 코드 라인을 줄임과 동시에 for문의 중첩을 줄여주어야 한다.

 

< Masking 방법 > 

import numpy as np

img = np.arange(27).reshape(3, 3, 3)
index = np.arange(60, 80 + 1)
mask = np.random.choice(index, 3 * 3 * 3).reshape(3, 3, 3) 
a = np.where(a > 20, mask, img)

 

(램이 충분하다면) 이와 같이 mask를 미리 만들어두어 np.where을 사용하여 img + noise이미지를 다시 생성해주는 코드입니다.

또한, 위 코드에서는 이미지가 rgb채널일 경우를 가정하고 하였는데, mask의 크기를 3*3으로 해주어도 파이썬의 특징인 브로드캐스팅이 작동하여 정상적으로 마스킹작업이 가능해지게 됩니다. 

위와 같이 하게 된 이유는 개인적인 결정이지만, 3*3*3으로 하면 좀더 많은 난수를 생성하게 되어 노이즈 대체값(60~80)에 대해 훨씬 넓은 선택폭을 가지게 되어

좀더 좋은 결과를 가지게 되지 않을까 생각하여 그렇게 하였습니다.

(실제로 3*3을 하면 그 행렬로 rgb를 전부 채우게 되어 랜덤하게 특징값을 채우는것에 대한 의미를 퇴색시킬 수 있겠다는 생각?)

 

< 그 외 > 

그 외의 방법은 알아보진 실험해보진 못했지만

1. openCV를 활용하여 이미지를 바이너리화 한 다음 masking방법을 진행

2. cifi나 cython을 이용 ( 결국 c언어가 제일 빨라요 )

3. 2번의 방법과 함께 CUDA를 이용하여 nvidia gpu 분기 작업 이용하기