🧐

OpenCVで画像内の「最頻色」を取得する

2022/09/16に公開

画像内の「最も多くの面積を占める色」を取得したく、考案したのがRGB全ての最頻値を取るというやり方でした。

BGRを3byte分の文字列に結合してstatistics.mode()で最頻値を取得してRGBそれぞれに分解し直してます。

一見同じ色に見えても、webカメラからの画像ソースだったりするとRGB値全てがキレイに揃わないことも多いですが、
inRange()で範囲を指定するときその基準となる色には使えそうです。

そのへんの事情を考慮すると本当はこういうのはクラスタリングで取得するのが最適なんですかね?🤔
もっとうまい実装法を知りたいです。

import cv2
import numpy as np
import statistics

def 画像の最頻色を取得(img):
    color_arr = np.vstack(img) # pix数 * 3(原色) の形状の行列
    color_code = ['{:02x}{:02x}{:02x}'.format(*color) for color in color_arr]

    mode = statistics.mode(color_code)
    b = int(mode[0:2], 16)
    g = int(mode[2:4], 16)
    r = int(mode[4:6], 16)
    color_mode = (r, g, b)
    return color_mode

img = cv2.imread(r'img.jpg')
print( 画像の最頻色を取得(img) )

Discussion