今回は【色を抽出】したいと思います。
正確には、【RGBの指定色のグレースケールを取得する】というのが表現的に正しいのかもしれません。
何言っているか分かりませんよねw
こういうことは、[百聞は一見に如かず]です。
実際にやってみましょう。
今回使用する関数
今回は、画像のチャンネルとして、3チャンネル(RGB)という事を前提とします。
HOperatorSet.Decompose3(HObject, out HObject, out HObject, out HObject)
簡単に引数説明。
第1引数:入力画像(3チャンネルの画像) 第2引数:1チャンネル目の画像(赤) 第3引数:2チャンネル目の画像(緑) 第4引数:3チャンネル目の画像(青)
下記に詳細の説明があります。
decompose3 [HALCON Operator Reference / Version 18.11.3.0] (mvtec.com)
サンプルを作ってみる
今回は、分かりやすいように色の数値が分かるように画像を作ってみました。
色を数値で表しているのは下記ルールです。
操作画面
いつものことながら、【読込】ボタン(btnReadImg)をクリックされたら、ユーザーに画像を選択してもらい、選択された画像を表示します。
そして、【チャンネル別】ボタン(btnColorCH)をクリックされたら、各チャンネルの画像を表示します。
[CH1:hWindowControl2]
[CH2:hWindowControl3]
[CH3:hWindowControl4]
定義
使用するnamespaceを明記します。
using HalconDotNet;
そして、フォーム内で使用する変数を定義します。
HObject DispOrgImg = null; //読み込んだ画像
const double DEF_W = 640.0;
const double DEF_H = 480.0;
処理
では、【チャンネル別】ボタンをクリックされた時の処理を紹介します。
private void btnColorCH_Click(object sender, EventArgs e)
{
if (DispOrgImg == null) return; //読み込んでいるかどうか
//チャンネルに分ける
HOperatorSet.Decompose3(DispOrgImg,
out HObject img1, out HObject img2, out HObject img3);
//ハンドル取得
HTuple hwndch1 = hWindowControl2.HalconWindow;
HTuple hwndch2 = hWindowControl3.HalconWindow;
HTuple hwndch3 = hWindowControl4.HalconWindow;
//表示削除
HOperatorSet.ClearWindow(hwndch1);
HOperatorSet.ClearWindow(hwndch2);
HOperatorSet.ClearWindow(hwndch3);
//Zoom方式で表示する
DispZoom(hwndch1, img1);
DispZoom(hwndch2, img2);
DispZoom(hwndch3, img3);
}
Decompose3()を使用して、各チャンネルの画像に分ける事が出来ました。
実行結果
Channel1は、RGBのR(赤)の部分になります。
Channel2は、RGBのG(緑)の部分になります。
Channel3は、RGBのB(青)の部分になります。
取得した各チャンネルは、グレースケールで取得されます。
【00は黒】~【FFは白】ですね。
まとめ
今回は、【色の抽出】をしてみました。
ちょっとイメージとは違いましたw
赤を取り出したら、赤だけの画像になってほしかったのですが。。。
それでも、赤だけの画像になった結果、グレースケールの画像として表現されるのです。
画像処理は難しいですね。。。
補足(作った関数の紹介)
■チャンネル数の取得関数
特に紹介しませんでしたが、下記関数を使用するとチャンネル数を取得できます。
今回はファイル読み込み時に取得して、表示するように作りました。
HOperatorSet.CountChannels(HObject, out HTuple)
■ユーザーにファイルを指定してもらう関数
private DialogResult SelectImageFile(out string fp)
{
fp = "";
OpenFileDialog ofd = new OpenFileDialog();
ofd.FileName = "";
ofd.InitialDirectory = @"C:\";
ofd.Filter = "画像ファイル(*.png;*.jpg)|*.png;*.jpg";
ofd.Title = "開くファイルを選択してください";
DialogResult res = ofd.ShowDialog();
if (res == DialogResult.OK) fp = ofd.FileName;
return res;
}
■画像サイズの比率を変えずに表示枠いっぱいに表示する
private void DispZoom(HTuple windowhandle, HObject img)
{
//Zoom方式で表示
HOperatorSet.GetImageSize(img, out HTuple w, out HTuple h);
double rateR = DEF_H / h, rateC = DEF_W / w;
double rate = (rateR < rateC) ? rateR : rateC;
double c1 = -((DEF_W / rate) - w) / 2;
double c2 = c1 + (DEF_W / rate);
double r1 = -((DEF_H / rate) - h) / 2;
double r2 = r1 + (DEF_H / rate);
HOperatorSet.SetPart(windowhandle, r1, c1, r2, c2);
HOperatorSet.DispObj(img, windowhandle);
}
■読込ボタンをクリックされた時の処理
private void btnReadImg_Click(object sender, EventArgs e)
{
//初期化
DispOrgImg = null;
//表示削除
HTuple hwndOrg = hWindowControl1.HalconWindow;
HOperatorSet.ClearWindow(hwndOrg);
//画像を選択してもらう
if (SelectImageFile(out string fp) == DialogResult.OK)
{
//画像読込
HOperatorSet.ReadImage(out HObject img, fp);
DispOrgImg = img;
//Zoom方式で表示
DispZoom(hwndOrg, img);
//チャンネル数取得
HOperatorSet.CountChannels(DispOrgImg, out HTuple chnum);
lblChannelNum.Text = "【チェンネル数】 " + chnum.I.ToString();
}
}
業務でプログラミング(C#/VB/Python)を作っている。
挫折を何回も繰り返し、幾度の壁を乗り越えてきた。
乗り越えてきた事を忘れないように記録に残す。
同じ思いをしている人への情報提供になれたらと思う。
基本は初心者に向けたプログラムの情報を提供する。
コメント