OpenCV만으로 자연스럽게 화상 처리(마스크 처리) 해 본다.
블로그의 목적
사진의 편집에 관해서는, GAN의 발전에 의해 꽤 자연스러운 느낌으로 할 수 있도록 되어 왔습니다. 하지만, 서둘러서 뭔가 제대로 하고 싶을 때 OpenCV에서 간단한 편집을 할 수 있으면 편리하죠? ? 그래서 이번에는 간단한 마스크 처리를 보다 자연스럽게 할 수 있도록 해 보았습니다.
내용
원본 이미지와 마스크 이미지 생성
import numpy as np
import matplotlib.pyplot as plt
import cv2
def show(img):
plt.grid(False)
plt.yticks([])
plt.xticks([])
plt.imshow(img)
img = cv2.imread('sample.jpg')
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
show(img)
mask = np.zeros_like(img)
cv2.circle(mask, (img.shape[1]//2, img.shape[0]//2), 150, (255, 255, 255), thickness=-1)
show(mask)
이번은 이 벌의 화상에 대해서 마스크 부분을 감마 보정으로 밝게 가공한다고 하는 처리를 실시합니다.
방법 1(그대로 합성)
def gamma_correction(img, gamma=0.6):
table = (np.arange(256) / 255) ** gamma * 255
table = np.clip(table, 0, 255).astype(np.uint8)
return cv2.LUT(img, table)
def create1(img, mask):
gamma_img = gamma_correction(img)
img = np.where(mask==0, img, gamma_img)
return img
show(create1(img, mask))
하는 일은 코드의 만마입니다. 마스크 밖의 픽셀이면 원래의 어두운 이미지, 마스크 내이면 감마 보정으로 밝게 한 이미지라는 규칙으로 간단하게 합성하고 있습니다. 보시다시피, 확실히 밝아지고 있지만 경계선이 분명하게 보이고 부자연스럽습니다.
방법 2(조금 궁리)
def create2(img, mask):
mask_size = mask.shape
mask = cv2.resize(mask, (mask_size[1]//20, mask_size[0]//20))
mask = cv2.GaussianBlur(mask, (9, 9), 0)
mask = cv2.resize(mask, (mask_size[1], mask_size[0]))
gamma_img = gamma_correction(img)
paste_img = gamma_img * (mask/255)
img = np.where(paste_img>img, paste_img, img).astype(np.uint8)
return img
show(create2(img, mask))
좋은 느낌으로 경계선이 사라졌습니다. 하는 일입니다만, 우선 전반에서 마스크에 평활화 필터 처리를 합니다. 이때 오리지널 사이즈의대로라면 Gaussian Filter의 처리 시간이 걸려 버리기 때문에, 한번 리사이즈로 가볍게 하고 나서 필터 처리를 실시해, 다시 리사이즈로 원래의 크기로 되돌리고 있습니다.
후반부에서는 필터 처리한 화상과 감마 보정으로 밝게 한 화상을 곱하여 다음과 같은 화상을 생성하고 있습니다.
그리고는 원래의 오리지날과 상기의 화상을 비교해, 보다 밝은 화소를 np.where
로 선택해 가면, 자연스러운 마스크 처리가 된다고 하는 것입니다.
덤
아래와 같이 처리하는 것으로 사악한 벌이 되었습니다.
def create3(img, mask):
mask_size = mask.shape
mask = cv2.resize(mask, (mask_size[1]//20, mask_size[0]//20))
mask = cv2.GaussianBlur(mask, (9, 9), 0)
mask = cv2.resize(mask, (mask_size[1], mask_size[0]))
gamma_img = gamma_correction(img)
paste_img = gamma_img * (mask/255)
img = np.where(paste_img==0, img, paste_img).astype(np.uint8)
return img
show(create3(img, mask))
미안해.
Reference
이 문제에 관하여(OpenCV만으로 자연스럽게 화상 처리(마스크 처리) 해 본다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/Takayoshi_Makabe/items/1fbbeeb41cc4d6a5f1e2
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
원본 이미지와 마스크 이미지 생성
import numpy as np
import matplotlib.pyplot as plt
import cv2
def show(img):
plt.grid(False)
plt.yticks([])
plt.xticks([])
plt.imshow(img)
img = cv2.imread('sample.jpg')
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
show(img)
mask = np.zeros_like(img)
cv2.circle(mask, (img.shape[1]//2, img.shape[0]//2), 150, (255, 255, 255), thickness=-1)
show(mask)
이번은 이 벌의 화상에 대해서 마스크 부분을 감마 보정으로 밝게 가공한다고 하는 처리를 실시합니다.
방법 1(그대로 합성)
def gamma_correction(img, gamma=0.6):
table = (np.arange(256) / 255) ** gamma * 255
table = np.clip(table, 0, 255).astype(np.uint8)
return cv2.LUT(img, table)
def create1(img, mask):
gamma_img = gamma_correction(img)
img = np.where(mask==0, img, gamma_img)
return img
show(create1(img, mask))
하는 일은 코드의 만마입니다. 마스크 밖의 픽셀이면 원래의 어두운 이미지, 마스크 내이면 감마 보정으로 밝게 한 이미지라는 규칙으로 간단하게 합성하고 있습니다. 보시다시피, 확실히 밝아지고 있지만 경계선이 분명하게 보이고 부자연스럽습니다.
방법 2(조금 궁리)
def create2(img, mask):
mask_size = mask.shape
mask = cv2.resize(mask, (mask_size[1]//20, mask_size[0]//20))
mask = cv2.GaussianBlur(mask, (9, 9), 0)
mask = cv2.resize(mask, (mask_size[1], mask_size[0]))
gamma_img = gamma_correction(img)
paste_img = gamma_img * (mask/255)
img = np.where(paste_img>img, paste_img, img).astype(np.uint8)
return img
show(create2(img, mask))
좋은 느낌으로 경계선이 사라졌습니다. 하는 일입니다만, 우선 전반에서 마스크에 평활화 필터 처리를 합니다. 이때 오리지널 사이즈의대로라면 Gaussian Filter의 처리 시간이 걸려 버리기 때문에, 한번 리사이즈로 가볍게 하고 나서 필터 처리를 실시해, 다시 리사이즈로 원래의 크기로 되돌리고 있습니다.
후반부에서는 필터 처리한 화상과 감마 보정으로 밝게 한 화상을 곱하여 다음과 같은 화상을 생성하고 있습니다.
그리고는 원래의 오리지날과 상기의 화상을 비교해, 보다 밝은 화소를
np.where
로 선택해 가면, 자연스러운 마스크 처리가 된다고 하는 것입니다.덤
아래와 같이 처리하는 것으로 사악한 벌이 되었습니다.
def create3(img, mask):
mask_size = mask.shape
mask = cv2.resize(mask, (mask_size[1]//20, mask_size[0]//20))
mask = cv2.GaussianBlur(mask, (9, 9), 0)
mask = cv2.resize(mask, (mask_size[1], mask_size[0]))
gamma_img = gamma_correction(img)
paste_img = gamma_img * (mask/255)
img = np.where(paste_img==0, img, paste_img).astype(np.uint8)
return img
show(create3(img, mask))
미안해.
Reference
이 문제에 관하여(OpenCV만으로 자연스럽게 화상 처리(마스크 처리) 해 본다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/Takayoshi_Makabe/items/1fbbeeb41cc4d6a5f1e2텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)