タイトルの文字数制限に引っかかるので短くしました。
基本的に一貫性のない男です。
基本的に一貫性のない男です。
危なくやる気がなくなって更新が止まってしまうとこでしたが今回は「画像処理」と検索すると関連キーワードに出る「ラベリング」についてです。
これは写真加工にも使えそうですが、どちらかというと画像処理の仕事で頻繁に使ってます。
そのくせなぜか本家のOpenCVには現在実装されてません。
ラベリングとは二値化処理された画像において連結した領域に同じ番号を割り振る処理です。
文章で説明してもなんのこっちゃ分からんという感じなんで処理した画像載せます。
これが原画像です。
![ラベリング前](https://stat.ameba.jp/user_images/20121108/01/sakiyamak/40/4f/j/t02200165_0520039112275643212.jpg?caw=800)
![ラベリング前](https://stat.ameba.jp/user_images/20121108/01/sakiyamak/40/4f/j/t02200165_0520039112275643212.jpg?caw=800)
これが前処理で二値化された画像です。
![二値化](https://stat.ameba.jp/user_images/20121108/01/sakiyamak/c9/20/j/t02200165_0520039112275643213.jpg?caw=800)
二値化については以前ブログで紹介した…と思ったらしてませんでした!
…面倒なうえ見た目もつまらないんでパス!
まあ良い感じで白黒の二色にする処理ですw
そしてこれをラベリングして色分けした画像がこちらです。
![ラベリング後](https://stat.ameba.jp/user_images/20121108/01/sakiyamak/ba/9a/j/t02200165_0520039112275643211.jpg?caw=800)
連結した領域に同じ色が割り振られていることが分かると思います。
正確には連結した領域に同じ番号が割り振られるのがラベリングです。
その番号ごとに色を塗って表示させました。
OpenCVjsを使ってのjavascriptコードはこんな感じです。
function Labeling(imgId, iplImage){
//必要な変数を宣言
var iplImage2 = null;
var min_val = new Array(4);
var max_val = new Array(4);
var min_locs = new Array(4);
var max_locs = new Array(4);
for(var i = 0 ; i < 4 ; i++){
min_locs[i] = new Point();
max_locs[i] = new Point();
}
//白黒濃淡画像に変換 (*1)
cvCvtColor(iplImage, iplImage, CV_CODE.RGB2GRAY);
//2値化 処理する画像によって第3引数を変える (*2)
cvThreshold(iplImage, iplImage, 100, 255, CV_THRESHOLD_TYPE.THRESH_BINARY_INV);
//ラベリング処理 (*3)
iplImage2 = cvLabeling(iplImage);
//画素の最大値を検出することで領域の数を数える
cvMinMaxLoc(iplImage2, min_val, max_val, min_locs, max_locs);
var maxV = max_val[0];
for(var i = 0 ; i < iplImage2.height ; i++){
for(var j = 0 ; j < iplImage2.width ; j++){
//領域の番号を取得
var v = iplImage2.RGBA[(j + i * iplImage1.width) * CHANNELS] ;
//領域番号によって色を変える(HSV表色系の値を代入)
iplImage.RGBA[(j + i * iplImage2.width) * CHANNELS] = 255 * v / maxV;
iplImage.RGBA[1 + (j + i * iplImage2.width) * CHANNELS] = 255;
iplImage.RGBA[2 + (j + i * iplImage2.width) * CHANNELS] = (v == 0) ? 0 : 255; //背景(0)ならVの値を0にする
iplImage.RGBA[3 + (j + i * iplImage2.width) * CHANNELS] = 255;
}
}
//HSVからRGBへ表色系を変換
cvCvtColor(iplImage, iplImage, CV_CODE.HSV2RGB);
//指定したimgタグへ画像を出力
cvShowImage(imgId, iplImage);
}
ほとんどが見た目に分かりやすく出力するための色塗りの処理であり、純粋なラベリングは(*1)(*2)(*3)だけです。
本来はこのあとにノイズの除去などに応用されますがウェブ業界の場合だとどう応用すべきか…
無理矢理思いついたことを書くと割り振られた番号ごとに写真加工フィルタを変えてみるといったことも出来るので面白いかもしれません。