画像処理ソリューション
これを見れば画像処理の入門から基礎~応用まで全てがわかるのを目指して!
   
翻訳(Translate)

プロフィール

Akira

ニックネーム:Akira
東京都の町田事業所に勤務
画像処理ソフトの開発を行っています。リンクフリーです!
詳細プロフィールは こちら
お問い合わせは、こちら↓

【補助HP】
画像処理ソリューションWeb版 【Newブログ】
イメージングソリューション

スポンサーリンク


カテゴリ

最近のコメント

カレンダー

07 | 2017/08 | 09
S M T W T F S
- - 1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31 - -

趣味のブログ

iPhone萬歳!
iPhoneの情報いろいろ。
ブログ学習帳
ブログ、SEO、アフィリエイト情報など(まだまだこれから)
俺流クラフト日記
ハンドメイド作品の記録(現在、放置中)

スポンサーリンク 最近の記事
(09/18)  計測測定展に光切断のデモを出展しました
(08/17)  ディジタル画像技術事典200に記事が載りました
(06/09)  光切断を画像センシング展で公開
(05/14)  中国(上海)へ行って来ました
(04/12)  韓国へ行って来ました
(03/10)  私の求める新人像
(01/18)  エレクトロテストジャパンにカラー光切断法のデモを出展しました。
(12/23)  ユニークアクセス200万達成!
(12/10)  【カラー光切断法】YouTube動画まとめ
(11/04)  国際画像機器展2014にカラー光切断法を出展します。
(10/05)  第25回コンピュータビジョン勉強会@関東に参加してきました。
(09/08)  フーリエ変換の記事を追加しました。
(08/09)  【画像処理】ランキング低下中
(07/06)  記事の更新が停滞中...
(06/08)  画像センシング展2014でカラー光切断法のデモを行います。
(05/17)  カラー光切断法の動画を公開しました。
(04/30)  ソニーα NEX-5Rで星空撮影
(04/10)  カラー光切断法の取込結果を追加しました
(03/08)  Korea Vision Show 2014へ行ってきました
(02/05)  フーリエ変換シリーズを始めます。
(01/06)  2014年、あけましておめでとうございます。
(12/04)  カラー光切断法を公開(国際画像機器展2013にて)
(11/13)  国際画像機器展2013に出展します
(10/14)  「画像処理のためのC#」はじめます。
(09/16)  【C#,VB.NET】高速描画コントロールをバージョンアップしました。
(09/04)  拡大鏡に輝度値表示、ルーラー機能を追加した個人ツールを公開
(08/05)  7月の拍手Top5
(07/06)  2013年6月人気記事Top5
(05/12)  SONY α NEX-5Rレビュー
(04/24)  SONY α NEX-5RY購入

【OpenCV】IplImageの輝度値を参照、設定する

メインページOpenCV

IplImageの輝度値(画素値)を直接参照、設定したい場合はIplImage構造体のimageDataのポインタを参照するばいいのですが、このポインタが符号付き8Bitのポインタ(char*)なので、ちょっと分かりづらいかもしれません。

と、その前に、IplImageの画像データがどのように格納させているか?のおさらいです。

モノクロ8Bit(8Bit、1Channnel)の場合、下図のように画像の左上を原点として、輝度値が格納されています。
画像のメモリ的にはwidtStepバイトの幅で確保され、必ずしも画像の幅(width)と一致しないので、注意して下さい。
(メモリの幅は4の倍数のバイト数になるように調整されています。)
この辺は.NETのBitmapと同じです。

IplImageの輝度値を参照、設定する

24Bitカラー(8Bit、3Channnel)の場合は、同じように画像の左上を原点として、輝度値がBGRBGR・・・の順で格納されています。

IplImageの輝度値を参照、設定する

この事を踏まえて、画像のコントラストを調整するサンプルプログラムは以下のようになります。

//////////////////////////////
// コントラスト調整
// src:入力画像(8Bit)
// dst:出力画像(8Bit)
// scale:輝度値の倍率
// offset:オフセット量
//////////////////////////////

void cv_ScaleShift(IplImage* src, IplImage* dst, double scale, double offset){

    int i, j;
    double val;
   
    //画像データポインタを取得する
    uchar *pSrc = (uchar*)src->imageData;
    uchar *pDst = (uchar*)dst->imageData;

    for (j = 0; j < src->height; j++){
        for (i = 0; i < src->width * src->nChannels; i++){
            //入力データにscaleを掛けてshiftを足す
            val = pSrc[i + j * src->widthStep] * scale + offset;

            //計算結果を0~255の範囲内にする
            val = (0 > val) ? 0 : val;
            val = (val < 255) ? val : 255;

            //計算結果を代入する
            pDst[i + j * dst->widthStep] = (uchar)val;
        }
    }
}

ポインタの参照方法は、人によって好みがあるかと思いますので、上記プログラムの最適化はお任せします。

ただし、上記ブログラムは輝度値の参照方法の説明のために書いただけなので、コントラストを調整したい場合は、OpenCVのcvConvertScale関数を使った方が簡単です。

また、cvSobel関数のように符号付き16Bitの画像データを使う場合もあるかと思いますが、その場合は
16Bitなので1画素に付き2バイト使う事を踏まえて

IplImage* img  = cvCreateImage(cvSize(640, 480), IPL_DEPTH_16S, 1);

short *pBuf = (short*)img->imageData;

//輝度値の参照する座標を(i, j)とした時の輝度値の参照方法
short val = pBuf [i + j * src->widthStep / 2];

のように輝度値を参照します。


OpenCVのChannnelという扱い。
OpenCVを始めたばかりの頃は、なかなか馴染めなかったのですが、よくよく考えるとChannnelを使う事でカラーとモノクロの処理を同じ関数で処理することができるので、結構、便利。
例えば、注目画素の左上の画素を参照する場合、昔だったら
  val = pSrc[i - 1 +( j - 1) * src->widthStep];
のように参照していましたが、これを
  val = pSrc[i - ch +( j - 1) * src->widthStep];
とするだけで、1つの関数でカラー(ch = 3)、モノクロ(ch = 1)対応になってしまうので簡単。

昔は、カラーをR,G,Bに分けて各RGBのプレーンにモノクロのフィルタ処理をして、RGBに戻す。
なんていう処理をしていました...

【関連記事】
IplImage構造体
IplImageからBitmapを確保する

Loading...
スポンサーリンク

この記事に対するコメント
Re: タイトルなし
fuさん、はじめまして


ポインタをキャストしている部分の
 (float)(unsigned)
はいまいちどのように動くのか?わからないのですが、キャストをしていない場合は

ptr[x + y * parallax->widthStep / 4])

が正解だと思います。

ptr[x * 4 + y * parallax->widthStep]だと、4チャンネルのデータ(1画素あたり、32ビットのデータが4個ある)となるのですが、それを意図していますでしょうか?

実行すると
0xC0000005: Access violation
のようなメッセージが出ていないでしょうか?
もし、メッセージが出ているようならエラーメッセージで検索すると(今回の場合は「0xC0000005」でしょうか?)、原因の特定が早くなると思います。
【2017/06/14 07:01】 URL | Akira #- [ 編集]


はじめまして。この記事を参考に32bit浮動小数点で構成された画像の各画素の輝度値をテキストデータに保存するプログラムを書いております。プログラムの必要な部分を下記に示します。(ファイル開閉や画像の作成等は省略しています)ご存知でしたらご教授下さい。よろしくお願いします。また、記事中でshort val = pBuf [i + j * src->widthStep / 2];と表記されておりますが、short val = pBuf [i + j * src->widthStep * 2];の間違いではないでしょうか?

fprintf(file2, "y x parallax:[m??]\n");

float *ptr = (float *)parallax->imageData;//最初の画素のポインタを得る

for (int y = 0; y < parallax->height; y++){
for (int x = 0; x < parallax->width; x++){
fprintf(file2, "%f\n",(float)(unsigned)ptr[x * 4 + y * parallax->widthStep]);//depthは IPL_DEPTH_32F
}
}

実行すると動作を停止し保存はできない状態となります
【2017/06/14 05:02】 URL | fu #mQop/nM. [ 編集]


この記事に対するコメントの投稿














管理者にだけ表示を許可する


この記事に対するトラックバック
トラックバックURL
→http://imagingsolution.blog107.fc2.com/tb.php/267-61001ddb
この記事にトラックバックする(FC2ブログユーザー)

現在の閲覧者数: / 合計