• 検索結果がありません。

Microsoft PowerPoint - handout08.ppt

N/A
N/A
Protected

Academic year: 2021

シェア "Microsoft PowerPoint - handout08.ppt"

Copied!
6
0
0

読み込み中.... (全文を見る)

全文

(1)

応用プログラミング 第8回

~プログラミングの応用

画像処理入門1

電気通信大学電子工学専攻

Intelligent Electronic Systems Group

長井 隆行

本日の内容

1.

画像処理入門

~画像を知る~

1.

CCDカメラの仕組み

2.

グレースケール画像

3.

カラー画像

4.

画像ファイルのフォーマット

5.

画像の入出力

2.

課題3

FILE構造体とは?(前回の補足)

†

FILE構造体

„

操作するファイルの情報を格納する構造体

„

ファイルの情報とは現在読み書きしているファイルのアドレス(位置)など

†

直接この構造体にアクセスすることはあまりない

„

普通はfopenやfprintfなどで指定するだけ

†

以下は参考までにFILE構造体の例(コンパイラによって異なる)

typedef struct {

unsigned char *curp; /* Current active pointer */ unsigned char *buffer; /* Data transfer buffer */ int level; /* fill/empty level of buffer */ int bsize; /* Buffer size */ unsigned short istemp; /* Temporary file indicator */ unsigned short flags; /* File status flags */ wchar_t hold; /* Ungetc char if no buffer */ char fd; /* File descriptor */ unsigned char token; /* Used for validity checking */ } FILE; /* This is the FILE object */

いよいよ画像

†

白黒濃淡画像(グレースケール画像)

画素(ピクセル)

一般的には

8bit

0~255

の範囲

8bppなどと呼ぶ)

(2)

いよいよ画像 続き

†

カラー画像

画素(ピクセル)

一般的には24bit

RGBがそれぞれ

0~255

の範囲

24bppなどと呼ぶ)

メモリ上ではどうなってるの?

†

2次元の情報である画像をどのようにメモリ(1次元の配列)に収めるか?

0x0a

0x09

0x08

0x07

0x06

0x05

0x04

0x03

0x02

0x01

0x00

value

add

どのように並べるかは基本的にプログラマの自由

画面へ表示するためには、いくつか約束事がある

ファイルに保存する場合も決まったやり方がある(フォーマット)

255 50 10 20 0 100 255 150 200 255 50 10 20 0 100 255 150 200

必ずしもこの順番である必要はない

カラー画像の場合は?

†

一般に

24bppとは各画素が0~

16777216の値をもっているのではなく

R(赤)、G(緑)、B(青)がそれぞれ0~

255(8bit)の値をもっている

8×3 = 24(bit)

255

B

0

G

0

R

200

B

100

G

20

R

0

B

255

G

0

R

0

B

0

G

255

R

画像ファイルのフォーマット

†

画像が成立するための必要な情報

†

画像データ本体 ⇒ 当然必要

†

計64枚のタイルを渡されて「これ並べて」と命令されても

のように並べればいいか

分からない

†

画像のサイズ

†

どんな順番で並んでいるか

†

カラーかグレースケールか(1ピクセルのビット数)

†

などなど・・・

ヘッダ情報

画像データ

(3)

画像ファイルのフォーマット 続き

†

画像の表現の仕方は色々あり得る

†

みんなが使えるように画像の表現方法の約束を決める

†

「ヘッダ情報や画像データをどのように記録しておくか」に関

する取り決め

†

ビットマップ

(.bmp)

windowsで標準

†

Jpeg (.jpg)

圧縮画像の標準形式

†

TIFF (.tif)

DTPなどでよく使用される

†

GIF (.gif)

インターネットでよく使用される(256色)

†

ポータブルグレーマップ

(.pgm)

Xwindow(Unix)でよく

使われる

.pgm(ポータブルグレーマップ)

†

グレースケール画像に対する最もシンプルな画像ファイル

フォーマット

†

PGM P5 フォーマット (グレースケール、バイナリ)

P5 320 240 255 rrtuvwxxz|{}~~ =cту㊧・・演糾給血麹克諮瑞荘葬涛湯粕 燈末楓迄劍劍履囹囮囹尹屆屁惧撼撼棍沺棍。「。。。「。。。。「「」 「「「「「」」」、、・・ヲ・、・ヲヲ・ヲヲ・ヲヲァヲヲヲァァァァ ヲィァァィァァィィァゥィゥィゥゥィィィゥェィィィゥェィィゥィゥゥィィゥゥェェェゥゥゥォォォォォォォゥゥゥェゥゥェゥゥェゥ ェィェゥィゥゥィゥゥィィゥィァ・ヲィヲァァィィァィァィヲヲァヲヲヲァヲ・ヲヲ、ヲ、・、・、、」「」、、、「」」「。・ pgm (P5)をテキストエディタで強引に開いたもの ・・・ずっと続く

ヘッダ

バイナリ画像データ 1バイト/1画素 ファイル識別子 画像の横幅 縦幅 最大階調値

.bmp(ビットマップ)

†

Windowsでは標準のビットマップ

†

PGMより複雑(基本的な考え方は同じ)

ヘッダ情報(バイナリ) 画像データ(バイナリ) BGRBGRBGR ・・・ BGR BITMAPFILEHEADER (ファイルヘッダ) BITMAPINFOHEADER (情報ヘッダ) 2byte ファイルのタイプ "BM" 4byte ファイルのサイズ(byte) 2byte 予約1 0 2byte 予約2 0 4byte BITMAPFILEHEADERから実際の ビットマップデータまで のオフセット値 ヘッダーのサイズと考えてよい(byte) 4byte 情報ヘッダのサイズ 40 4byte 画像の幅(画素数) 4byte 画像の高さ(画素数) 4byte 圧縮形式 0:無圧縮 2byte プレーンの数 1 2byte 1画素のビット数(bpp) 4byte 画像データのサイズ(byte) 4byte 横方向解像度 4byte 縦方向解像度 4byte パレット数 4byte 重要なパレットのインデックス

14byte 40byte byte数は画像サイズによる

画像処理するために

†

本講義での流れ

撮影 (デジカメ) PCへ転送 (ハードディスク) 自らのプログラムで 画像ファイルを読み込む (メモリ) 自らのプログラムで メモリ上の画像データを処理 (メモリ) 自らのプログラムで メモリ上の画像データを ファイルに書き出す (ハードディスク) 画像データをviewerで開き 結果を確認 入力 出力 画像処理

(4)

この講義における画像処理

Step1 まず画像を用意する(bmpやjpg)

Step2 既存のソフト(paint,xvなど)を使ってbmp形式に変換す

る(もともとビットマップであれば変換の必要ないが、以下の条

件を満たしていない場合はやはり変換が必要)

*画像の幅が

4の倍数

である

*1ピクセルが24ビット(24bpp)

また、画像を処理して保存する際もこれらの条件が満たされな

くてはいけない

Step3 p8-1.cに画像処理部分を追加する

Step4 既存のソフト(paint,xvなど)を使って保存した画像を開く

プログラムで画像を扱う

†

p8-1.cの使い方

†

p8-1forInt.cとp8-1forMot.cがある

†

CPUの違いで使い分ける必要がある

†

使っているCPUがインテル系である

(windows、Linuxの人はこちらだと思ってよい)

p8-1forInt.c

†

使っているCPUがモトローラ系である

(Mac、Solaris(sun)の人はこちらだと思ってよい:大学の情

報処理センターで行う人はこっち)

p8-1forMot.c

プログラムで画像を扱う 続き

† 処理はbuffer上で行うか、out_bufferにデータをコピーしてout_buffer上で行う † もしくは、新たな画像用配列を宣言して使用してもよい † 但し、書き込みの際は必ずout_bufferに結果の画像データが存在する必要がある buffer buffer[3*width(height-1)] buffer[3*width*height-1] buffer[0] 3*Width buffer[3*width-1] height out_buffer width height ファイル名”result.bmp”で保存される B G R 1画素分のデータ(BGR) BG R buffer[0] buffer[1] buffer[2] ・ ・ buffer[3*width-1] buffer[3*width] buffer[3*width(height-1)] buffer[3*width*height-1] ・ ・ ・ ・ ・ ・

ビットマップの読み込み部 (p8-1.c)

/*メイン関数*/ int main(void) {

int size, width, height; FILE *fp = NULL;

unsigned char *buffer; /*入力画像用メモリのポインタ*/ unsigned char *out_buffer; /*出力画像用メモリのポインタ*/

BITMAPFILEHEADER bmfh; BITMAPINFOHEADER bmih; /*ファイルを開く*/ fp = fopen( "bitmap.bmp" , "rb" ); /*ビットマップのヘッダーを読み込む*/ /*構造体のメンバはメモリ上に定義順に確保されていることに注目*/

fread( &bmfh , sizeof(BITMAPFILEHEADER) , 1 , fp ); fread( &bmih , sizeof(BITMAPINFOHEADER) , 1 , fp );

/*使いやすいように画像の幅と高さをコピーする*/ width = bmih.biWidth;

height = bmih.biHeight;

size = width * height; /*ビットマップのサイズを算出*/ buffer = (unsigned char*)malloc( 3*size ); /*必要なサイズのメモリを確保*/

fread( buffer , 3*size , 1 , fp ); /*画像データ本体の読み込み*/ fclose( fp ); /*読み終わったのでファイルを閉じる*/

(5)

ビットマップのための構造体

p8-1.c

/*ビットマップファイルヘッダのための構造体定義*/ typedef struct tagBITMAPFILEHEADER {

unsigned short bfType; unsigned long bfSize; unsigned short bfReserved1; unsigned short bfReserved2; unsigned long bfOffBits; } BITMAPFILEHEADER;

/*ビットマップインフォヘッダのための構造体定義*/ typedef struct tagBITMAPINFOHEADER{

unsigned long biSize; long biWidth; long biHeight; unsigned short biPlanes; unsigned short biBitCount; unsigned long biCompression; unsigned long biSizeImage; long biXPixPerMeter; long biYPixPerMeter; unsigned long biClrUsed; unsigned long biClrImporant; } BITMAPINFOHEADER; 画像情報のための構造体を定義 •windows.hをインクルードできれば、 その中に定義されているので自分で する必要はない

関数

freadによる読み込み

fread関数を使って、ファイルから

バイナリデータ

を直接読み込む

fread( &bmfh , sizeof(BITMAPFILEHEADER) , 1 , fp );

fread( &bmih , sizeof(BITMAPINFOHEADER) , 1 , fp );

ポイントは、構造体を直接読み込んでいること

メンバごとに読み込む必要がない⇒

メンバがメモリ上に順番に並んでいるため

fread( buffer , 3*size , 1 , fp );

画像データも直接読み込んでいる

fread(コピー先のポインタ, 何バイト読むか, 何個読むか, ファイルポインタ);

14バイト読んだ 次に40バイト読む 今ファイルのどこまで読んだかが ファイルポインタfpに記録されている

ビットマップの読み込み

メモリ HD fread( &bmfh , sizeof(BITMAPFILEHEADER) , 1 , fp );

fp

ファイルの先頭 ファイルの最後

fread( &bmih , sizeof(BITMAPINFOHEADER) , 1 , fp );

fp

fread( buffer , 3*size , 1 , fp );

fp bmfhの先頭 bmihの先頭 buffer[0]の先頭 fp fp fp

構造体の直接読み込み

メモリ HD fread( &bmfh , sizeof(BITMAPFILEHEADER) , 1 , fp );

fp ファイルの最後 bmfhの先頭 2byte ファイルのタイプ "BM" 4byte ファイルのサイズ(byte) 2byte 予約1 0 2byte 予約2 0 4byte BITMAPFILEHEADERから実際の ビットマップデータまで のオフセット値 ヘッダーのサイズと考えてよい(byte) bfType bfSize bfReserved1 bfReserved2 bfOffBits

(6)

ビットマップの出力部 (

p8-1.c)

/*書き込み処理*/ /*結果をファイルに書くためには、out_bufferに結果をしまう必要がある*/ fp = fopen( "result.bmp" , "wb" ); /*ファイルを書き込み用で開く*/ /*画像の情報を作成する(画像処理によって変わる可能性があるものだけ作成)*/ /*出力画像のwidth、heightが変更されていればそれを書き込む*/

bmfh.bfSize = width*height*3 + BMP_HEADER_SIZE; bmih.biWidth = width;

bmih.biHeight = height; /*ビットマップを書き込む*/

fwrite( &bmfh , sizeof(BITMAPFILEHEADER) , 1 , fp ); fwrite( &bmih , sizeof(BITMAPINFOHEADER) , 1 , fp ); fwrite( out_buffer , 3*size , 1 , fp );

fclose( fp ); /*ファイルを閉じる*/ /*メモリを解放する*/ free( buffer ); free( out_buffer ); return 0; }

関数

fwriteによる書き出し

†

出力はまさに入力の逆

fwrite関数を使ってバイナリデータを直接ファイルに書き込む

fwrite( &bmfh , sizeof(BITMAPFILEHEADER) , 1 , fp );

fwrite( &bmih , sizeof(BITMAPINFOHEADER) , 1 , fp );

fwrite( out_buffer , 3*size , 1 , fp );

14バイト分書き込んだ後に 40バイト分書き込み その後に 画像サイズ分書き込む

まずは以下をやってみよう

†

これは課題ではないので提出する必要ありませんがまず試

すことをお勧めします

†

好きなビットマップ画像を用意する(24ビットカラー)

†

画像の幅が4の倍数以上のものは、画像ソフトで4の倍数に

なるように切り取る

†

p8-1.cをコンパイルし実行する

†

実行すると新たなビットマップ画像ができるはず

†

保存したファイルを画像ソフトで開き、入力した画像と全く同

じであれば成功

†

p8-1.cを眺めてみる

参照

関連したドキュメント

回転に対応したアプリを表示中に本機の向きを変えると、 が表 示されます。 をタップすると、縦画面/横画面に切り替わりま

Instagram 等 Flickr 以外にも多くの画像共有サイトがあるにも 関わらず, Flickr を利用する研究が多いことには, 大きく分けて 2

画像の参照時に ACDSee Pro によってファイルがカタログ化され、ファイル プロパティと メタデータが自動的に ACDSee

ヒュームがこのような表現をとるのは当然の ことながら、「人間は理性によって感情を支配

我々は何故、このようなタイプの行き方をする 人を高貴な人とみなさないのだろうか。利害得

・本計画は都市計画に関する基本的な方 針を定めるもので、各事業の具体的な

撮影画像(4月12日18時頃撮影) 画像処理後画像 モックアップ試験による映像 CRDレール

 次に、羽の模様も見てみますと、これは粒粒で丸い 模様 (図 3-1) があり、ここには三重の円 (図 3-2) が あります。またここは、 斜めの線