ScanLineを使って画像の色データを取得する方法

このQ&Aのポイント
  • 現在、Visual C++を使用して、画像のグレースケール化、二値化などの加工を行うプログラムを作成しています
  • しかし、各ピクセルの値を1つずつ取得する方法では計算量が多くなり、処理時間がかかってしまっています
  • そこで、ScanLineを用いて1行のデータを取得するプログラムを作成したいのですが、正しいプログラム文がわかりません
回答を見る
  • ベストアンサー

ScanLineを使っての画像の色データ取得

現在、Visual C++を使用して、ある画像のグレースケール化、二値化などの加工を行うプログラムを作成しています。 しかし、今は各ピクセルの値を1つずつとっている状態なので、(行の)for文の中に(列の)for文がある状態になっていて計算量が多くなっているため、加工画像を表示させるまでに時間が少しかかっています。 そこで、ScanLineを用いて1行のデータをとるようなプログラムを作っているのですが、「・・・のメンバーではありません」などのエラーが出て、実行することができない状態です。 現在、加工画像は Bitmap^ bmap_gray=gcnew Bitmap(pictureBox1->Image); としているのですが、ScanLineを使うにはどのようなプログラム文を書けばいいのでしょうか?

  • kitct
  • お礼率13% (7/53)

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

 こんばんは。  BitmapDataクラスです。  http://msdn.microsoft.com/ja-jp/library/system.drawing.imaging.bitmapdata_members(v=VS.71).aspx  かなり複雑なものですので、一貫したプログラムを書くには、時間がかかります。  取りあえず、触りだけ書いておきます。大体以下の様になります。 System::Drawing::Bitmap^ bmap_gray = gcnew System::Drawing::Bitmap(pictureBox1->Image); System::Drawing::Rectangle rect(0, 0, bmap_gray->Width, bmap_gray->Height); //bmap_grayをロックしてBitmapDataクラスを得る System::Drawing::Imaging::BitmapData^ bmpData = bmap_gray->LockBits(rect, System::Drawing::Imaging::ImageLockMode::ReadWrite, bmap_gray->PixelFormat); //イメージへのポインタを取りだす(イメージのピクセルフォーマットによってキャストするサイズが左右されるので要注意) //以下は32bitの場合 System::UInt32* ptr = static_cast<System::UInt32*>(bmpData->Scan0.ToPointer());

関連するQ&A

  • ビットマップ画像の色取得のご相談

    ビットマップ画像の色取得のご相談 WinXPでVC++2008ExpressEditionを使用してWinアプリケーションで画像処理をしようとしています.そこで,現在ビットマップのカラー画像を二値化(閾値判別分析法)するために,各色の抽出してグレースケール化を試みているのですが,色々試したのですがエラーがとれないので,もし間違い等ありましたら,ご助言いただけたらなと思います.何卒よろしくお願いいたします. 【エラー内容】 'System.ArgumentOutOfRangeException' のハンドルされていない例外が System.Drawing.dll で発生しました。追加情報: パラメータは正の値で、高さより小さい値指定しなければなりません。 【流れ】(ボタンを押したら以下三つを実行) 1.ファイルの読み込みピクチャーボックスに表示 2. ビットマップ画像の色の抽出 3. グレースケール化 /*ここから*/ OpenFileDialog^ OpenDlg = gcnew OpenFileDialog; //ファイルを開くダイアログ OpenDlg->Filter ="画像ファイル(*.bmp,*.jpg,*.jpeg,*.png,*.tif,*.tiff,*.ico)|*.bmp;*.jpg;*.jpeg;*.png;*.tif;*.tiff;*.ico"; OpenDlg->ShowDialog(); //ダイアログの表示 if (OpenDlg->FileName == "") { //ファイル名が指定されなかった場合 return; } Bitmap^ bmp; bmp = gcnew Bitmap(OpenDlg->FileName); //Bitmapをファイルより作成 pictureBox1->Image = bmp; //ピクチャボックスへ画像の表示 Bitmap^ bmp1 = gcnew Bitmap(pictureBox1->Image); unsigned char Image_in[480][640][3]; //Image_in[Y][X][3] unsigned char (*Gray)[640] = new unsigned char[480][640]; //(*Gray)[X] = new unsigned char[Y][X] double Y; int i, j; //iがY方向,jがX方向 Color color1; unsigned char R,G,B; // 赤,緑,青成分の抽出 for( i = 1; i < 480; i++) //Y方向 { for( j = 1; j < 640; j++) //X方向 { ////////////////////////////////////////////// /*この辺がエラーの原因だと思うのですが・・・*/ color1 = bmp->GetPixel(i,j); R = color1.R; G = color1.G; B = color1.B; Image_in[i][j][0] = R; Image_in[i][j][1] = G; Image_in[i][j][2] = B; } } //RGB to Gray カラー画像をグレースケール化 for( i = 0; i < 480; i++) //Y方向 { for( j = 0; j < 640; j++) //X方向 { Y = 0.299*Image_in[i][j][0] + 0.587*Image_in[i][j][1] + 0.114*Image_in[i][j][2]; Gray[i][j] = Y; } }

  • C++/CLIでの画像情報(RGB)の取得

    Visual C++ 2005のC++/CLI対応で、.NET Frameworkのクラスライブラリを使用し、画像処理のプログラムを作成しています。 pictureBox1->Image = gcnew Bitmap( ファイル名 ); で、画像を表示するところまではできたのですが、表示したBitmapデータのRGBカラー情報を取得する方法がわからず、困っています。 ご存知の方、教えてください。 また、このような情報が載っている書籍やサイトがありましたら、合わせて教えてください。 よろしくお願いします。 必要な情報が抜けていましたら、お手数ですが、ご指摘お願いします。

  • 二つの画像を並べて表示

    ひとりで独学でVC++2005を勉強してるのですが、pictureBoxでつまずいます。初心者ですがわかりやすく教えて頂けたらと思います。 やりたい事はタイトル通り、画像を単純に並べて表示したいだけなのですが、WEB場で検索しても的を得た答えが見つかりませんでした。 二つの画像を読み込んで、新しいBitmapデータに書き込めばいいのかと思ったのですが、どうやっていいのか見当が付きません。 Bitmap^ bmpA = gcnew Bitmap("testAA.bmp"); Bitmap^ bmpB = gcnew Bitmap("testAB.bmp"); int w = bmpA->Width + bmpB->Width; int h = bmpA->Height + bmpB->Height; Bitmap^ bmp = gcnew Bitmap(w,h); //ここで何やっていいかわかりません。 pictureBox1->Image = bmp; 最終的にはタイル的にどんどん並べて行きたいと考えています。 助言の方よろしくお願いします。

  • VC++2005で高解像度画像の取り扱い。

    いつも質問ばかりで申し訳ないのですが、独学で勉強していて聞ける人がいないので協力して頂けたらと思います。 VC++2005のOS Windows32bit環境で高解像度(10240pixel × 10240pixel以上)の画像を取り扱うにはどうしたら良いのでしょうか? Bitmap^ bmp = gcnew Bitmap( 10240, 10240 ); ~省略 pictureBox1->Image = bmp ; のような書き方をして、エラーが出てる場所は Bitmap^ bmp = gcnew Bitmap( 10240, 10240 ); の部分です。 Bitmap^ bmp = gcnew Bitmap( 5120, 5120 ); だと平気です。 メモリーが不足しています。と警告が出てるのですが、はやり32bit環境では限界なのでしょうか? PCには8GB(うち5GB、RAMディスク)のメモリーを積んでますが、そう言う問題でもないですよね。 PhotoShopやAftterEffectとかはかなりの高解像度でも表示出来てるので不可能では無いとは思うのですが、初心者レベルでは無謀なのでしょうか? 何か打開策があれば教えて頂けたら助かります。 よろしくお願いします。

  • Bitmapデータ型の画像幅の拡大

    現在Visual studio 2005のフォームアプリケーションでプログラミグを行っている者です。以下のプログラムの中に画像の幅であるw,hという変数があるのですが、私の作ろうとしている画像処理の関係上、この画像データの幅を倍にしたいです(例:3*w,3*h)。しかし、変数宣言(例:int 3*w)やfor文の中で倍にしようとしても、ビルドはできるものの"アプリケーションのコンポーネントで、ハンドルされていない例外が発生しました。・・・パラメータは正の値で、高さより小さい値指定しなければなりません。"とでて、実行できません。おそらく倍にしてあげたとこで、倍になった部分の画像データがわからないためこういったエラーが出てしまうのだと考えています。どうにかして、BITMAPデータ型で読み込んだ画像の幅を倍の数値を得たいのですが、エラーのでないようにするためにはどのようにしてあげればいいのでしょうか?わかる方がいたらよろしくお願いします。 プログラムは以下のとおりです。 #pragma once // 省略 // } #pragma endregion private:Bitmap^ pic; private:array< Bitmap^>^ bmp; // 原画像格納 // private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e) { bmp[0] = gcnew Bitmap("画像ファイル1",true); pictureBox1->Image = bmp[0]; pic = gcnew Bitmap("画像ファイル2",true); } private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) { int x,y,a,b; /* x,y: 画像の座標 a,b: 複合画像の座標 */ int w = pic->Width; //ここでpic->Width*3としてもエラー /* 複合画像の横幅 */ int h = pic->Height; /* 複合画像の縦幅 */ x = 0; y = 0; a = 0; b = 0; for(y = 0; y < h; y++){ //ここで3*hとしてもエラー for(x = 0; x < w; x+=3){ pic->SetPixel( x, y, bmp[1]->GetPixel( x, y ) ); } } pictureBox2->Image = pic; } }; }

  • Bitmap.GetPixelより高速なもの

    いまVBでBitmap.GetPixelを使って、グレースケールの画像のRGBを取得しています。 まあグレースケールなんでRGB同じなのでとりあえずRの値を使うとして、 200*300の画像をFor文でBitmap.GetPixelを使うととてもじゃないぐらい遅いです。 ある程度調べると、LockBits()というものが見つかったのですが使い方がわかりません。 教えてください。

  • Open CVについて

    現在,OpenCVとVC++2008のC++/CLIでwindows formアプリケーションを作成しています。 フォーム上のpictureBoxにUSBカメラから取得した画像を,録画しながら,pictureBoxに表示させています。しかし,取り込んだ画像が,pictureBoxに収まり切っていないようです。(添付画像のようなに枠内の画像に対して,肌色部分しか,pictureBoxに表示されていない状態) コードは http://hisoap.jugem.jp/?eid=156 を参考に,以下のように記述しています。 CvCapture *capture srcImage = cvQueryFrame(capture); Bitmap^ bmpPicBox = gcnew Bitmap(pictureBox->Width, pictureBox->Height); pictureBox->Image = bmpPicBox; Graphics^g = Graphics::FromImage(pictureBox->Image); Bitmap^ bmp = gcnew Bitmap(pictureBox->Width, pictureBox->Height, srcImage->widthStep,System::Drawing::Imaging::PixelFormat::Format24bppRgb, IntPtr(srcImage->imageData)); g->DrawImage(bmp, 0, 0, srcImage->width , srcImage->height); どのようにすれば,画像をpictureBoxにぴったりと表示させることができるでしょうか?

  • pictureBoxの画像の座標の色の出し方。

    VC++で、pictureBoxで表示した画像を適当な場所をクリックするとその座標とRGBの色あいが表示するプログラムなんですが、エラーはしなかったんですが、デバックして画像表示して適当にクリックしてもなにも表示されませんでした。 プログラムに間違えでもあるのかみてください。 private: System::Void pictureBox1_MouseDown(System::Object^sender, System::Windows::Forms::MouseEventArgs^ e) { String^fname = openFileDialog1->FileName; Bitmap^fun = gcnew Bitmap(fname); Point^ p = PointToClient( Point(e->X ,e->Y)); Color^col = fun->GetPixel(p->X,p->Y); label1->Text = String::Format("..{0}", fun->GetPixel(p->X,p->Y)); }

  • 画像の取り込みについてですが

    プログラミングの初心者ですが、現在VC++2005でプログラムについて勉強しています。画像の取り込みを行うところで、わからなくなってしまったので、みなさんのご指導お願いいたします。 今、行いたいのは あるフォルダAの中に100枚の画像の中の何枚かに対し連続的に処理することです。この100枚の画像の名前は1から100までの番号です。例えば、50枚目から70枚目の20枚の画像に対して、二値化を行って、結果を保存したいです。保存する時の画像名前は元の番号に100を足して、(例:50+100=150)そうすると、元は何番なのかがわかります。 ここで、この50番から連続の20枚の画像をfor文で実現しようとしています。しかしながら、連続に取り込む方法がよくわからなくて困っています。 Bitmap^ bmap=gcnew Bitmap("C¥A"); ここでフォルダを指定します。 for(n=0;n<=20;n++){ ここから20枚の画像を処理する /ここで一番最初の50番の画像を取り込みます/(やり方がわからないです) /二値化処理をします/ /保存します(保存の仕方がわからないです)/ /取り込んだ50番をn足して次の51番になります(やり方がわからないです)。for文に戻り、続けて処理を行う/ } もしかして根本的な考え方も間違っているかもしれませんが、ご指導をいただければ感謝致します。 どうぞよろしくお願い致します。

  • プログラムへの画像埋め込み(?

    Visual C++でカレンダーを作っています 前後矢印のボタンを押せば、カレンダーがそれぞれ前後の月に移動し それに伴いカレンダー脇に表示される画像も変更される、 というプログラムなのですが、デバッグではキチンと動くのに いざアプリケーション単体では動作しません。 素人ながら思うには、プログラム中では private: void Hyouji(System::Object^ sender, System::EventArgs^ e) { DateTime tm=DateTime(myYear,myMonth,1); String^ FileName="Gazou/"+filename[myMonth-1]+".jpg"; monthCalendar1->SelectionStart=tm; monthCalendar1->SelectionEnd=tm; pictureBox1->Image=gcnew Bitmap(FileName); this->Invalidate(); } として、Gazouフォルダ内の画像を参照しているから起動しているのであって アプリケーション単体ではそれができていないのだと思うのですが、 はたしてそれで合っていますでしょうか。 もしそうならば プログラム中に画像ファイルを埋め込むことができれば解決すると思うのですが、 それにはどうすれば良いか、ご教授願えますでしょうか よろしくお願いします

専門家に質問してみよう