1 全体の流れ 画像ファイルを開き,画像データをメモリ上にロード メモリ上にロードした画像データに処理を加える 処理後のデータを出力ファイルに書き出す 画像データ用に確保したメモリを解放.

Slides:



Advertisements
Similar presentations
プログラミング演習Ⅱ 課題 4 第 2 週 画像ファイル (ppm) の読み書き 画像データ用のメモリ確保・解放 1.
Advertisements

プログラミング 関数編 情報科学科. プログラミングにあたって C 言語では、 main 内に処理を記述 1000 行になるような大きなプログラムでは、 プログラム全体が何をしているのかを把握 することが困難になる 他人が見ると非常に理解しにくい 作成者であっても時が経てば内容を忘れて、他 人が見た時と同じ状況になる.
画像情報処理 1 プログラミング課題 知的画像処理研究室 M2 大村 瑞穂. 目次 プログラミング課題の準備 – ファイルのダウンロード・解凍・コンパイル サンプルプログラムの説明 画像処理の方法 レポートに載せる画像について 例題と第 1 回レポート課題.
画像情報処理1 ~画像処理プログラミング~ 2015/05/01 知的画像処理研究室 M1 吉原寛樹
構造体変数 1234 x xyz A 普通の変数 ( ここでは座標値 ) 構造体変数 ( ここでは点を表す ) xyz B 14 y 5 z 点 A の x 座標 プログラム中では A.x 点 B の y 座標 プログラム中では B.y 例えば 「 3 次元空間で2点 A と B の 間に線分を引き・・・」
アルゴリズムとデータ構造 第2回 線形リスト(復習).
情報・知能工学系 山本一公 プログラミング演習Ⅱ 第5回 関数(1) 情報・知能工学系 山本一公
A B x y z 復習 構造体変数 普通の変数 x y z 構造体変数 x y z 箱のイメージ 引き出しのイメージ
情報基礎演習B 後半第5回 担当 岩村 TA 谷本君.
数理情報工学演習第一C プログラミング演習 (第3回 ) 2014/04/21
第12回新しい型と構造体.
第13回構造体.
データ構造とアルゴリズム 第10回 mallocとfree
第12回構造体.
画像ファイル(ppm)の読み書き 画像データ用のメモリ確保・解放
OSとコマンド OS:コンピュータを使うための基本プログラム コマンド:OS上で使用できる命令 OS本体であるカーネルの内部コマンド
記憶クラス 変数をどのような記憶領域に割り当てるかを指定するのが記憶クラス 記憶クラスには、自動変数、静的変数、外部変数などがある。
第8回 プログラミングⅡ 第8回
担当:青木義満 情報工学科 3年生対象 専門科目 システムプログラミング システムプログラミング プロセス間通信(パイプ) 担当:青木義満
プログラミング演習Ⅰ 課題2 10進数と2進数 2回目.
画像ファイル(ppm)の読み書き 画像データ用のメモリ確保・解放
10: ファイル入出力 C プログラミング入門 基幹2 (月4) Linux にログインし、以下の講義ページ を開いておくこと
補足説明.
関数の定義.
iioLoadFile()とiioMallocImageBuffer()の補足
Cプログラミング演習 第7回 メモリ内でのデータの配置.
iioLoadFile()とiioMallocImageBuffer()の補足
iioLoadFile()とiioMallocImageBuffer()の補足
プログラミング 4 記憶の割り付け.
プログラミング演習I 2003年6月25日(第10回) 木村巌.
画像処理プログラムの説明.
プログラミング演習I 2003年5月7日(第4回) 木村巌.
プログラミング入門2 第11回 情報工学科 篠埜 功.
同じ構造をした「引き出し」変数を構造体変数と呼ぶ
プログラミング演習Ⅱ 課題4第3週 画像処理 (1) ビット演算子.
プログラミング入門2 第11回 情報工学科 篠埜 功.
第7回 プログラミングⅡ 第7回
復習 前回の関数のまとめ(1) 関数はmain()関数または他の関数から呼び出されて実行される.
プログラミング言語論 第五回 理工学部 情報システム工学科 新田直也.
第11回 プログラミングⅡ 第11回
P n ポインタの基礎 5 q m 5 7 int* p; int 型の変数を指すポインタ int* q; int 型の変数を指すポインタ int n=5, m=7; int 型の変数 int array[3]; int* pArray[3]; p = &n; ポインタにアドレスを代入しているのでOK.
第4回 ファイル入出力方法.
フロントエンドとバックエンドのインターフェース
岩村雅一 知能情報工学演習I 第12回(C言語第6回) 岩村雅一
画像処理プログラミング 知的画像処理研究室 M2 小林 佳奈美.
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
プログラミング言語論 第六回 理工学部 情報システム工学科 新田直也.
B演習(言語処理系演習)第2回 田浦.
文字列へのポインタの配列 static char *lines[MAXLINES]; lines[0] NULL
情報基礎演習B 後半第2回 担当 岩村 TA 谷本君.
ファイルの読み込み, ファイルからのデータの取り出し, ファイルの書き出し
第5回 プログラミングⅡ 第5回
オブジェクト指向言語論 第五回 知能情報学部 新田直也.
C プログラミング入門 基幹7 (水5) 14: 発展事項
プログラミング演習Ⅱ 課題4第4週 画像処理 (2) 応用.
岩村雅一 知能情報工学演習I 第12回(後半第6回) 岩村雅一
全体の流れ 画像ファイルを開き,画像データをメモリ上にロード メモリ上にロードした画像データに処理を加える
プログラミング言語論 第九回 理工学部 情報システム工学科 新田直也.
オブジェクト指向言語論 第七回 知能情報学部 新田直也.
プログラミング言語論 第九回 理工学部 情報システム工学科 新田直也.
オブジェクト指向言語論 第七回 知能情報学部 新田直也.
プログラミング言語Ⅰ(実習を含む。), 計算機言語Ⅰ・計算機言語演習Ⅰ, 情報処理言語Ⅰ(実習を含む。)
14: 発展事項 C プログラミング入門 基幹2 (月4) Linux にログインし、以下の講義ページ を開いておくこと
プログラミング演習II 2003年11月19日(第6回) 木村巌.
プログラミング演習II 2003年12月10日(第7回) 木村巌.
マスク合成(のような処理) 出力画像 Out 入力画像1 In1 In1 In2 Out 入力画像2 In
左右反転と180度回転 [0][xsize – 1] [0][0] → i ↓ j [ysize – 1][xsize – 1]
岩村雅一 知能情報工学演習I 第7回(後半第1回) 岩村雅一
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
C プログラミング入門 総機1 (月1) 14: 発展事項
Presentation transcript:

1 全体の流れ 画像ファイルを開き,画像データをメモリ上にロード メモリ上にロードした画像データに処理を加える 処理後のデータを出力ファイルに書き出す 画像データ用に確保したメモリを解放

2 画像ファイル内での画素データのフォーマット データ構造 ~ 1 画素をどう表現するか~ typedef struct { unsigned char r; unsigned char g; unsigned char b; } PIXEL, *PPIXEL; 88 (136) B1 (177) E7 (231) 8A (138) B2 (178) E7 (231) … 1 画素あたり RGB 各 8 ビット 合計 3 バイト 88 B1 E7 PIXEL 構造体 r g b

3 画像ファイル内での画素データのフォーマット データ構造 ~ 1 画素をどう表現するか~ typedef struct { unsigned char r; unsigned char g; unsigned char b; } PIXEL, *PPIXEL; 88 (136) B1 (177) E7 (231) 8A (138) B2 (178) E7 (231) … 1 画素あたり RGB 各 8 ビット 合計 3 バイト 88 B1 E7 PIXEL 構造体 r g b PIXEL 構造体へのポインタ型. 名前は PPIXEL にするよ この構造体の型名は PIXEL にするよ

4 データ構造 ~画像データをどう表現するか~ typedef struct { int xsize; int ysize; int level; PPIXEL *pBuffer; } IMAGE; 画像ファイルのフォーマット ヘッダー ( 画像サイズ,最大輝度 ) 画像データ IMAGE 構造体 xsize ysize level pBuffer 画像データのサイズは,ヘッダ読み込み後 でないと分からない → 画像用のメモリは [ ] 88 (136) B1 (177) E7 (231)

5 データ構造 ~画像データをどう表現するか~ typedef struct { int xsize; int ysize; int level; PPIXEL *pBuffer; } IMAGE; 画像ファイルのフォーマット ヘッダー ( 画像サイズ,最大輝度 ) 画像データ 画像データのサイズは,ヘッダ読み込み後 でないと分からない → 画像用のメモリは 動的 に確保 IMAGE 構造体 xsize ysize level pBuffer PPIXEL へのポインタ = ( PIXEL へのポインタ)へのポイン タ 88 (136) B1 (177) E7 (231)

6 ポインタの配列 ~課題 2 の文字列のソートの復習~ strawberry\0 lines[0] lines[1] lines[2] watermelon\0 banana\0 lines[MAXLINES-1] char *lines[MAXLINES]; 文字列にあわせた長さ 定数 MAXLINES 個 ( )

7 ポインタの配列 ~画像バッファの確 保~ void iioMallocImageBuffer(IMAGE *pImage) xsize ysize level pBuffer ysize 個の [ ] の配列を確保 malloc(ysize * sizeof(PPIXEL)); xsize 個の [ ] の配列を確保 malloc(xsize * sizeof(PIXEL)); pImage

8 ポインタの配列 ~画像バッファの確 保~ void iioMallocImageBuffer(IMAGE *pImage) xsize ysize level pBuffer xsize 個の PIXEL の配列を確保 malloc(xsize * sizeof(PIXEL)); pImage ysize 個の PPIXEL の配列を確保 malloc(ysize * sizeof(PPIXEL));

9 モジュール設計 どういう機能を用意するか モジュールごとの独立性をどう高めるか メイン main.c 画像処理 img_proc.c img_proc.h 画像のファイル入出力 画像データ用メモリ確保と解放 img_io.c img_io.h

10 復習:コンパイラの動作 (1) コンパイラはソースファイルを [ ] // 呼び出される関数 double func(double d) { return 0.0; } // 呼び出し側関数 int caller(void) { f = func(4); // 関数呼び出し } func という関数は、 double を受 け取って double を返すんだ な・・ double を渡して double を返し てもらうようなコードを生成し よう・・ 4 は 4.0 に変換してから渡そ う・・・ 関数呼出部分をコンパイルす るときに、コンパイラは呼び 出される関数の引数の数・型、 戻り値の型を知っておく必要 がある

11 復習:コンパイラの動作 (1) コンパイラはソースファイルを上から下へ解釈し ていく // 呼び出される関数 double func(double d) { return 0.0; } // 呼び出し側関数 int caller(void) { f = func(4); // 関数呼び出し } func という関数は、 double を受 け取って double を返すんだ な・・ double を渡して double を返し てもらうようなコードを生成し よう・・ 4 は 4.0 に変換してから渡そ う・・・ 関数呼出部分をコンパイルす るときに、コンパイラは呼び 出される関数の引数の数・型、 戻り値の型を知っておく必要 がある

12 コンパイラの動作 (2) 関数記述位置の上下を逆にすると・・・ // 呼び出し側関数 int caller(void) { f = func(4); // 関数呼び出し } // 呼び出される関数 double func(double d) { return 0.0; } 正常にコンパイルできない ( C 処理系では warning が、 C++ 処理系ではエラーが発 生する)

13 コンパイラの動作 (2) 関数記述位置の上下を逆にすると・・・ // 呼び出し側関数 int caller(void) { f = func(4); // 関数呼び出し } // 呼び出される関数 double func(double d) { return 0.0; } func 関数の引数の型も 引数の個数も知らないぞ・・・ 正常にコンパイルできない ( C 処理系では warning が、 C++ 処理系ではエラーが発 生する)

14 関数プロトタイプ宣言 double func(double d); // 呼び出し側関数 int caller(void) { f = func(4); // 関数呼び出し } // 呼び出される関数 double func(double d) { return 0.0; } 関数呼出部分より前に [ ] を行うことにより、正常にコン パイルが可能となる func という関数は、 double を受 け取って double を返すんだ な・・ double を渡して double を返し てもらうようなコードを生成し よう・・ 4 は 4.0 に変換してから渡そ う・・・

15 関数プロトタイプ宣言 double func(double d); // 呼び出し側関数 int caller(void) { f = func(4); // 関数呼び出し } // 呼び出される関数 double func(double d) { return 0.0; } 関数呼出部分より前に プロトタイプ宣 言 を行うことにより、正常にコン パイルが可能となる func という関数は、 double を受 け取って double を返すんだ な・・ double を渡して double を返し てもらうようなコードを生成し よう・・ 4 は 4.0 に変換してから渡そ う・・・ 最後はセミコロ ン

16 分割コンパイル ソースファイルを複数に分割し、それぞれをコンパイルしてできたオブジェ クトファイルをリンカで結合 更新されたソースファイルのみコンパイルすればよいため、プログラムの規 模が大きくなった場合でも、微細な変更時のビルド時間を大幅に短縮可能 gin.clime.c gin.objlime.objlibc.lib ginlime.exe ソースファイル オブジェクトファイル 実行ファイル ライブラリファイル ( コンパイル済 ) [ ]

17 分割コンパイル ソースファイルを複数に分割し、それぞれをコンパイルしてできたオブジェ クトファイルをリンカで結合 更新されたソースファイルのみコンパイルすればよいため、プログラムの規 模が大きくなった場合でも、微細な変更時のビルド時間を大幅に短縮可能 gin.clime.c gin.objlime.objlibc.lib ginlime.exe ソースファイル オブジェクトファイル 実行ファイル リンク コンパイル ライブラリファイル ( コンパイル済 )

18 単純にファイルを分割すると … // 呼び出される関数 double func(double d) { return 0.0; } module.c // 呼び出し側関数 int caller(void) { f = func(4); // 関数呼び出し } caller.c コンパイルは [ ] ため、 caller.c は正常にコンパイルできない。 func って何 ?

19 単純にファイルを分割すると … // 呼び出される関数 double func(double d) { return 0.0; } module.c // 呼び出し側関数 int caller(void) { f = func(4); // 関数呼び出し } caller.c コンパイルは ファイル単位で別々に実行さ れる ため、 caller.c は正常にコンパイルできない。 func って何 ?

20 ヘッダファイルの利用 #include “module.h” // 呼び出される関数 double func(double d) { return 0.0; } module.c #include “module.h” // 呼び出し側関数 int caller(void) { f = func(4); // 関数呼び出 し } caller.c // プロトタイプ宣言 double func(double d); module.h コンパイラは #include 擬似命令 の部分で、 module.h ファイルを 読み込む 呼び出される関数のプロトタイプ宣言は に記述 呼び出し側のソースファイルで #include 擬似命令により、ヘッダ ファイル内の宣言を読み込む ヘッダファイル ” ” で囲んでいる ことに注意!

21 ヘッダファイルの利用 #include “module.h” // 呼び出される関数 double func(double d) { return 0.0; } module.c #include “module.h” // 呼び出し側関数 int caller(void) { f = func(4); // 関数呼び出 し } caller.c // プロトタイプ宣言 double func(double d); module.h 呼び出される関数のプロトタイプ宣言はヘッダファイルに記述 呼び出し側のソースファイルで #include 擬似命令により、ヘッダ ファイル内の宣言を読み込む ヘッダファイル コンパイラは #include 擬似命令 の部分で、 module.h ファイルを 読み込む ” ” で囲んでいる ことに注意!

22 と " " #include のように で囲まれて いると,プリプロセッサはシステムで定められた 場所にあるファイルを取り込む #include “module.h” のように ” ” で囲まれて いると,まずプログラムファイルと同じ場所を探 し,存在しない場合はシステムで定められた場所 を探す

23 モジュール化の基本 #include #include “module.h” int internal_func(int a); #define INT_MACRO(a) (…) static int internal_func(int a) { // モジュール内で // 使用する関数 } #define MAX 1024 typedef unsigned char BYTE; void exported_func(int i); module.c module.h void exported_func(int i) { // 外部に公開する関数 } ヘッダファイルには [ ] 関数のプロトタイプ宣 言 typedef 型宣言 #define マクロ定義 など プロトタイプ宣言が関数本体と一 致するように注意 モジュール内のみで使用する関数 のプロトタイプ宣言やマクロ定義 などは [ ] で 行う

24 モジュール化の基本 #include #include “module.h” int internal_func(int a); #define INT_MACRO(a) (…) static int internal_func(int a) { // モジュール内で // 使用する関数 } module.c module.h void exported_func(int i) { // 外部に公開する関数 } ヘッダファイルには 外部に公開する情報のみを記述 関数のプロトタイプ宣 言 typedef 型宣言 #define マクロ定義 など プロトタイプ宣言が関数本体と一 致するように注意 モジュール内のみで使用する関数 のプロトタイプ宣言やマクロ定義 などはモジュール内で行う モジュールで,何を公開し, 何を隠すかがポイント #define MAX 1024 typedef unsigned char BYTE; void exported_func(int i);

25 ファイルを分割したときの関数のス コープ × ○ #include #include “module.h” int internal_func(int a); #define INT_MACRO(a) (…) static int internal_func(int a) { // モジュール内で // 使用する関数 } module.c module.h void exported_func(int i) { // 外部に公開する関数 } #define MAX 1024 typedef unsigned char BYTE; void exported_func(int i); 別のモジュール #include “module.h” exported_func(15); internal_func(30); foo.c ヘッダファイルにプロトタイプ宣言がない 関数は外部から参照できない static な関数は外部から参照できない 見え る ?

26 img_io.c 画像ファイルのロード ファイルオープン 画像バッファ確保 データコピー ファイルクローズ 画像ファイルのセーブ 画像バッファ確保 画像バッファ解放 サンプルプログラム 2 の関数呼び出し 関係 main.c 画像ファイルをロードする関数を呼び出す 画像処理関数を呼び出す 画像ファイルをセーブする関数を呼び出す 画像バッファを解放 img_proc.c 画像を 90 度回転 作業用バッファを確保 データを移し変え 不要なバッファを解放 ( あとで処理を追加したい ) etc

27 img_io.c 画像ファイルのロード ファイルオープン 画像バッファ確保 データコピー ファイルクローズ 画像ファイルのセーブ 画像バッファ確保 画像バッファ解放 サンプルプログラム 2 の関数呼び出し 関係 main.c 画像ファイルをロードする関数を呼び出す 画像処理関数を呼び出す 画像ファイルをセーブする関数を呼び出す 画像バッファを解放 img_proc.c 画像を 90 度回転 作業用バッファを確保 データを移し変え 不要なバッファを解放 ( あとで処理を追加したい ) etc

28 関数の設計 ファイル入出力&メモリ確保 / 解放 関連 int iioLoadFile(IMAGE *pImage, const char *fname); int iioSaveFile(IMAGE *pImage, const char *fname); void iioMallocImageBuffer(IMAGE *pImage); void iioFreeImageBuffer(IMAGE *pImage); 画像処理関連 void ipRotateImage(IMAGE *pImage);

29 関数の設計 ファイル入出力&メモリ確保 / 解放 関連 int iioLoadFile(IMAGE *pImage, const char *fname); int iioSaveFile(IMAGE *pImage, const char *fname); void iioMallocImageBuffer(IMAGE *pImage); void iioFreeImageBuffer(IMAGE *pImage); 画像処理関連 void ipRotateImage(IMAGE *pImage); IMAGE 構造体 へのポインタ ファイル名を表す 文字列へのポイン タ

30 サンプルプログラム2の説明 実装済みの関数( main 関数, iioLoadFile , iioMallocImageBuffer )の説明をするので 配布資料のサンプルプログラムを見ること

31 画像ファイルのセーブ 出力用ファイルを バイナリモードでオープン ヘッダ情報を出力 画像データを出力 ファイルクローズ 開始 終了 int iioSaveFile(IMAGE *pImage, const char *fname) xsize ysize level pBuffer pImage pBuffer[0] pBuffer[1] pBuffer[2] 一行ずつ出力 ヒント: fwrite ヒント 1: fprintf ヒント 2: xsize の後ろに空白 1 つ ysize の後ろに改行 level の後ろに改行 を忘れない

32 画像バッファの解放 void iioFreeImageBuffer(IMAGE *pImage) pBuffer を解放 ② 開始 終了 j < ysize? xsize ysize level pBuffer pImage pBuffer[0] pBuffer[1] pBuffer[2] ① 一行ずつ解放 ②最後に各行へのポイ ンタの配列を解放 pBuffer[ j ] を解放 ① j++; j =0; Y N