0~255のランダムデータをPGM画像として表示させる方法

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
lvparisvl

0~255のランダムデータをPGM画像として表示させる方法

#1

投稿記事 by lvparisvl » 9年前

以前、トピックを立てたのですが、気付くとCLOSEしていたので、もう一度、御指導を宜しくお願い致します。
***********************************************
プログラム開発環境はWindowsXPでVisualStudioC++2008を利用して行っています。
開発言語は、C言語です。(私のC言語のレベルは、本を1冊終わった程度です。C++は、全くわかりません。)

最終的な目標は既存のバイナリデータ(1ピクセル1バイトRAWデータ)をSEEK等で任意個のピクセルを間引きして画像として表示させるプログラムを作成したいと思っています。
その途中の段階で、間引いたデータを直接画像として表示するプログラムを作成したいのですが、どのように作成すれば良いかわかりません。
現状は、間引いたデータを一度PGMファイルとして書き出し、そのファイルを再び読込んで表示するプログラムなら完成したのですが、書き込み等のせいで処理時間がかかります。
そこで、ファイルとして書き出さずに画像表示できるプログラムを教えてください。
(配列に格納されているデータをPGM画像として表示する方法が分かれば、この問題は解決すると思われます。)

** ”データ配列をBMP画像表示する” 様な質問は見かけるのですが、PGM画像表示のものは、探してみましたがみつかりませんでした。
PGMにこだわる理由は、BMPのような画像データの前に格納されているファイルヘッダやパレットが必要ないぶん、作成が簡単かと思ったからです。
もし、BMPのほうが簡単だと思われる場合、BMPで作成する方法を教えてください。
プログラムの流れとしては、
ファイルオープン→間引いたバイナリデータを配列に順に格納→画像表示→ファイルクローズ
でいけると思うのですが・・・

御指導宜しくお願い致します。

アバター
asd
記事: 318
登録日時: 9年前

Re: 0~255のランダムデータをPGM画像として表示させる方法

#2

投稿記事 by asd » 9年前

文面を見る限り、画像の描画方法が分からないものと思っていますが正しいでしょうか?

PGMフォーマットのデータの読み書きが出来ているならば、あとは描画領域を用意してあげて
そこにデータどおりのピクセルを描画すればよいのかなと思います。
(以下のページではピクセルの描画方法がないので、直線などを短く引くことでピクセルに見せかける必要があるかと思います)

お門違いな助言になっているかもしれませんが、描画については以下のページが参考になりませんか?
http://www-higashi.ist.osaka-u.ac.jp/~k ... index.html

蛇足ですがPGM画像の扱いについても。
http://www.mm2d.net/c/c-10.shtml
Advanced Supporting Developer
無理やりこじつけ(ぉ

アバター
あたっしゅ
記事: 261
登録日時: 9年前
住所: 東京23区
連絡を取る:

Re: 0~255のランダムデータをPGM画像として表示させる方法

#3

投稿記事 by あたっしゅ » 9年前

前にも書きましたが、お答えがありません。

PGM の表示プログラムは、自分でお書きになったのですか ?
それとも、なんかのライブラリを呼んだだけですか ?
手提鞄あたっしゅ、[MrAtassyu] http://ameblo.jp/mratassyu/
手提鞄屋魚有店(てさげかばんやうおありてん)
レスがついていないものを優先して、レスしています。時々、見当外れなレスをします。

lvparisvl

Re: 0~255のランダムデータをPGM画像として表示させる方法

#4

投稿記事 by lvparisvl » 9年前

asd様
コメントありがとうございます。
教えて頂いたURLを参考に、現在奮闘しております・・・
が、おっしゃっておられる、”直線などを短く引くことでピクセルに見せかける必要があるかと思います”というのが、よく理解できないのですが、
LineToで短い線を引いて、その線の色を白~黒の間のグレースケール256色で描くということだと、勝手に理解したのですが、これって、可能なのでしょうか?
御返答を宜しくお願い致します。

あたっしゅ様
コメントありがとうございます。
きちんと回答できておらず、もうしわけございません。
PGMの表示プログラムは、OpenCVのライブラリを利用しました。(本当は自分で書きたかったのですが、どう書けば良いかわからなかったもので・・・)

コード:

       // 画像の読み込み
       img = cvLoadImage(imgfile, CV_LOAD_IMAGE_GRAYSCALE);

       // 画像の表示
       cvNamedWindow ("image", CV_WINDOW_AUTOSIZE);
       cvShowImage ("image", img);
       cvWaitKey (0);
       cvDestroyWindow("image");
表示の部分は、上のとおりです。
宜しくお願いします。

アバター
あたっしゅ
記事: 261
登録日時: 9年前
住所: 東京23区
連絡を取る:

Re: 0~255のランダムデータをPGM画像として表示させる方法

#5

投稿記事 by あたっしゅ » 9年前

OpenCV は、よく知らないので、これを機にちょっと調べてみました。

http://ja.wikipedia.org/wiki/OpenCV OpenCV - Wikipedia(ja)
http://opencv.jp/ OpenCV.jp(ja)

なんか、ヴァーションによって、違いがあるようですね。OpenCV 2.2 が現在(2011年1月)の最新か ?

ところで、OpenCV は、ご自分でインストールされたんですか ?
手提鞄あたっしゅ、[MrAtassyu] http://ameblo.jp/mratassyu/
手提鞄屋魚有店(てさげかばんやうおありてん)
レスがついていないものを優先して、レスしています。時々、見当外れなレスをします。

lvparisvl

Re: 0~255のランダムデータをPGM画像として表示させる方法

#6

投稿記事 by lvparisvl » 9年前

あたっしゅ様

OpenCVは、自分でインストールをしました。バージョンは、2.1です。
できれば、OpenCVを使用せずに、Windowsプログラミングで表示できればと考えているのですが、
いかんせん時間が迫っているもので、OpenCVでもWindowsプログラミングでも、どちらでも表示できれば良いと考えております。

アバター
asd
記事: 318
登録日時: 9年前

Re: 0~255のランダムデータをPGM画像として表示させる方法

#7

投稿記事 by asd » 9年前

lvparisvl さんが書きました:asd様
コメントありがとうございます。
教えて頂いたURLを参考に、現在奮闘しております・・・
が、おっしゃっておられる、”直線などを短く引くことでピクセルに見せかける必要があるかと思います”というのが、よく理解できないのですが、
LineToで短い線を引いて、その線の色を白~黒の間のグレースケール256色で描くということだと、勝手に理解したのですが、これって、可能なのでしょうか?
御返答を宜しくお願い致します。
返答が遅くなってしまい申し訳ありませんです。
簡単な図にして説明すると、PGMデータは全て各ピクセル単位で記述されているため、
読み込んだピクセルデータがRGB値で(255,0,0),(0,255,0),(0,0,255)の繰り返しの場合はピクセルを以下のように出力する必要があると思います。
(■が1ピクセルの画素だと思ってください)


・・・

指定した色のピクセルを描画する命令があればそのまま描画すればよいのですが、少し調べた限りでは直線や文字、楕円を描画する命令しか見つけられなかったので、1ピクセルの直線を引くことでピクセルを描画したものとする必要があるのかなと思った次第です。

OpenCVを使用されているようですので、お門違いな助言になってしまった気がします。
なんだか混乱させてしまって申し訳ないです。
Advanced Supporting Developer
無理やりこじつけ(ぉ

アバター
Dixq (管理人)
管理人
記事: 1661
登録日時: 9年前
住所: 北海道札幌市
連絡を取る:

Re: 0~255のランダムデータをPGM画像として表示させる方法

#8

投稿記事 by Dixq (管理人) » 9年前

OpenCVを使っていいなら簡単ですよ。
ピクセルごとに描画するんじゃなくて、サーフェイスのピクセルデータを直接いじれば良いです。
・・と口で言っても解りにくいと思うのでサンプル書いてみました。

コード:

int CheckKey(){
	int c = cvWaitKey(100);
	if( c == '\x1b' )return 1;
	else return 0;
}

int main (){
	uchar r,g,b;
	IplImage *img1,*img2;
	CvSize size;
	int x,y;

	img1 = cvLoadImage( "sample.bmp" );

	size = cvGetSize( img1 );

	img2 = cvCreateImage( size, IPL_DEPTH_8U, 3);

	cvNamedWindow ("Conv_test", CV_WINDOW_AUTOSIZE);

	for( y=0; y<size.height; y++ ){
		for( x=0; x<size.width; x++ ){
			b = img1->imageData[img1->widthStep * y + x * 3];	
			g = img1->imageData[img1->widthStep * y + x * 3 + 1];
			r = img1->imageData[img1->widthStep * y + x * 3 + 2];
			img2->imageData[img2->widthStep * y + x * 3]	 = cvRound (b * 1.0);
			img2->imageData[img2->widthStep * y + x * 3 + 1] = cvRound (g * 0.5);
			img2->imageData[img2->widthStep * y + x * 3 + 2] = cvRound (r * 0.0);
		}
	}

	while ( !CheckKey() ) {
		cvShowImage ("Conv_test", img2);
	}

	cvSaveImage("test.bmp",img2);

	cvDestroyWindow ("Conv_test");
	cvReleaseImage( &img2 );
	cvReleaseImage( &img1 );
	return 0;
}
sample.bmpを読み込んで、赤要素を0、緑要素を半分、青要素をそのままにした画像を表示し続け、Escを押すとその画像をtest.bmpに保存して終了します。
ピクセルをいじりたいなら、2重for文の中をいじればいいでしょう。
OpenCVであればどんな拡張子でも関係無く使えてしまうので便利ですよね。

lvparisvl

Re: 0~255のランダムデータをPGM画像として表示させる方法

#9

投稿記事 by lvparisvl » 9年前

asd様

回答、ありがとうございます。
なるほど、理解いたしました!
ピクセルを描画する命令が無いので、直線に色をつけて代用ということですね。
一度、OpenCVのプログラムとは別に作成してみます。
ありがとうございました。

lvparisvl

Re: 0~255のランダムデータをPGM画像として表示させる方法

#10

投稿記事 by lvparisvl » 9年前

Dixq (管理人)様

ご回答いただき、ありがとうございます。
今回使用するデータはバイナリデータですので、記述していただいたプログラムの読み込み部分を
img = cvLoadImage(imgfile, CV_LOAD_IMAGE_GRAYSCALE);
で、画像を読み込んで、2重for文で画素をいじれば良いのは分かるのですが・・・

”元データを間引いて読み込み、間引かれたデータを表示する”のをどう記述していいか分かりません。
具体的に図示すると、
■□□□□■□□□□■□□□□■□□□□■□□□□■□□□□■□□□□■□□□□■□□□□■□□□□■□□□□■□□□□■□□□□■□□□□
■□□□□■□□□□■□□□□■□□□□■□□□□■□□□□■□□□□■□□□□■□□□□■□□□□■□□□□■□□□□■□□□□■□□□□
・・・
・・・
と並んでいるピクセルのデータを5こを1つに間引いて(■□□□□→■)
■■■■■■■■■■■■■■
■■■■■■■■■■■■■■
・・・
・・・
のような画像にして表示したいのです。
データはRBGとかではなく、1ピクセルに0~255の数値が入っているだけのものです。

ご返信、宜しくお願い致します。

アバター
asd
記事: 318
登録日時: 9年前

Re: 0~255のランダムデータをPGM画像として表示させる方法

#11

投稿記事 by asd » 9年前

lvparisvl さんが書きました:asd様

回答、ありがとうございます。
なるほど、理解いたしました!
ピクセルを描画する命令が無いので、直線に色をつけて代用ということですね。
一度、OpenCVのプログラムとは別に作成してみます。
ありがとうございました。
ご理解いただけたようでよかったです。

ちなみにOpenCVは門外漢なので見た感じのちょっとした助言ですが、
横方向のみの間引きになるのでイメージとしては横方向の縮小画像を作る感じしょうか。
また読み込むデータがグレースケールの場合、R,G,Bの全てに同じ値を設定すればグレースケール画像になりますよ。

なので読み込んだ画像をimg、間引き後のデータをimg2とすると、ロジックとしては、
  1. 間引き後のデータを入れるimg2を用意
  2. img2の(x,y)の画素(R,G,B全て同じ値)をimgの(x*5,y)から取得する
  3. img2が全て埋まったら画像を表示、保存する
こんな感じでしょうか。

実際に試せる環境がないので言葉での説明ですが^^;
回答がつかないようであれば実際に試せる環境を用意してサンプルでも書いてみようと思います。
#管理人様が先に回答を投稿してくださりそうですけど^^;;
Advanced Supporting Developer
無理やりこじつけ(ぉ

閉鎖

“C言語何でも質問掲示板” へ戻る