Python | OpenCVで色の割合を求める

Python | OpenCVで色の割合を求める

今回は画像に含まれる「色」の割合を数値化してみたいと思います。

二値化の場合(閾値処理)

まずは二値化から行いました。コードは以下の通りです。

※以下のサイトを参考にしています。

処理の流れ

cv2.threshold()を利用することで、簡単に2値化を行うことができます。

1)画像のグレースケール化

2)二値化処理

cv2.threshold(画像, 閾値, 閾値以上の場合に置き換える値, 閾値処理のフラグ)

閾値処理のフラグ

フラグは幾つか種類があります。

・cv2.THRESH_BINARY
・cv2.THRESH_BINARY_INV
・cv2.THRESH_TRUNC
・cv2.THRESH_TOZERO
・cv2.THRESH_TOZERO_INV

3)割合計算

の流れです。

# ------------------------------------------------------------
# 画像の二値化
# ------------------------------------------------------------

import cv2

try:
    # 1)画像を読み取る / 引数=(表示したい画像のパス)
    img = cv2.imread('lena_std.bmp')
    if img is None:
        raise FileNotFoudError('File Not Found!')

    # 2)閾値(threshold)の設定
    th = 100
    
    # 3)グレースケールに変換 
    img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
    # 4)2値化処理
    #   輝度が th(100)以上の場合は 白(255)に設定する
    ret, img_th = cv2.threshold(img_gray, th, 255, cv2.THRESH_BINARY)

    # 5)白黒の割合を計算
    #  今回の場合
    #    >> size = 786432
    #    >> white = 179171
    #    >> 白の領域: white/size / 黒の領域: 100-白の領域
    size = img.size
    white = cv2.countNonZero(img_th)
    whiteAreaRatio = (cv2.countNonZero(img_th)/size)*100
    blackAreaRatio = 100-whiteAreaRatio
    print("White:"+str(whiteAreaRatio) +"[%]\nBlack:" + str(blackAreaRatio)+"[%]")
    
    # 6)画像を表示する / 引数=(Window名,表示したい画像)
    cv2.imshow('lena_std',img_th)

    # 7)キーイベントの待機 / 引数=0 で何か入力されるまで待つ
    cv2.waitKey(0)

    # 8)入力されたら、ウィンドウを閉じる
    cv2.destroyAllWindows()

# except) Error時
except FileNotFoundError as e:
    print(e)

出力される画像は以下の通りです。

黒の比率が高いことが分かります。

th =100の場合

White:22.782770792643227[%]
Black:77.21722920735678[%]

3色(GBR)の場合

ヒストグラムを表示したいと思います。

#------------------------------------------------------------
# 色成分の抽出
#------------------------------------------------------------
import numpy as np
import cv2
import copy
import matplotlib.pyplot as plt

try:
    # 1)画像を読み取る / 引数=(表示したい画像のパス)
    img = cv2.imread('lena_std.bmp')
    if img is None:
        raise FileNotFoudError('File Not Found!')
    
    # 2)サイズを 縦300px にリサイズする(高さは連動) 
    img_h,img_w = img.shape[:2]
    size = (300,int(300/img_w*img_h),)
    img = cv2.resize(img,size)
    
    # 3)色の抽出
    # --------------
    # axis = 0 : blue
    # axis = 1 : green
    # axis = 2 : red
    # --------------
    
    # blueのみ抽出
    img_b = copy.deepcopy(img)
    img_b[:,:,(1,2)] = 0
    
    # greenのみ抽出
    img_g = copy.deepcopy(img)
    img_g[:,:,(0,2)] = 0
    
    # redのみ抽出
    img_r = copy.deepcopy(img)
    img_r[:,:,(0,1)] = 0
    
    # 4)画像を表示する 
    mergeImg_01 = np.hstack((img,img_r)) #hstack ->横
    mergeImg_02 = np.hstack((img_g,img_b))
    mergeImg_all = np.vstack((mergeImg_01,mergeImg_02)) #vstack ->縦
    cv2.imshow('lena_std',mergeImg_all)
    
    # 5)ヒストグラムの表示
    hist_b = cv2.calcHist([b],[0],None,[256],[0,256])
    hist_g = cv2.calcHist([g],[0],None,[256],[0,256])
    hist_r = cv2.calcHist([r],[0],None,[256],[0,256])
    plt.plot(hist_r, color='r', label="r")
    plt.plot(hist_g, color='g', label="g")
    plt.plot(hist_b, color='b', label="b")
    plt.legend()
    plt.show() 
    
    # 6)キーイベントの待機 / 引数=0 で何か入力されるまで待つ
    cv2.waitKey(0)

    # 7)入力されたら、ウィンドウを閉じる
    cv2.destroyAllWindows()


# except) Error時
except FileNotFoundError as e:
    print(e)

各色のイメージ↓

ヒストグラム↓

今回は以上です!

本日のAmazonおすすめ_Top10

2024-04-25 09:50:49時点