Digital Image Processing 2013 4/1 デジタル 画 像 と 簡 単 な 画 像 処 理 2 Digital Image Processing 2013 4/4 2 画 像 の 生 成 1 画 像 ファイルから 入 力 する 方 法 画 像 ファイルから 画 像 を 作 るための 関 数 は Mat imread(const string& ファイル 名, int flags); この 関 数 は, 指 定 した 名 前 の 画 像 ファイルから, 画 像 を 読 み 込 み, 読 み 込 んだ 画 像 をMat 型 の 値 として 返 す 第 2 引 数 のflagsは, 画 像 を 入 力 するときの 変 換 方 法 を 指 定 し, 実 際 に 使 用 できるのは 下 記 の 三 つである CV_LOAD_IMAGE_UNCHANGED 無 変 換 ( 画 像 ファイルの 内 容 と 同 じ) CV_LOAD_IMAGE_GRAYSCALE 常 に 濃 淡 画 像 に 変 換 する CV_LOAD_IMAGE_COLOR 常 にカラー 画 像 に 変 換 する 注 意 : 画 像 形 式 上 の 変 換 である つまり,1 画 素 にR,G,Bの3つの 値 を 持 たせる 濃 淡 画 像 に 自 動 的 に 着 色 することはしない Digital Image Processing 2013 4/2 OpenCVで 画 像 処 理 のプログラムを 書 こう ここで, 次 の 内 容 について 学 習 する 1. 画 像 の 表 現 2. 画 像 の 生 成 3. 画 素 値 の 操 作 4. 画 像 の 表 示 5. 画 像 の 保 存 Digital Image Processing 2013 4/5 Imread 関 数 の 使 用 例 : 1. sample.jpg という 画 像 ファイルをそのまま 読 み 込 み 変 数 image1に 代 入 する Mat image1 = imread( sample.jpg, CV_LOAD_IMAGE_UNCHANGED); Mat image1: image1 = imread( sample.jpg, CV_LOAD_IMAGE_UNCHANGED); 2. sample.png という 画 像 ファイルを 濃 淡 画 像 として 読 み 込 み 変 数 image2に 代 入 する Mat image2 = imread( sample.pngg, CV_LOAD_IMAGE_GRAYSCALE); Mat image2: image2 = imread( sample.pngg, CV_LOAD_IMAGE_GRAYSCALE); Digital Image Processing 2013 4/3 1.OpenCVにおける 画 像 の 表 現 OpenCVでは, 一 枚 の 画 像 を 一 つの Mat 型 変 数 で 表 現 する 新 しい 画 像 の 生 成 : 変 数 の 定 義 だけでは, 画 像 を 作 ることはできない 画 像 の 実 体 を 作 る 方 法 : 1 画 像 ファイルから 入 力 する 2 大 きさと 種 類 を 指 定 して, 新 しい 画 像 を 作 る Digital Image Processing 2013 4/6 読 み 込 んだ 画 像 の 情 報 の 取 り 出 し 1. 画 像 データの 有 無 画 像 データは Mat 型 変 数 名.data に 保 存 されている 画 像 データは 無 いとき ( 例 えば 存 在 しないファイル, 間 違 ったファイル 名 の 画 像 をimread 関 数 で 読 むとき), Mat 型 変 数 名.data は NULL になる 例 : /* sample.jpg の 画 像 ファイルを 読 み 込 む */ Mat image1 = imread( sample.jpg, CV_LOAD_IMAGE_UNCHANGED); /* 画 像 の 読 み 込 みは 失 敗 したら メッセッジを 表 示 し プログラムを 終 了 させる */ if (image1.data == NULL) { printf( Can not read sample.jpg. n ); exit(1); /* プログラムを 終 了 させる 関 数 引 数 は 整 数 の 終 了 コード */ 1
Digital Image Processing 2013 4/7 画 像 の 大 きさ( 縦 横 幅 ), 種 類 画 像 の 縦 幅 ( 行 ): Mat 型 変 数 名.rows 画 像 の 横 幅 ( 列 ): Mat 型 変 数 名.cols 画 像 のチャンネル 数 : Mat 型 変 数 名.channels() 濃 淡 画 像 の 場 合 は 1 カラー 画 像 の 場 合 は 3 例 : /* image1の 縦 幅 横 幅 を 表 示 する */ printf("the size is %d X %d pixel n", image1.cols, image1.rows); /* image1の 種 類 の 判 定 と 表 示 */ if (image1.channels() == 1) printf("image1 is a grey image. n"); else if (image1.channels() == 3) printf("image1 is a RGB color image. n"); Digital Image Processing 2013 4/10 3.2 カラー 画 素 値 の 操 作 カラー 画 像 の 場 合, 座 標 が(x, y)の 位 置 にある 画 素 値 は Mat 型 変 数.at<Vec3b>(y, x) を 使 って,Vec3b(3 個 の 符 号 なし 文 字 型 要 素 から 構 成 される3 次 元 ベクトル 型 )の 変 数 と 同 じように 使 うことができる Vec3b 型 の 整 数 i 番 目 の 要 素 は, Vec3b 型 変 数 (i) を 使 って,unsigned char 型 の 変 数 と 同 じように 使 うことができる また,3 個 の 要 素 からVec3b 型 のベクトルを 作 る 時,Vec3bの 構 築 子 を 利 用 することができる 例 1:image3の(30,40)の 座 標 にある 画 素 値 の 表 示 Vec3b pixel = image3.at<vec3b>(40, 30); printf( Red=%d Green=%d Blue=%d n", pixel(2), pixel(1), pixel(0)); 例 2:image3の(30,40)の 座 標 にある 画 素 値 2 倍 にして, 画 像 の 元 の 場 所 に 代 入 Vec3b pixel = image3.at<vec3b>(40, 30); image3.at<vec3b>(40, 30) = Vec3b(pixel(0)*2, pixel(1)*2, pixel(2)*2); 例 3:image3の(30,40)の 座 標 にある 画 素 値 をimage4の(13,24)の 座 標 に 代 入 image4.at<vec3b>(24, 13) = image3.at<vec3b>(40, 30); Digital Image Processing 2013 4/8 2 大 きさと 種 類 を 指 定 して, 新 しい 画 像 を 作 る 方 法 指 定 した 大 きさ, 種 類 の 画 像 を 新 しく 生 成 し,Mat 型 変 数 に 代 入 するとき,Mat クラス(C++の 概 念 で,C 言 語 の 構 造 体 の 拡 張 である)の 構 築 子 (constructor, Mat 型 の 変 数 を 作 るための 関 数 で 名 前 はMatである)を 使 って 行 う Mat 型 構 築 子 に 引 数 が3 個 あり,それぞれ 縦 幅 横 幅 種 類 を 指 定 する 縦 幅 横 幅 は 整 数 で, 単 位 は 画 素 である 種 類 の 指 定 には OpenCVで 用 意 した 定 数 を 使 う 濃 淡 画 像 を 作 る 時 は CV_8U1 カラー 画 像 を 作 る 時 は CV_8U3 を 指 定 する 例 1:100 行 x200 列 の 濃 淡 画 像 を 作 り 変 数 yimg に 代 入 する Mat yimg = Mat(100, 200, CV_8U1); Mat yimg(100, 200, CV_8U1); 例 2:240 行 x360 列 のカラー 画 像 を 作 り 変 数 rgbimg に 代 入 する Mat rgbimg = Mat(240, 360, CV_8U3); Mat rgbimg(240, 360, CV_8U3); Digital Image Processing 2013 4/11 3.3 画 像 コピーの 例 Mat 型 変 数 の 代 入 は, 画 像 の 実 体 を 渡 すことであり,つまり, 代 入 先 の 画 素 値 を 変 えれば, 元 の 画 像 の 画 素 値 も 変 わる 画 像 のコピーを 作 りたい 場 合,コピー 元 と 同 じ 種 類, 大 きさの 新 しい 画 像 を 作 り, 元 の 画 像 の 内 容 ( 全 ての 画 素 )を 新 しい 画 像 にコピーする 必 要 がある 例 :image1をimage2にコピーする int width = image1.cols, height = image1.rows, ch = image1.channels(); Mat image2; if (ch == 1) { image2 = Mat(height, width, CV_8U1); for (int y = 0; y < height; y++) { for (int x = 0; x < height; x++) image2.at<uchar>(y,x) = image1.at<uchar>(y,x); else if (ch == 3) { image2 = Mat(height, width, CV_8U3); for (int y = 0; y < height; y++) { for (int x = 0; x < height; x++) image2.at<vec3b>(y,x) = image1.at<vec3b>(y,x); Digital Image Processing 2013 4/9 3 画 素 値 の 操 作 3.1 濃 淡 画 素 値 の 操 作 濃 淡 画 像 の 場 合, 座 標 が(x, y)の 位 置 にある 画 素 値 は Mat 型 変 数.at<uchar>(y, x) を 使 って,unsigned char( 符 号 なし 文 字 型,8ビット の 符 号 なし 整 数 型 )の 変 数 と 同 じように 使 うことができる 例 1:image2の(30,40)の 座 標 にある 画 素 値 の 表 示 printf( image2(30, 40) = %d n", image2.at<uchar>(40, 30)); 例 2:image2の(30,40)の 座 標 にある 画 素 値 2 倍 にして, 画 像 の 元 の 場 所 に 代 入 image2.at<uchar>(40, 30) = image2.at<uchar>(40, 30) * 2; 例 3:image2の(30,40)の 座 標 にある 画 素 値 をimage1の(13,24)の 座 標 に 代 入 image1.at<uchar>(24, 13) = image2.at<uchar>(40, 30); Digital Image Processing 2013 4/12 4 画 像 の 表 示 4.1 表 示 用 のウィンドウの 用 意 OpenCVでは, 画 像 を 表 示 するために,namedWindows 関 数 を 使 って 表 示 用 の ウィンドウを 先 に 用 意 する 必 要 がある namedwindow(ウィンドウタイトル, CV_WINDOW_AUTOSIZE); ウィンドウタイトルとは,ウィンドウの 上 に 表 示 される 文 字 列 のことである 4.2 画 像 の 表 示 画 像 を 表 示 するとき,imshow 関 数 を 使 う imshow(ウィンドウタイトル, Mat 型 変 数 ); 4.3 画 像 の 表 示 時 間 の 指 定 imshow 関 数 は, 画 像 をウィンドウに 表 示 した 後 すぐ 終 了 する 何 もしなければ, プログラムは 残 りの 部 分 の 実 行 に 入 るために, 表 示 はすぐ 消 える waitkey 関 数 を 使 って, 画 像 の 表 示 時 間 をコントロールすることができる waitkey( 時 間 ); waitkeyは, 指 定 した 時 間 を 経 つか, 何 かのキーが 押 されたまで,プログラムの 実 行 を 一 時 的 に 停 止 させる 時 間 は 整 数 で, 単 位 はミリ 秒 である 2
Digital Image Processing 2013 4/13 5 画 像 の 保 存 -50 Mat 型 変 数 表 現 される 画 像 を 画 像 ファイルに 保 存 するとき,imwrite 関 数 を 使 う imwrite(ファイル 名, Mat 型 変 数 ); 注 意 :imwriteは 画 像 ファイル 名 の 拡 張 子 画 像 ファイルの 形 式 を 選 択 するために, 拡 張 子 は 間 違 ったり, 省 略 したりすると,imwriteは 失 敗 してしまう 画 像 ファイル 名 の 正 しい 例 : mypicture.jpg toyota.png cat.gif art.tif background.bmp 不 適 切 のファイル 名 の 例 : paper.doc note.txt test.tex figure.ai kouen.pptx -100-150 注 目 Digital Image Processing 2013 4/14 画 素 値 の 変 更 1( 足 し 算 ) 各 画 素 の 値 画 素 値 = 元 の 画 素 値 + 定 数 効 果 :. 画 像 は 明 るく( 或 いは 暗 く)なる Digital Image Processing 2013 4/17 画 素 値 の 変 更 2( 掛 け 算 ) 各 画 素 の 値 画 素 値 = 元 の 画 素 値 定 数 効 果 : 明 るいものは より 明 るく( 暗 く) なる 定 数 > 0 の 場 合 : 画 素 値 が 増 える 画 像 が 明 るくなる 調 整 後 の 画 素 値 定 数 > 0 無 変 換 定 数 > 1.0 の 場 合 : 画 素 値 の 大 きいも のはより 大 幅 に 大 きくなる 明 るい 画 素 と 暗 い 画 素 の 差 が 大 き くなる 調 整 後 の 画 素 値 定 数 >1.0 k 無 変 換 定 数 < 0 の 場 合 : 画 素 値 が 減 る 画 像 が 暗 くなる 0 定 数 < 0 元 の 画 素 値 画 素 値 変 換 曲 線 定 数 < 1.0 の 場 合 : 画 素 値 の 大 きいも のはより 大 幅 に 小 さくなる 明 るい 画 素 と 暗 い 画 素 の 差 が 小 さ くなる 0 定 数 < 1.0 画 素 値 変 換 曲 線 元 の 画 素 値 +50 0.7 +100 注 目 +150 1.5 3
Digital Image Processing 2013 4/19 画 素 値 を 計 算 する 際 の 注 意 事 項 1.コンピュータは 計 算 を 素 直 に 行 う 繰 上 げはどこまでもでき 借 りるのはいつでも 可 能 仮 に, 計 算 結 果 を 保 存 するために,10 数 の2 桁 分 しかない 場 合 を 考 える コンピュータで 計 算 すると こうなる 60 10 + 50-30 110 999999980 10 80 画 素 値 は 一 般 的 に,8 桁 の2 進 数 で 表 現 する その 範 囲 は 0~255である したがって, 画 素 値 の 計 算 でも 上 記 の 例 の 現 象 が 発 生 する 可 能 性 がある Digital Image Processing 2013 4/22 画 素 値 の 演 算 におけるOverflowの 対 処 計 算 結 果 を 画 素 に 代 入 する 前 に 1) Overflow が 起 きているかを 判 断 2) 発 生 したら 画 素 が 表 現 できる 範 囲 内 から 計 算 結 果 に 最 も 近 い 値 にする 飽 和 処 理 0; 画 素 値 = 計 算 結 果 ; 255; 計 算 結 果 < 0 0 計 算 結 果 255 計 算 結 果 > 255 Digital Image Processing 2013 4/20 例 : 画 素 値 = 240 + 50 +150 2 進 数 で 表 現 すると 240 11110000 + 50 + 110010 290 1 00100010 8 溢 れ!=2 =256 結 果 を 画 素 に 代 入 するとき 溢 れたものは 捨 てられる ために 画 素 値 = 240 + 50 256 = 34 逆 に 小 さくなった! -150 Digital Image Processing 2013 4/21 Digital Image Processing 2013 4/24 例 : 画 素 値 = 40-50 2 進 数 で 表 現 すると 1+1 40 1 00101000-50 - 00110010-10 11110110 上 位 から 借 りたもの=256 画 素 値 = 256 + 40-50 = 246 逆 に 大 きくなった! 1.5 1.5 4
Digital Image Processing 2013 4/25 宿 題 4 4.1 画 素 値 は0~ 2 8 1 の 整 数 値 で 表 す 画 像 をより 明 るくしようとして, 全 ての 画 2素 8 値 1に4 0を 足 し 算 する 画 像 の 中 にある 元 の 画 像 値 がそれぞれ 30, 120, 140, 200, 250の 画 素 の 処 理 後 の 結 果 を, 飽 和 処 理 なしとありの 場 合 を 分 けて 求 めなさい 4.2 宿 題 3.2に, 飽 和 処 理 を 追 加 して 完 成 し なさい 4.3 宿 題 3.3に, 飽 和 処 理 を 追 加 して 完 成 し なさい 5