カメラ画像で、色のない部分(白、灰色、黒)を透明にするという画像処理をやってみた。
具体的な処理は以下のとおり。
1.画像をHSVに変換
2.S(彩度)とV(明度)がある程度大きい領域の抜出(mask)
3.maskの領域の画像と、背景画像を重ねる。
プログラムの捜査は、
[space]現在の画像を背景画像としてメモリーに保存
[t] 透明処理の有無を切り替え
[q] 終了
以下プログラム。
S_LOW, V_LOW は環境によって変わるので、適当に調節してください。
import cv2
import numpy as np
S_LOW = 78
V_LOW = 50
isTrans = True
cap = cv2.VideoCapture(0)
ret, img_back = cap.read() # background image
while True:
ret, img = cap.read()
img_h = cv2.cvtColor(img, cv2.COLOR_RGB2HSV)
mask = cv2.inRange(img_h, (0, S_LOW, V_LOW), (180, 255, 255)) # transparent area
mask_inv = cv2.bitwise_not(mask) # inverse of transparent area
mask = cv2.cvtColor(mask, cv2.COLOR_GRAY2RGB)
mask_inv = cv2.cvtColor(mask_inv, cv2.COLOR_GRAY2RGB)
img_masked = cv2.bitwise_and(img, mask) # AND processing
img_back_masked = cv2.bitwise_and(img_back, mask_inv) # AND processing
img_out = cv2.addWeighted(img_masked, 1, img_back_masked, 1, 0) # marge images
if isTrans:
img_show = img_out
else:
img_show = img
cv2.imshow('img', img_show)
INPUT = cv2.waitKey(10) & 0xFF
if INPUT == ord('t'): # mode change: transparent or not
isTrans = 1-isTrans
if INPUT == ord(' '): # capture background image
ret, img_back = cap.read()
if INPUT == ord('q'): # quit
cv2.destroyAllWindows()
break