画像ファイル(ppm)の読み書き 画像データ用のメモリ確保・解放

Slides:



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

10: ファイル入出力 Linux にログインし、以下の講義ページ を開いておくこと teachers/w483692/CPR1/ C プログラミング入門 総機 1 ( 月 1) 1.
プログラミング 関数編 情報科学科. プログラミングにあたって C 言語では、 main 内に処理を記述 1000 行になるような大きなプログラムでは、 プログラム全体が何をしているのかを把握 することが困難になる 他人が見ると非常に理解しにくい 作成者であっても時が経てば内容を忘れて、他 人が見た時と同じ状況になる.
1 全体の流れ 画像ファイルを開き,画像データをメモリ上にロード メモリ上にロードした画像データに処理を加える 処理後のデータを出力ファイルに書き出す 画像データ用に確保したメモリを解放.
画像情報処理 1 プログラミング課題 知的画像処理研究室 M2 大村 瑞穂. 目次 プログラミング課題の準備 – ファイルのダウンロード・解凍・コンパイル サンプルプログラムの説明 画像処理の方法 レポートに載せる画像について 例題と第 1 回レポート課題.
画像情報処理1 ~画像処理プログラミング~ 2015/05/01 知的画像処理研究室 M1 吉原寛樹
情報基礎演習B 後半第5回 担当 岩村 TA 谷本君.
数理情報工学演習第一C プログラミング演習 (第3回 ) 2014/04/21
第12回新しい型と構造体.
第13回構造体.
第12回構造体.
プログラミング入門2 第10回 構造体 情報工学科 篠埜 功.
プログラミング言語Ⅰ(実習を含む。), 計算機言語Ⅰ・計算機言語演習Ⅰ, 情報処理言語Ⅰ(実習を含む。)
記憶クラス 変数をどのような記憶領域に割り当てるかを指定するのが記憶クラス 記憶クラスには、自動変数、静的変数、外部変数などがある。
第8回 プログラミングⅡ 第8回
構造体.
プログラミング演習Ⅰ 課題2 10進数と2進数 2回目.
画像ファイル(ppm)の読み書き 画像データ用のメモリ確保・解放
2014/05/02 知的画像処理研究室 M1 中津美冴 画像情報処理1 ~画像処理プログラミング~ 2014/05/02 知的画像処理研究室 M1 中津美冴
第3回 配列,構造体,ポインタ ~ データ構造について学ぶための基礎~
精密工学科プログラミング基礎Ⅱ 第3回資料 今回の授業で習得してほしいこと: 2次元配列の使い方 (前回の1次元配列の復習もします.)
構造体 構造体, 構造体とポインタの組み合わせ,.
第10回 プログラミングⅡ 第10回
10: ファイル入出力 C プログラミング入門 基幹2 (月4) Linux にログインし、以下の講義ページ を開いておくこと
補足説明.
Cプログラミング演習.
情報・知能工学系 山本一公 プログラミング演習Ⅱ 第2回 ファイル処理 情報・知能工学系 山本一公
iioLoadFile()とiioMallocImageBuffer()の補足
Cプログラミング演習 第7回 メモリ内でのデータの配置.
iioLoadFile()とiioMallocImageBuffer()の補足
iioLoadFile()とiioMallocImageBuffer()の補足
精密工学科プログラミング基礎 第10回資料 (12/18実施)
プログラミング演習I 2003年6月25日(第10回) 木村巌.
画像処理プログラムの説明.
プログラミング入門2 第11回 情報工学科 篠埜 功.
プログラミング演習Ⅱ 課題4第3週 画像処理 (1) ビット演算子.
第7回 プログラミングⅡ 第7回
第11回 プログラミングⅡ 第11回
デジタル画像とC言語.
システムプログラミング 第7回、8回 ファイルシステム関連の システムコール
岩村雅一 知能情報工学演習I 第9回(後半第3回) 岩村雅一
2分法のプログラム作成方法 2分法のプログラム(全体構成) プログラム作成要領 2分法のメイン関数(変数宣言)
第4回 ファイル入出力方法.
岩村雅一 知能情報工学演習I 第12回(C言語第6回) 岩村雅一
画像処理プログラミング 知的画像処理研究室 M2 小林 佳奈美.
システムプログラミング 第7回、8回 ファイルシステム関連の システムコール
精密工学科プログラミング基礎Ⅱ 第5回資料 今回の授業で習得してほしいこと: 構造体 (教科書 91 ページ)
11: 動的メモリ確保 C プログラミング入門 総機1 (月1) Linux にログインし、以下の講義ページ を開いておくこと
情報基礎演習B 後半第2回 担当 岩村 TA 谷本君.
ファイルの読み込み, ファイルからのデータの取り出し, ファイルの書き出し
第5回 プログラミングⅡ 第5回
プログラミング演習Ⅱ 課題4第4週 画像処理 (2) 応用.
モジュール分割.
岩村雅一 知能情報工学演習I 第12回(後半第6回) 岩村雅一
11: 動的メモリ確保 C プログラミング入門 基幹2 (月4) Linux にログインし、以下の講義ページ を開いておくこと
全体の流れ 画像ファイルを開き,画像データをメモリ上にロード メモリ上にロードした画像データに処理を加える
プログラミング言語論 第九回 理工学部 情報システム工学科 新田直也.
プログラミング演習I 2003年6月11日(第9回) 木村巌.
オブジェクト指向言語論 第七回 知能情報学部 新田直也.
プログラミング言語論 第九回 理工学部 情報システム工学科 新田直也.
オブジェクト指向言語論 第七回 知能情報学部 新田直也.
プログラミング演習II 2004年11月 16日(第5回) 理学部数学科・木村巌.
プログラミング言語Ⅰ(実習を含む。), 計算機言語Ⅰ・計算機言語演習Ⅰ, 情報処理言語Ⅰ(実習を含む。)
プログラミング演習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 第13回(後半第7回) 岩村雅一
プログラミング 2 静的変数.
岩村雅一 知能情報工学演習I 第9回(C言語第3回) 岩村雅一
Presentation transcript:

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

画像データの基礎 画素ごとの明るさを数値で表現 (8bitなら0から255) カラー画像は各画素にRed, Green, Blue 200 130 100 ... 画素ごとの明るさを数値で表現 (8bitなら0から255) カラー画像は各画素にRed, Green, Blue (R,G,B)= (255, 0, 0): 赤,(255, 255, 255): 白 raw画像ファイルでは1次元上に数値が並んでいる B1 B2 B3 B4 B5 B6 B7 B8 B9 ファイル上の画像データの並び G1 G2 G3 G4 G5 G6 G7 G8 G9 R1 G1 B1 R2 G2 B2 ... B3 R4 G4 R1 R2 R3 R4 R5 R6 R7 R8 R9

PPM画像ファイル 画像に関する情報をヘッダとして持っている 今回使用する画像データはR,G,B各8ビット 8bit 24bit 解説 P6 # Created by IrfanView 1024 768 255 [ここから画像データ] ..... マジックナンバー(バイナリPPM,固定) #から改行まではコメント文 横方向の画素数[空白]縦方向の画素数 最大輝度 [ここから画像データ] ..... 画像に関する情報をヘッダとして持っている 今回使用する画像データはR,G,B各8ビット R1 G1 B1 R2 G2 B2 ... B3 R4 G4 8bit 24bit

データ構造~画像データをどう表現するか~ 画像ファイルのフォーマット 88 (136) B1 (177) E7 (231) ヘッダ(画像サイズ,最大輝度) 画像データ int xsize; int ysize; int level; unsigned char   buffer_r[ysize][xsize],   buffer_g[ysize][xsize],   buffer_b[ysize][xsize]; プログラムでデータを読み込む場合・・・ ・変数が6つ必要 → 構造体でまとめる ・配列サイズはヘッダを読むまで決められない → メモリの動的確保・解放

データ構造~構造体定義~ ヘッダ 画像データ (1画素分) typedef struct { int xsize; int ysize; 画像ファイルのフォーマット 88 (136) B1 (177) E7 (231) ヘッダ(画像サイズ,最大輝度) 画像データ typedef struct { int xsize; int ysize; int level; PIXEL **pBuffer; } IMAGE; ヘッダ 画像データへの二重ポインタ typedef struct { unsigned char r; unsigned char g; unsigned char b; } PIXEL; 画像データ (1画素分)

データ構造~構造体定義~ (PIXEL*)型として PPIXELを新たに定義 typedef struct { int xsize; 画像ファイルのフォーマット 88 (136) B1 (177) E7 (231) ヘッダ(画像サイズ,最大輝度) 画像データ typedef struct { int xsize; int ysize; int level; PPIXEL *pBuffer; } IMAGE; typedef struct { unsigned char r; unsigned char g; unsigned char b; } PIXEL, *PPIXEL; (PIXEL*)型として  PPIXELを新たに定義

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

画像バッファの様子 ysize個 → i ↓ j pImage->pBuffer[0][0] → i ↓ j xsize 256 ysize 192 level 255 pImage->pBuffer[0][0] pBuffer → i ↓ j ysize個 pImage->pBuffer[j] pImage->pBuffer[j][i] xsize個

画像へのアクセス方法 IMAGE *pImage; /* pImageに画像データを読み込んだ後と仮定する */ pImage->xsize; /* int型,画像幅 */ pImage->ysize; /* int型,画像高さ */ pImage->pBuffer[j][i]; /* PIXEL型,位置(i,j)における{R,G,B}*/ pImage->pBuffer[j][i].r; /* unsigned char型 */ /* 位置(i,j)におけるRの値 */ pImage->pBuffer[j]; /* PPIXEL型,(j)行の画素値が連続で格納されて /* いる場所の先頭アドレス */

モジュール設計について

モジュール設計 利点: 可読性,分割コンパイル,情報の隠ぺい モジュールごとの独立性を高めるように設計 メイン main.c 画像のファイル入出力 画像データ用メモリ確保と解放 img_io.c img_io.h 画像処理 img_proc.c img_proc.h

関数プロトタイプ宣言 あるファイル内で定義した関数(func)を,定義している位置より前で呼び出したい場合 プロトタイプ宣言 最後はセミコロン double func(double d); int caller(void) {   f = func(4); } double func(double d) return d*2; 関数呼出部分より前に   プロトタイプ宣言 を行う プロトタイブ宣言がないと, func 関数は未定義エラー func 関数の定義部

ヘッダファイルの利用 あるファイル内で定義した関数(func)を,違うファイルで呼び出したい場合 関数のプロトタイプ宣言をヘッダファイルに記述 呼び出し側のファイルで #include module.h ヘッダファイル //プロトタイプ宣言 double func(double d); caller.c ” ” で囲んでいることに注意! module.c #include “module.h” //呼び出し側関数 int caller(void) {   f = func(4); // 関数呼び出し } #include “module.h” //呼び出される関数 double func(double d) { return d*2; }

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

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

○ × ファイルを分割したときの関数のスコープ 別のモジュール ヘッダファイルにプロトタイプ宣言がない 関数は外部から参照できない #include <string.h> #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); 別のモジュール foo.c ○ #include “module.h” exported_func(15); internal_func(30); ×  ヘッダファイルにプロトタイプ宣言がない   関数は外部から参照できない  staticな関数は外部から参照できない

サンプルプログラム2について

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

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

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

関数の設計 ファイル入出力 (済) 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);

第2週目の目標 画像ファイルを読み込み 90°回転させた後, 画像ファイルを出力するプログラムを作成する 画像ファイルを読み込み 90°回転させた後, 画像ファイルを出力するプログラムを作成する 読み込み関数や回転処理関数は既に実装済み 画像ファイルをセーブする関数”iioSaveFile”と    画像バッファを解放する関数” iioFreeImageBuffer”を完成させる

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

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