カメラ画像で、色のない部分(白、灰色、黒)を透明にするという画像処理をやってみた。

具体的な処理は以下のとおり。
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