【Python/OpenCV】色抽出処理、フォルダ処理、csv出力

プログラミング

目次

1. 概要

PythonとOpenCVを用いて、以下のような画像の中に描かれた赤い線を画像処理で抽出する方法について紹介します。
さらに、抽出した赤い線の座標値をcsvファイルへ出力する方法や、複数枚の画像を連続的に処理するフォルダ処理を行う方法についても紹介したいと思います。

2. 開発環境

  • OS : Windows10 64bit
  • OpenCV :4.1.0
    Python環境へのOpenCVのインストール方法は、こちらを参照ください。
  • IDE : Spyder

3. 処理内容

早速ですが、pythonのコードを紹介します。

#ライブラリのインポート
import numpy as np
from matplotlib import pyplot as plt
import os
import skimage
from skimage import io
from tqdm import tqdm
import glob
import cv2
import csv

#入力する画像ファイルのディレクトリ、結果出力先のディレクトリを指定
#rootフォルダ - 「data」フォルダ - 「image」フォルダ内にある画像を処理する。
#rootフォルダ - 「data」フォルダ - 「result」フォルダ内へ結果出力する
#rootフォルダとは、.pyがある階層のこと
path="data/"
input_dir="image"
output_dir="result"

#ファイルパスを結合してフルパスを作成
all_files=glob.glob(os.path.join(path,input_dir,"**/*.*"),recursive=True)

#追記型でcsvファイルを作成
csvfile = open("np_csv_test.csv", "w")

#ループ処理の開始
#ループ処理内は、インデントを入れること!
for i,filepath in tqdm(enumerate(all_files)):

    #画像の読み込み
    src = cv2.imread(filepath)

    #抽出する赤色の範囲の定義
    #lower = (0, 0, 200)
    #upper = (50, 50, 255)
    #OpenCV の画像のチャンネルは BGR の順番なので、lower, upper も青、緑、赤の順で指定することに注意
    #適宜数値を変更してください。
    dst = cv2.inRange(src, (0, 0, 200), (50, 50, 255))

    #赤線を抽出した画像をbmpファイルとして保存する。
    #スクリプトファイルと同階層に保存されます。

    #finenameから「画像ファイル名.bmp」を抽出する
    filename = filepath.rsplit("\\")[1]
    #出力する画像ファイルのフルパスを作成する
    outputimage = path + output_dir +"/" + "Extracted_redline_" + filename
    cv2.imwrite(outputimage, dst)

    #赤線の座標値(x,y)を求める
    #<メモ>np.where() を使う。
    #返り値は Y座標、X座標で別れているので、np.dstack()で結合している
    #indices = np.dstack(np.where(dst == 255)) #これはエラーになる
    indices = np.where(dst == 255) #Y,Xの順で出力されるのでエクセルでグラフを作成する場合は注意

    #座標データindicesの出力
    #スクリプトファイルと同階層に保存されます。
    #画像1枚に対して、csv1個が生成される・・・。
    outputcsv = path + output_dir +"/" + "result.csv";

    #結果csv出力のためにいろいろ準備
    #実行のたびに、csvファイルに上書きされるので注意してください。
    y = indices[0]
    y1 = y.reshape(1, y.size)
    x = indices[1]
    x1 = x.reshape(1, x.size)
    axis = np.arange(x.size)
    axis = axis.reshape(1, axis.size)
    with open(outputcsv, 'ab') as f:
        np.savetxt(f, filepath.rsplit("\\"), fmt="%s", delimiter = ",")
        np.savetxt(f, axis, fmt="%.0d", delimiter = ",")
        np.savetxt(f, x1, fmt="%.0d", delimiter = ",")
        np.savetxt(f, y1, fmt="%.0d", delimiter = ",")

#csvファイルのクローズ
csvfile.close()

4. 処理結果

4.1 入力画像

ハート、星型、五角形の形に赤い線が描かれている画像を処理してみます。

4.2 抽出結果

ハート、星型、五角形の形に書かれた赤い線が抽出できています。

4.3 出力結果

エクセル(EXCEL)を使ってグラフにしてみました。
線を構成する各画素の座標(X,Y)が出力されているので、画像と同じようにできています。

コメント

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