ロゴ メインコンテンツへ
RSSフィード
「Web 開発」に関連する記事一覧

OpenCV.js で画像の差の絶対値の総和を計算する

2020/03/09
(この記事の文字数: 296)

自作しているFEHツールで、入力したマップ画像がどのマップ種なのかを自動判別したかったので、OpenCV.js で差の絶対値の総和を計算して相関を取る処理を書いてみました。cv.Mat 要素の総和を取る関数が OpenCV.js には見当たらなかったので仕方なく自前で計算しています。


let src1 = cv.imread(sourceCanvas1);
let src2 = cv.imread(sourceCanvas2);
let dst = new cv.Mat();

// 差の絶対値を計算
cv.absdiff(src1, src2, dst);

// 差の絶対値の総和を計算
let channels = dst.channels();
let sum = 0;
for (let y = 0; y < dst.rows; ++y) {
    for (let x = 0; x < dst.cols; ++x) {
        for (let c = 0; c < channels; ++c) {
            sum += dst.ucharPtr(y, x)[c];
        }
    }
}

console.log(`sum = ${sum}`);

src1.delete();
src2.delete();
dst.delete();

しかし、これでは処理速度が大分遅くて実用に耐えない感じになってしまいました。

そこで、以下のようにして高速化したところ実用に耐える速度になりました。具体的には、事前に画像を縮小して全体の処理負荷を削減した、自前で画像処理をしている総和計算部分の負荷を減らすために差の絶対値画像をグレースケールに変換した2点になります。


let src1 = cv.imread(sourceCanvas1);
let src2 = cv.imread(sourceCanvas2);

// 高速化のために画像を縮小してから差の絶対値を取る(精度が落ちるので適度に)
let shrinkDiv = 4;
cv.resize(src1, src1, new cv.Size(src1.cols / shrinkDiv, src1.rows / shrinkDiv), 0, 0, cv.INTER_AREA);
cv.resize(src2, src2, new cv.Size(src1.cols, src1.rows), 0, 0, cv.INTER_AREA);

let dst = new cv.Mat();
cv.absdiff(src1, src2, dst);

// 高速化のためにグレースケールに変換し、1チャンネルのみで総和を計算する
cv.cvtColor(dst, dst, cv.COLOR_RGBA2GRAY, 0);
let channels = 1;

let sum = 0;
for (let y = 0; y < dst.rows; ++y) {
    for (let x = 0; x < dst.cols; ++x) {
        for (let c = 0; c < channels; ++c) {
            sum += dst.ucharPtr(y, x)[c];
        }
    }
}

console.log(`sum = ${sum}`);

src1.delete();
src2.delete();
dst.delete();

  このエントリーをはてなブックマークに追加  

<<「Web 開発」の記事一覧に戻る

コメント(1 件)


1(ID: 1445989647)
2022-01-26 14:19

something like: diffSum = diffGray.data.reduce(function(accumulator, currentValue) { return accumulator + currentValue; }, 0); will avoid the loop


コンテンツロード: 0.0065 sec
Copyright(C)2006-2024 puarts All Rights Reserved