opencvのJavaScript版でラベリングを行おうとして基本的なところで躓いています。
当方jsもopencvも初心者でこちら(前回の質問)で画像のピックアップを模索していましたが、躓き部分が質問のレベルに達っせず、新規質問として改めさせていただきます。
前提
PythonからのJavaScriptへのビルド?は成功せず、githubを調べたところ、asm.js版のopencv.jsが公開されていて、そちらを利用したところopencv.jsが機能を始めたので良しとしました。(探してもnode.js版とasm.js版、もしくはver3.xより古いものしかない)
https://github.com/huningxin/opencv.js/tree/master/build/asm.js/opencv.js
こちらを拝借。
asm.jsは、対応環境でなければjavaScriptのサブセットとして動くということなので、問題は無いと思ってます
テスト環境と実際のプログラム
テストしてる環境はこちらです
以下要約
html
1 <script src="https://cdn.rawgit.com/ssmxgo/opencv.js/ff19899a/build/asm.js/opencv.js" type="text/javascript"></script>
JavaScript
1 // 画像の読み込み 2 let mat = cv.imread(imgElement); 3 // 変換先(処理をかけた画像)の定義 4 var dst_gray = new cv.Mat(); 5 var dst_binary = new cv.Mat(); 6 var label = new cv.Mat(); //ラベル画像(CV_32SC1 or CV_16UC1) 7 var stats = new cv.Mat(); //バウンディングボックスを形成する値と面積値 8 var centroids = new cv.Mat(); //重心(x,y)(CV_64FC1) 9 10 11 // グレースケール変換 12 cv.cvtColor(mat, dst_gray, cv.COLOR_RGBA2GRAY, 0); 13 //二値化 14 cv.threshold(dst_gray, dst_binary, 0, 255, cv.THRESH_BINARY_INV | cv.THRESH_OTSU); 15 16 // ラベリング処理 17 cv.connectedComponentsWithStats(dst_binary, label, stats, centroids, 8, cv.CV_32S); 18 19 console.table(label); 20 console.table(stats);
成功したこと
画像をopencvによるMat形式にセット…①
グレイスケール化(モノクロ化)
2値化(閾値を基準に白と黒の2色化)…②
です。
①…
②…
できないこと
本題ですが、次にラベリングを行い画像の要素の取得?、その後に領域検索?みたいなことをする予定なのですが(素人でしてやりながらの理解になります)、その前提としての
connectedComponentsWithStats
がうまく値を取得できていないようです(できているかもしれませんが解析する力がありません)
上がlabel,下がstatus をconsole.talbeで出力したものですがわけわかりません(汗)
配列でそれぞれの画像のプロバティが戻ってくるようなイメージなのですが…(そもそもその認識が間違ってるかもしれませんが)
※ちなみにFirefoxを使ってますが、chromeだと若干レスポンスが違うように思います
ひっかかり
こちらのページを参照していますが、Pythonはよくわからないながら
Python
1 int nLab = cv::connectedComponentsWithStats(src, LabelImg, stats, centroids); 2 3 // ラベリング結果の描画色を決定 4 std::vector<cv::Vec3b> colors(nLab); 5 colors[0] = cv::Vec3b(0, 0, 0); 6 for (int i = 1; i < nLab; ++i) { 7 colors[i] = cv::Vec3b((rand() & 255), (rand() & 255), (rand() & 255)); 8 } 9 10 // ラベリング結果の描画 11 cv::Mat Dst(src.size(), CV_8UC3); 12 for (int i = 0; i < Dst.rows; ++i) { 13 int *lb = LabelImg.ptr<int>(i); 14 cv::Vec3b *pix = Dst.ptr<cv::Vec3b>(i); 15 for (int j = 0; j < Dst.cols; ++j) { 16 pix[j] = colors[lb[j]]; 17 } 18 }
ラベリング結果の描画色を決定 というところはさっぱりわからないのですが、その下のラベリング結果の描画では、
LabelImg.ptr<int>(i)
みたいな表現が出てきます。
推測ですが、LabelImg.ptr(i)をforで回している考えると、LabelImg.ptrは配列であるべきなのかな?と思ったりするわけですが、undefinedが返されてます。
つまりそもそも connectedComponentsWithStats の設定が失敗しているのかな?と。
あと、付随しますが
javascript
1 var label = new cv.Mat(); //ラベル画像(CV_32SC1 or CV_16UC1) 2 var stats = new cv.Mat(); //バウンディングボックスを形成する値と面積値 3 var centroids = new cv.Mat(); //重心(x,y)(CV_64FC1)
とコメントにありますが、いずれもデータ・タイプを設定していないところに問題があるのか?。そもそも設定の仕方もわからないですが。
結果的に、こちらのページで紹介されているようなステップにつなげる予定です。
こちらはこちらでpythonさっぱりでやろうとしてることはなんとなくわかりつつも、コードが解析できませんが、それは混沌とさせてしまうため、ここでは割愛いたします
回答2件
あなたの回答
tips
プレビュー