OpenCV でマスク処理をする

OpenCV でマスク画像を生成するには、 cv2.inRange(画像,最小値,最大値) を使う。inRange では範囲内が 255 、範囲外が 0 の画像が出力される。

画像編集前後

先にマスク処理でできたことを紹介。紅葉を赤くした。画像全体を赤くするだけだと不自然なので、空の青はそのままにして、空以外の部分を変化させ、合成した。

元画像:紅葉
編集画像:空の青い部分はそのまま、それ以外の部分を赤くした

コード

今回 HSV 情報からマスク画像を生成した。mkmask 関数に元画像と、HSV の範囲を渡して mask にする。これで、紅葉の元画像の、空の青い部分と、それ以外の部分とが、 mask によって判定できる。全体を赤くした画像 imgr を作成し、mask を使って img2 に合成。このようにして、紅葉を更に赤く表現した。

import cv2
import sys
import numpy as np

# 画像を加工する
def mkimg(img):
    # 赤くする操作
    rc = [[0.6, 0. , 0.1],
          [0. , 0.6, 0.1],
          [0. , 0. , 0.8]]
    imgr = bgrtune(img,rc)

    # マスク処理操作 HSV 範囲から mask を作成し、2種類の画像を img2 に合成する。
    mask = mkmask(img,90,120,0,255,0,255)
    img2 = img * (mask/255) + imgr * (1-mask/255)
    
    return img2

# HSV情報からmaskを作成
def mkmask(img,hmin,hmax,smin,smax,vmin,vmax):
    h,s,v = np.float32(cv2.split(cv2.cvtColor(img,cv2.COLOR_BGR2HSV)))  # 色空間をBGRからHSVに変換
    mask = (cv2.inRange(h,hmin,hmax)/255) \
         * (cv2.inRange(s,smin,smax)/255) \
         *  cv2.inRange(v,vmin,vmax)
    return cv2.cvtColor(ct(mask), cv2.COLOR_GRAY2BGR)

# 行列でBGRを編集する
def bgrtune(img,rc):
    img2 = np.dot(np.float32(img) , rc)
    return ct(img2)

# 値を0-255にclipして、typeをuint8にする                                                 
def ct(img):
    return np.clip(img,0,255).astype(np.uint8)

file_name = sys.argv[1]
img = cv2.imread(file_name)
img2 = mkimg(img)

cv2.imwrite(file_name.replace(".",".out."),img2)

コメント

タイトルとURLをコピーしました