inRange関数 を使えば、特定の範囲の色のピクセルのみを抽出することができます。
特定の範囲の色の指定方法ですが、今回はHSVを使って指定しました。
RGBからHSVに変換する際の選択肢として、COLOR_RGB2HSV と COLOR_RGB2HSV_FULL のどちらを使うか迷ったのですが、調査の結果 COLOR_RGB2HSV_FULL を使うことにしました。
COLOR_RGB2HSVはHの1階調を2度、COLOR_RGB2HSV_FULLはHの1階調を1度として扱うようです。
まずは、画像から青っぽい部分を抜き出してみます。
ソースコード(抜粋)
const Module = { onRuntimeInitialized() { const img = new Image(); img.onload = () => { const srcMat = cv.imread(img); const distMat = new cv.Mat(); const minMat = cv.matFromArray( 1, 3, cv.CV_8UC1, [90, 36, 0] ); const maxMat = cv.matFromArray( 1, 3, cv.CV_8UC1, [170, 255, 255] ); cv.cvtColor(srcMat, distMat, cv.COLOR_RGB2HSV_FULL); cv.inRange(distMat, minMat, maxMat, distMat); cv.imshow('src', srcMat); cv.imshow('dist', distMat); }; img.src = 'img.png'; } };
ソースコード(抜粋)
const Module = { onRuntimeInitialized() { const img = new Image(); img.onload = () => { const srcMat = cv.imread(img); const distMat = new cv.Mat(); const minMat = cv.matFromArray( 1, 3, cv.CV_8UC1, [90, 36, 0] ); const maxMat = cv.matFromArray( 1, 3, cv.CV_8UC1, [170, 255, 255] ); cv.cvtColor(srcMat, distMat, cv.COLOR_RGB2HSV_FULL); cv.inRange(distMat, minMat, maxMat, distMat); cv.medianBlur(distMat, distMat, 7); // 追加 cv.imshow('src', srcMat); cv.imshow('dist', distMat); }; img.src = 'img.png'; } };
ソースコード(抜粋)
const Module = { onRuntimeInitialized() { const img = new Image(); img.onload = () => { const srcMat = cv.imread(img); const distMat = new cv.Mat(); const minMat = cv.matFromArray( 1, 3, cv.CV_8UC1, [90, 36, 0] ); const maxMat = cv.matFromArray( 1, 3, cv.CV_8UC1, [170, 255, 255] ); cv.cvtColor(srcMat, distMat, cv.COLOR_RGB2HSV_FULL); cv.inRange(distMat, minMat, maxMat, distMat); cv.medianBlur(distMat, distMat, 3); cv.imshow('src', srcMat); cv.imshow('dist', distMat); document.getElementById('ratio').innerText = `青: ${ cv.countNonZero(distMat) / (distMat.cols * distMat.rows) * 100 }%`; // 追加 }; img.src = 'img.png'; } };
結果
青っぽい部分は全体の8.16%程度でした。