opencv4nodejsの使い方 thresholdで2値化

先日に続きOpenCVネタである。opencv4nodejsを入れるとnodejsでOpenCVが使えるようになる。
コンパイルエラーを取って、無事ビルドすることができた。
しかし、使い方がわからない。examplesに例があるようなのだが、npm install opencv4nodejsでは作成されないようである。
GitHubには上がっているので、git cloneでごっそり持ってきた。
examplesディレクトリに沢山サンプルがある。しかし、なんか実行できないが...
readmeには簡単なプログラムの例が載っている。しょうがないので簡単なところからやってみよう。まずは画像の読み込みだな。
test.js

const cv = require('../');
const img = cv.imread('sample.jpg');

これで読み込みできるようである。
適当にsample.jpgを用意して、実行してみる。

node test.js

お、実行できるじゃん。
しかし、読み込みをやっただけなので、うまく動いているかよくわからない。
requireのパスはexamplesで実行させる際の指定。ちゃんとモジュールでインストールしたらrequire('opencv4nodejs')でOKと思われる。
じゃあ、書き込みもしてみるか。
test.js

const cv = require('../');
const img = cv.imread('sample.jpg');
cv.imwrite('output.jpg', img);

これで、sample.jpgを読み込んで、output.jpgに出力するはず。sample.jpgがoutput.jpgにコピーされればOK。

% node test.js
% ls *.jpg
sample.jpg output.jpg

やったできたみたい。ちゃんと使えてるじゃない。
imreadにはAsync版もある。単なるimreadはSyncっていうことか。本番サーバーに組み込むときは、Async版を使った方が良いであろう。以下のようにしてみた。
test.js

const cv = require('../');
async function main() {
const img = await cv.imreadAsync('sample.jpg');
await cv.imwriteAsync('output.jpg', img);
}
main();

えーと、何がやりたかったかというと、QRコードの認識率を上げるために画像処理したかったわけなのだが... まずは、グレースケールに変換してみようか。
ちゃんとしたドキュメントがないのでよくわからないなぁ... bgrToGrayでできそうかも。
test.js

const cv = require('../');
async function main() {
const img = await cv.imreadAsync('sample.jpg');
const img_gray = img.bgrToGray();
await cv.imwriteAsync('output.jpg', img_gray);
}
main();

output.jpgを開いてみるとちゃんとグレースケールに変換されているよ。bgrToGrayにはAsync版ないのか?
ややあるじゃん。基本全部にAsyncあるっぽいな。
今度は2値化してみるか。2値化はというと、thresholdかな。こいつにもAsyncがあるぞ。
test.js

const cv = require('../');
async function main() {
const img = await cv.imreadAsync('sample.jpg');
const img_gray = await img.bgrToGrayAsync();
const img_ths2 = await img_gray.thresholdAsync(200, 255, cv.THRESH_BINARY);
await cv.imwriteAsync('output.jpg', img_ths2);
}
main();

thresholdでは、閾値が200(引数の値)で固定。いい感じの値を自動的に決める機能はないみたい。
2値化の手法にadaptiveThresholdというのもある。こちらだと「適応型閾値」を決定してくれるようである。こっちだと画素ごとに閾値をイイ感じに決定してくれるようである。
test.js

const cv = require('../');
async function main() {
const img = await cv.imreadAsync('sample.jpg');
const img_gray = await img.bgrToGrayAsync();
const img_ths2 = await img_gray.adaptiveThresholdAsync(255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY, 11, 2);
await cv.imwriteAsync('output.jpg', img_ths2);
}
main();

がしかし「QRコード読取」の前処理としては、単に2値化する方がよいみたい。「適応型閾値」の方はQRコードの四角が■ではなく、□になってしまうことがある。これでは逆効果かも。

投稿者プロフィール

asai
asai