Atom's tech blog

OpenCVとmatplotlibで画像ファイルのRGB色をグラフに表示してみた

概要

  • 画像ファイル(VGAサイズ)を40ピクセル毎にRGB値を取得
  • 画像内で重複している色は複数表示しない
  • グラフにRGBの色画像を表示
  • 色画像の横にRGB値を表示
  • CSVファイルにRGB値を書き込み

コメント

  • 画像ファイルの特定の色を変更したい理由で、まずは画像内のRGB値確認のために作成してみた
  • python勉強中で各種変換やループなど簡単な方法でトライ、もっといい方法があるのかも
  • matplotlibのグラフ表示はサンプルコードをカスタマイズ
  • VGA画像サイズで色抽出からグラフ出力まで22秒程度(MacBookPro Core i5
  • ラズパイでも動作可能なはず
  • 表示したRGB色画像は全部確認できていないので間違っていたらすみません
  • 使ったツールバージョンは以下
  • MacOS Catalina / python3.5.6 / Opencv3.4.2 / VS code1.38.1

読み込み画像

f:id:iAtom:20201008143639p:plain

RGB画像出力イメージ

f:id:iAtom:20201008143651j:plain

CSVファイル出力イメージ

f:id:iAtom:20201008143658j:plain

ファイル構成

  • color_detect.py : 画像ファイルRGB値取得/出力処理ソースファイル(下のソースコード

ソースコード

import cv2
import numpy as np
import matplotlib.pyplot as plt

# 変数定義と初期化
color_list = []
list_cnt = 0
same_color = False

# カラー描画/CSVファイル書き込みメソッド
def draw_colors(colors):
    writeFile = open("color_rgb.csv", 'w')
    rows = np.ceil(len(colors) / 10)
    # グラフサイズ    
    fig = plt.figure(figsize=(10, 10))
    # プロットのタイトル    
    fig.suptitle("Photo RGB Colors")
    for i, color in enumerate(colors, 1):
        img = color.reshape(1, 1, 3)
        # BGR -> RGBへ変換
        img_rgb = img[:,:,::-1]
        # RGB値個別取得と文字列に変換
        blue_str = format(img_rgb[0, 0, 2],'02x')
        green_str = format(img_rgb[0, 0, 1],'02x')
        red_str = format(img_rgb[0, 0, 0],'02x')
        # RGB値文字列作成
        rgb_str=red_str+green_str+blue_str
        # CSVファイルに保存
        writeFile.write(rgb_str+"\n")
        # プロット場所
        ax = fig.add_subplot(rows, 10, i)
        # RGB値文字列表示設定
        ax.text(1.8, 0.2, rgb_str, fontsize=7,ha="center",color="black")
        # RGB色を表示設定
        ax.imshow(img_rgb)
        #軸の非表示
        ax.set_axis_off()
    
    #CSVファイルクローズ
    writeFile.close()
    # プロットを全表示    
    plt.show()

# 画像読み込み
img = cv2.imread("cat_face.png",cv2.IMREAD_COLOR)
# 画像サイズ取得
height, width, channels = img.shape[:3]

# 画像高さ 40ピクセル単位でループ
for h in range(0, height,40):
    # 画像幅 40ピクセル単位でループ
    for w in range(0,width,40):
        # 対象画像位置のBGR値を取得
        pixelValue = img[h, w]
        # 同じ色があるか確認用のループ
        for i in range(0,list_cnt,1):
            # 同じ色は抽出対象外とする
            if np.allclose(color_list[i], pixelValue) == True:
                same_color = True
                break

        # 同じ色が無い場合
        if same_color == False:
            # 色情報をListに追加
            color_list.append(pixelValue)
            # 色の数を加算
            list_cnt += 1

        print(".", end="")
        # フラグを初期化
        same_color = False

print("\n")
print("Color Type Cnt : " + str(list_cnt))
# 色表示        
draw_colors(color_list)
# 色リスト情報クリア
color_list.clear()
print("Exit Program")