end0tknr's kipple - 新web写経開発

http://d.hatena.ne.jp/end0tknr/ から移転しました

opencv.inRange() と bitwise_and() による 画像の特定色の抽出

opencv.findContours() による 画像の境界(輪郭)探索 - end0tknr's kipple - 新web写経開発

先程のエントリでは、建物の間取り図のみが記載された画像の輪郭を抽出しましたが、 外構も描かれたケースを考えてみた。

抽出方法と結果は、以下の script の通りです。

#!/usr/local/bin/python
# -*- coding: utf-8 -*-
from PIL import Image
import cv2
from datetime import datetime
import matplotlib
matplotlib.use('Agg')
import matplotlib.pylab as plb
import numpy as np
import sys

def main():
    org_file = sys.argv[1]

    img_org = cv2.imread(org_file)

    img_hsv = cv2.cvtColor(img_org, cv2.COLOR_BGR2HSV)
 
    # 取得する色の範囲を指定する
    lower_color = np.array([  0,  0,  0])
    upper_color = np.array([130,130,130])

    # 指定した色に基づいたマスク画像の生成
    img_mask = cv2.inRange(img_hsv, lower_color, upper_color)

    # フレーム画像とマスク画像の共通の領域を抽出する。
    img_tmp = cv2.bitwise_and(img_hsv, img_hsv, mask=img_mask)

    time_str = datetime.now().strftime("%Y%m%d_%H%M%S")
    # 一旦、fileの出力
    tmp_file = 'tmp_' + time_str + '.png'
    cv2.imwrite(tmp_file, img_tmp)

    # 抽出した壁面が、なぜか赤色となる為、2値化 & ネガポジ反転
    img_tmp = cv2.cvtColor(img_tmp, cv2.COLOR_BGR2GRAY)
    ret, img_tmp = cv2.threshold(img_tmp,
                                 10,                # 閾値
                                 256,               # 画素値の最大値
                                 cv2.THRESH_BINARY_INV) # 2値化type

    new_file = 'new_' + time_str + '.png'
    cv2.imwrite(new_file, img_tmp)


if __name__ == '__main__':
    main()

↑こう書くと↓こう変換されます。

色を抽出するまではできましたが、ドットが粗い?部分があるので 輪郭を求めるには、一旦、膨張処理を行った方が良い気がします

f:id:end0tknr:20120723195307j:plain:w350

f:id:end0tknr:20171104211747p:plain:w270 f:id:end0tknr:20171104211749p:plain:w270