C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[8]: 読み込んだ画像からRGB値を配列に


(過去ログ 134 を表示中)

[トピック内 11 記事 (1 - 11 表示)]  << 0 >>

■79243 / inTopicNo.1)  読み込んだ画像からRGB値を配列に
  
□投稿者/ 画像プログラム初心者 (1回)-(2016/03/18(Fri) 09:32:46)

分類:[C#] 

初心者で申し訳ございません。

ボタン(button5)を押すと画像を読み込めるようにしてます。

読み込んだ画像をpictureBox5に表示。(下記プログラム内容)


private void button5_Click(object sender, EventArgs e)
{
OpenFileDialog dialog = new OpenFileDialog();
dialog.FileName = "image.bmp";
dialog.InitialDirectory = @"C:\";

if (dialog.ShowDialog() != DialogResult.OK)
{
return;
}

try
{
pictureBox5.Image = Image.FromFile(dialog.FileName);

return;
}
catch (Exception ex)
{
MessageBox.Show("ex");
}


ここからやりたいことですが、読み込んだ画像を各ピクセル座標ごとのRGB値を

取得して、配列に落としたいと思っています。

たとえば、縦a 横b の画像の各座標a,b のR値を 配列値 C[1,1] に入れ込みたい。



Bitmap test = new Bitmap(a, b, PixelFormat.Format32bppArgb);

test = (Bitmap)pictureBox5.Image;


for (int b = 0; b < pictureBox5.Height; b++)
{
for (int a = 0; a < pictureBox5.Width; a++)
{
int C[a,b] = test.GetPixel(a,b).ToArgb();  的な・・・

}
}



わかるかたいましたら教えてください。

お願いします。


引用返信 編集キー/
■79244 / inTopicNo.2)  Re[1]: 読み込んだ画像からRGB値を配列に
□投稿者/ kiku (89回)-(2016/03/18(Fri) 09:58:58)
下記、2つの情報から解決できると思います。
調べてみてください。

配列の宣言と利用方法
https://msdn.microsoft.com/ja-jp/library/2yd9wwz4.aspx

GetPixeが返すColor構造体のメンバー
https://msdn.microsoft.com/ja-jp/library/system.drawing.color(v=vs.110).aspx
引用返信 編集キー/
■79248 / inTopicNo.3)  Re[2]: 読み込んだ画像からRGB値を配列に
□投稿者/ 画像プログラム初心者 (2回)-(2016/03/18(Fri) 12:50:47)
No79244 (kiku さん) に返信
> 下記、2つの情報から解決できると思います。
> 調べてみてください。
>
> 配列の宣言と利用方法
> https://msdn.microsoft.com/ja-jp/library/2yd9wwz4.aspx
>
> GetPixeが返すColor構造体のメンバー
> https://msdn.microsoft.com/ja-jp/library/system.drawing.color(v=vs.110).aspx


返信有難う御座います。

とりあえず各座標のRGB値を取得して、

そのRBG値が FFFFFFFF の場合は 1 を返す。 それ以外なら 0 みたいなことをやる場合はどうしたらよいでしょう?


for (int b = 0; b < pictureBox5.Height; b++)
{
for (int a = 0; a < pictureBox5.Width; a++)
{
int P = test.GetPixel(a, b).ToArgb();

if (P = FFFFFFFF)
{
data[a, b] = 1;

}
else
{
data[a,b]= 0;
}

}

}
引用返信 編集キー/
■79249 / inTopicNo.4)  Re[3]: 読み込んだ画像からRGB値を配列に
□投稿者/ 魔界の仮面弁士 (670回)-(2016/03/18(Fri) 13:23:35)
No79248 (画像プログラム初心者 さん) に返信
> そのRBG値が FFFFFFFF の場合は 1 を返す。

RBG値ですか?
RGB値でも
ARGB値でもなく?


FFFFFFFF の 8桁のようなので、それが ARGB の書き間違いだとすれば、
> if (P = FFFFFFFF)
の部分を
 if (P == 0xFFFFFFFF)
にすれば良いと思います。


ただ、GetPixel はそれほど高速な処理ではありません。
画像サイズが大きい場合は、LockBits を使った方が素早く走査できます。

とはいえ、処理コード的には、GetPixel の方が簡単に書けますので、
要件に応じて使い分けてみてください。


> それ以外なら 0 みたいなことをやる場合はどうしたらよいでしょう?
これが、白黒の2値化画像にしたいという意味だとしたら、こういった処理もできます。
http://dobon.net/vb/dotnet/graphics/1bpp.html

また、グレースケール化だとしたらこんな感じ。
http://dobon.net/vb/dotnet/graphics/grayscale.html
引用返信 編集キー/
■79402 / inTopicNo.5)  Re[4]: 読み込んだ画像からRGB値を配列に
□投稿者/ 画像プログラム初心者 (3回)-(2016/03/30(Wed) 18:56:57)
魔界の仮面弁士さん、返信有難う御座います。お礼が遅れて申し訳御座いません。

またまた質問になってしまいますが、、、

読み込んだ画像の各座標ごとのR値を取得。R値が130以下の場合は各座標に対応した

2次元配列 data[a,b] の値を 1 に。 130以上の場合は 2 を返す、

としたい場合はこのような感じでしょうか、、、 なかなかうまくいきません。



Bitmap test = new Bitmap(a, b, PixelFormat.Format32bppArgb);

test = (Bitmap)pictureBox1.Image;

for (int b = 0; b < pictureBox1.Height; b++)
{
for (int a = 0; a < pictureBox1.Width; a++)
{

int P = test.GetPixel(a, b).R;

if (P < 130)
{
data[a, b] = 1;
}

else
{
data[a,b]= 2;
}

真っ黒の画像読み込んでも、真っ白の画像読み込んでも、

data[a,b]の値が反応しません、、、なぜかずっと0を返し続けてます、、、


label1.Text = "0,0: " + Data[0,0] + " ";
label2.Text = "180,180: " + Data[180, 180] + " ";

引用返信 編集キー/
■79404 / inTopicNo.6)  Re[5]: 読み込んだ画像からRGB値を配列に
□投稿者/ Azulean (623回)-(2016/03/30(Wed) 22:53:40)
No79402 (画像プログラム初心者 さん) に返信
> としたい場合はこのような感じでしょうか、、、 なかなかうまくいきません。

コンパイルエラーで前のコードで実行されているのでは?
a と b を定義する前に new Bitmap で使っているし、仮に a と b を前もって定義していたとすると、for ループのところで二重定義のエラーになります。
また、test の変数を書き換えてしまっているなど、意図したコードが実行されているか怪しい感じがします。
引用返信 編集キー/
■79413 / inTopicNo.7)  Re[6]: 読み込んだ画像からRGB値を配列に
□投稿者/ Jitta (187回)-(2016/03/31(Thu) 19:06:08)
Dataとdata
C#では異なる。
引用返信 編集キー/
■79414 / inTopicNo.8)  Re[6]: 読み込んだ画像からRGB値を配列に
□投稿者/ 画像プログラム初心者 (4回)-(2016/03/31(Thu) 19:38:56)
Azuleanさん、返信有難う御座います。

新しくプロジェクトを作って確かめてみました。

新しいフォームに button1、pictureBox1、label1、を設置しまして、

コードを下記のように。

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;

namespace WindowsFormsApplication14
{
public partial class Form1 : Form
{
public int a, b;
public int[,] data = new int[360, 360];

public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{

}

private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog dialog = new OpenFileDialog();
dialog.FileName = "image.bmp";
dialog.InitialDirectory = @"C:\";

if (dialog.ShowDialog() != DialogResult.OK)
{
return;
}

try
{
pictureBox1.Image = Image.FromFile(dialog.FileName);
return;
}
catch (Exception ex)
{
MessageBox.Show("ex");
}


Bitmap test = new Bitmap(a, b, PixelFormat.Format32bppArgb);
test = (Bitmap)pictureBox1.Image;

for (int b = 0; b < pictureBox1.Height; b++)
{
for (int a = 0; a < pictureBox1.Width; a++)
{
int P = (byte)(test.GetPixel(a, b).R);

if(P<130)
{
data[a, b] = 1;
}
else
{
data[a, b] = 2;
}

}
}
label1.Text = "" + data[0, 0];
Refresh();
}
}
}

画像をLoadしてもlabe1.Textの値に変化がないので根本的に間違っている気はするのですが、、、
引用返信 編集キー/
■79416 / inTopicNo.9)  Re[7]: 読み込んだ画像からRGB値を配列に
□投稿者/ 魔界の仮面弁士 (678回)-(2016/03/31(Thu) 20:04:05)
2016/03/31(Thu) 20:08:19 編集(投稿者)

コードを掲載する場合は、投稿モードを「図表モード」にして送信すると読みやすくなります。


No79414 (画像プログラム初心者 さん) に返信
> pictureBox1.Image = Image.FromFile(dialog.FileName);
この方法でも良いですが、その場合、この画面が閉じられるまで
ファイルが開かれたままになります。

画像がロックされないようにする場合、下記のようにすることができます。
http://dobon.net/vb/dotnet/graphics/drawpicture2.html


> Bitmap test = new Bitmap(a, b, PixelFormat.Format32bppArgb);
生成した Bitmap が Dispose されていないのが気になりますが、今回それは置いといて…。


上記では「new Bitmap(…);」を使って、Bitmap オブジェクトを
新たに作成していますが、折角生成したにもかかわらず、その直後の
> test = (Bitmap)pictureBox1.Image;
の行で、別の Bitmap オブジェクトを代入しているため、
new した Bitmap は一度も使用される事なく、
変数 test 内から放り出されてしまっています。

そしてこの変数 test は、先の Bitmap インスタンスの代わりに、
既にロード済みの pictureBox1.Image を参照するようになっています。


であれば、最初に new Bitmap などせずとも、最初から
 Bitmap test = (Bitmap)pictureBox1.Image;
で良いわけですし、そもそも表示も不要なら、PictureBox も使わずに
 Bitmap test = (Bitmap)Image.FromFile(dialog.FileName);
で済みますよ。


> for (int b = 0; b < pictureBox1.Height; b++)
> for (int a = 0; a < pictureBox1.Width; a++)

変数名を付けるときは、「a」「b」ではなく、
height、width といった変数名にしておくと
コードが読みやすくなります。

短い変数名がお好みなら、
x、y (横方向、縦方向 の意味) や
h、w (width、height の意味) が良いかも。


> int P = (byte)(test.GetPixel(a, b).R);

代入式の左辺は int なので、なんだか違和感が…。(^^;


まぁ、文法的には間違ってはいませんが、
「(byte)」でキャストせずとも、
R プロパティは最初から byte 型ですよ。


> label1.Text = "" + data[0, 0];
ループで data[,] の中身を書き換えていますが、
label1 に表示するのは、左上の data[0,0] だけですが、
それで良いのですね?


> 画像をLoadしてもlabe1.Textの値に変化がないので根本的に間違っている気はするのですが、、、
ちなみに、その画像の (0, 0) 座標にある色は、
RGB 値でいうと幾つの値なのでしょうか?
引用返信 編集キー/
■79422 / inTopicNo.10)  Re[7]: 読み込んだ画像からRGB値を配列に
□投稿者/ 画像プログラム初心者 (5回)-(2016/04/01(Fri) 08:47:19)
魔界の仮面弁士さん、回答有難う御座います。
いろいろ教えてくれて大変助かります。

> コードを掲載する場合は、投稿モードを「図表モード」にして送信すると読みやすくなります。
了解しました。次回よりソース貼る場合は図表モードに致します。


> label1.Text = "" + data[0, 0];
> ループで data[,] の中身を書き換えていますが、
> label1 に表示するのは、左上の data[0,0] だけですが、
> それで良いのですね?
将来的には、画像の左上から右下まで全ての座標でのピクセルデータを取得して
data[X座標,Y座標] の値を白い部分は 1 を、黒い部分は 2 を返すようにしたいです。
とりあえず、今はプログラムがきちんと動作しているのを確認するために
左上のdata[0,0]の値がちゃんとできているか?を確認することを試みています。

label1 の値が画像を読み込んでも数値が入らず、label1 の表示がずっとlabel になってしまっていますが、、、


> ちなみに、その画像の (0, 0) 座標にある色は、
> RGB 値でいうと幾つの値なのでしょうか?
全面、黒い画像を読み込んでいるので 255 だと思うのですが、、、
とりあえずRGBの値を表示するプログラムからスタートしたほうがいいですかね。


引用返信 編集キー/
■79423 / inTopicNo.11)  Re[8]: 読み込んだ画像からRGB値を配列に
□投稿者/ 魔界の仮面弁士 (679回)-(2016/04/01(Fri) 09:29:46)
No79422 (画像プログラム初心者 さん) に返信
> とりあえず、今はプログラムがきちんと動作しているのを確認するために
少なくとも、期待した動作にはなっていないでしょうね…。


> 左上のdata[0,0]の値がちゃんとできているか?を確認することを試みています。
そもそも、「label1.Text = "" + data[0, 0];」の行に到達していませんよね。
その事に気づいているか、あるいはその理由に気づけているか。


> try
> {
>    pictureBox1.Image = Image.FromFile(dialog.FileName);
>    return;
> }
> catch (Exception ex)
> {
>    MessageBox.Show("ex");
> }

画像をロードした時点で、直ちに return していますよね。
この時点で button1_Click の処理は抜けるので、そもそも
ループ処理までたどりついてはいません。

ループに到達するのは、画像のロードが失敗したときに限られますが、
その場合、変数 test に入るのは、OpenFileDialog で指定されたファイルではなく
その直前に表示していた Bitmap です。

しかも、ロード失敗時に通過する catch 句にしても、
変数 ex の内容を表示するのではなく、
文字列 "ex" を表示するコードになっているので、
いずれにせよ期待する結果では無いでしょう。


ついでに言うと、
> for (int b = 0; b < pictureBox1.Height; b++)
ループ中に利用している変数「a」「b」は、
フィールド変数として宣言された「a」「b」とは別物です。
> public int a, b;



> 全面、黒い画像を読み込んでいるので 255 だと思うのですが、、、
そこも間違えていますよ。

label1.Text = Color.Black.R.ToString();
label2.Text = Color.White.R.ToString();
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -