[Python] 이미지 블렌딩, 이미지 비트 연산
1. 이미지 블렌딩이란?
이미지 블렌딩은 이미지를 서로 합칠때 가중치를 두어 합치는 방법.
두 이미지가 있고 1번에서 2번 이미지로 전환하는 경우 서서히 변환하는 기능을 이용할때 좋은 기법
이미지 블랜딩 기법을 구현하기 위한 수식
g(x) = (1-a)f_0(x) + af_1(x)
a의 값이 0에서 1로 변해가면서 f_0(x)의 효과는 점점 작아지고, f_1(x)의 효과는 점점 커지게 됨.
이 수식은 addWeighted(이미지파일, 수식) 함수를 사용하면 된다.
아래의 예제에서는 위에 수식과 트랙바를 이용해서 구현해보았다.
<코드>
img1 = cv2.imread('./image/anemone-5281964_1280.jpg')
img2 = cv2.imread('./image/dove-2516641_1280.jpg')
def onChange(x):
pass
def ImgBlending(imgfile1, imgfile2):
cv2.namedWindow('Img')
cv2.createTrackbar('Blending', 'Img', 0, 1000, onChange)
while True:
weight = cv2.getTrackbarPos('Blending', 'Img')
img = cv2.addWeighted(imgfile1, float(1000-weight) * 0.001, imgfile2, float(weight) * 0.001, 0)
cv2.imshow('Img', img)
k = cv2.waitKey(1) & 0xFF
if k == 27:
break
트랙바를 이용해서 블렌딩 강도를 조절할 수 있음.
2. 이미지 비트연산이란?
이미지는 AND, NOT, OR , XOR 비트연산이 가능핟.
이미지 비트 연산은 특정 영역을 추출하거나 직사각형 모양이 아닌 ROI를 정의할때,
이미지의 바탕을 제거하고 2개의 이미지를 합칠 때에 유용하게 사용 할 수 있음.
cv2.destroyAllWindows()
cv2.waitKey(1)
아래 이 두개의 파일을 합쳐볼건데 로고는 검정배경을 제거하고 자연스럽게 합칠거다.
2.1) ROI영역 추출
로고를 넣을 이미지 영역을 추출한다.
<코드>
rows, cols, channels = img2.shape
roi = img1[ 10:10 + rows, 10:10 + cols ]
roi_bgr = bgr_to_rgb(roi)
plt.imshow(roi_bgr)
plt.title('ROI')
plt.xticks([])
plt.yticks([])
plt.show()
2.2) 로고 이미지를 흑백으로 전환하고 binary이미지로 전환한다.
threshold함수를 사용하는 이유는 픽셀값이 10 이상으로 넘어가면 255로 변경해서
뒷배경을 제외하고 정확한 로고 부분을 추출하기 위함이다.
또한 비트 연산으로 이를 반전시켜 mask_inv에 저장한다. (흰->검, 검->흰)
<코드>
img2gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
ret, mask = cv2.threshold(img2gray, 10, 255, cv2.THRESH_BINARY)
mask_inv = cv2.bitwise_not(mask) # 0->255 / 255-> 0 반대로 만드는 연산
images = [img2gray, mask, mask_inv]
titles = ["gray-scale", "mask", "mask_inv"]
plt.figure(figsize=(8, 8)) # 가로세로 8인치로 설정
for i in range(3):
plt.subplot(1, 3, i+1)
plt.imshow(images[i], cmap="gray")
plt.title(titles[i])
plt.axis('off')
plt.tight_layout()
plt.show()
2.3) mask, maks_inv로 추출한 이미지를 배경과 로고 이미지와 bitwise_and 연산
둘다 0이 아닌 값만 통과시키기 (검정 제외시키기)
img1_bg = cv2.bitwise_and(roi, roi, mask = mask_inv)
img2_fg = cv2.bitwise_and(img2, img2, mask = mask)
dst = cv2.add(img1_bg, img2_fg)
img1_bg_rgb = bgr_to_rgb(img1_bg)
img2_fg_rgb = bgr_to_rgb(img2_fg)
dst_rgb = bgr_to_rgb(dst)
images = [img1_bg_rgb, img2_fg_rgb, dst_rgb]
titles = ["img1_bg", "img2_fg", "dst"]
plt.figure(figsize=(8, 8))
for i in range(3):
plt.subplot(1, 3, i+1)
plt.imshow(images[i], cmap="gray")
plt.title(titles[i])
plt.axis('off')
plt.tight_layout()
plt.show()
2.4) 최종으로 합친 dst를 img1에 합쳐주면 끝
img1[ 10:10 + rows, 10:10 + cols ] = dst
cv2.imshow('result', img1)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.waitKey(1)