画像のサイズを変更する
- void cvResize( IplImage* src, IplImage* dst, int interpolation);
- void resize(Mat& src, Mat& dst, Size size, double sx, double sy, int interpolation);
- 解説
- CvMat* cvReshape( IplImage* src, CvMat* dst, int new_channels, int new_height );
- Mat Mat::reshape(int new_channels, int new_height);
- 解説
- サンプルコード
- 実行結果
- 実体ファイル
- その他
void cvResize( IplImage* src, IplImage* dst, int interpolation);†
- src:IplImage*型の入力画像.CvMat*も可
- dst:IplImage*型の出力画像.CvMat*も可
- interpolation:内挿方法をint型で指定する
- CV_INTER_NN(0):最近傍
- CV_INTER_LINEAR(1):線型内挿
- CV_INTER_CUBIC(2):3次畳み込み内挿
- CV_INTER_AREA(3):モアレを軽減させる内挿方法
- CV_INTER_LANCZOS4(4):LANCZOSフィルタによる内挿
- 省略した場合は線型内挿
返り値†
void resize(Mat& src, Mat& dst, Size size, double sx, double sy, int interpolation);†
C++版インタフェース.少なくとも2.2以降ではC++版が実体でC版がラッパー
- src:Mat&型の画像.
- dst:Mat&型の画像.
- sx:double型の拡大率(x方向).省略すると0.
- sy:double型の拡大率(y方向).省略すると0.
- interpolation:内挿方法をint型で指定する
- INTER_NEAREST(0):最近傍内挿(CV_INTER_NN)
- INTER_LINEAR(1):線型内挿(CV_INTER_LINEAR)
- INTER_CUBIC(2):3次畳み込み内挿(CV_INTER_CUBIC)
- INTER_AREA(3):モアレを軽減させる内挿方法(CV_INTER_AREA)
- INTER_LANCZOS4(4):LANCZOSフィルタによる内挿(CV_INTER_LANCZOS4)
返り値†
- cvResizeの場合
- 倍率は指定せず,srcとdstのサイズから自動的に拡大/縮小される
- srcとdstはタイプが同じ必要がある(32Fや64Fなど)
- resizeの場合
- 倍率はsxとsy両方に有効な倍率を指定するか,Size型で出力画像のサイズを指定する
- srcとdstはタイプが同じでなくても自動的に変換される
- CV_INTER_AREA, INTER_AREA は
- 縮小時のみ有効(縦横ともに1倍未満の拡大率)
- それ以外の場合は指定しても線型補間になる
- 同列のenumにINTER_MAX(7)やWARP_INVERSE_MAP(16)があるが,これはresize, cvResizeで使うと実行時エラーになる
- INTER_MAXは単にenumが取りうる値の最大値
- CV_WARP_INVERSE_MAPやWARP_INVERSE_MAPはwarpAffineやwarpPerspectiveなどで使う
- 2.4以降はビルド時の指定によって最適化(TEGRA)の効果あり¬e{rev6866:Changeset 6866 – OpenCV};
CvMat* cvReshape( IplImage* src, CvMat* dst, int new_channels, int new_height );†
- src:IplImage*型の入力画像.CvMat*も可
- dst:CvMat*型の出力画像.IplImage*は代用不可なので注意
- new_channels:新しいチャンネル数
- new_height:新しい高さ
- 省略した場合は0が指定され,元と同じ高さが用いられる
返り値†
Mat Mat::reshape(int new_channels, int new_height);†
C++版.cvReshapeは通常の関数だが,reshapeはMatのメンバ関数なのでラッパー関係にはない
- new_channels:int型の新しいチャンネル数
- new_height:int型の新しい高さ
- 省略した場合は0が指定され,元と同じ高さが用いられる
返り値†
- cvResizeがコピーなのに対し,cvReshapeはコピーを行わずに変形が可能
- ただし,総ピクセル数(バイト数)が変更できない点に注意
- ↓3x3の行列を9x1のベクトルに置き換える,と言った変換に用いられる
&mimetex(\left( \begin{array}{ccc}H_{11} & H_{12} & H_{13} \\ H_{21} & H_{22} & H_{23} \\ H_{31} & H_{32} & H_{33} \\ \end{array}\right)\longrightarrow \left( \begin{array}{ccc}H_{11} \\H_{12} \\H_{13} \\H_{21} \\H_{22} \\H_{23} \\H_{31} \\H_{32} \\H_{33}\\\end{array}\right));
- この場合も,メモリ番地上の配列が変わってないことがミソ
- チャンネル数だけは指定しないといけないが,チャンネル数も高さも同じものを指定した場合は行列と画像の変換と等価な処理になる
- また,画像のサイズを保持することになるdstは,CvMat型のポインタであるが,実際に値を格納するため,ただのポインタ変数ではなく,実変数のポインタである必要がある
- 詳しくはサンプルコードを
サンプルコード†
- インタレース解除の例
#geshi(c++,number){{
// インタレース画像
IplImage *interlaceImage = cvLoadImage(INTERLACED_IMAGE_FILENAME);
// インタレース解除画像
IplImage *resizeImage = cvCreateImage(cvSize(interlaceImage->width/2, interlaceImage->height), interlaceImage->depth, interlaceImage->nChannels);
// ↓これはポインタでなく,CvMat型の変数を用意しないとだめ
CvMat deinterlaceImage;
// ↓ここで幅を半分に縮小
// ↓水平軸方向にだけ作用しているので
// ↓インタレースについては何も起きてないことに注目
cvResize(interlaceImage, resizeImage, CV_INTER_LINEAR);
// ここで同じチャンネル数(=同じカラー数),半分の高さを指定することで
// ここで左側に偶数ライン,右側に奇数ラインを表示する
cvReshape(resizeImage, &deinterlaceImage, interlaceImage->nChannels, interlaceImage->height/2);
}}
実行結果†
- ↑サイズを半分にだけ圧縮した画像.(2.jpg)
- cvResizeの実行結果
- 2.jpgを高さを半分に,幅を倍にした画像
- cvReshapeの実行結果
- 左側が偶数フレーム,右側が奇数フレームなので,左右で撮影時刻が違って映ってる画像も違うものである
実体ファイル†
cvResize†
- OpenCV 1.1 以前
- cv/src/cvimgwarp.cpp
- cv/include/cv.h
- OpenCV 2.0,2.1
- src/cv/cvimgwarp.cpp
- include/opencv/cv.h
- OpenCV 2.2以降
- modules/imgproc/include/opencv2/imgproc/imgproc.hpp (C++版)
- modules/imgproc/include/opencv2/imgproc/imgproc_c.h (C版)
- modules/imgproc/src/imgwarp.cpp
cvReshape†
- OpenCV 1.1以前
- cxcore/src/cxarray.cpp
- cxcore/include/cxcore.h
- OpenCV 2.0,2.1
- src/cxcore/cxarray.cpp
- include/opencv/cxcore.h
- OpenCV 2.2以降
- modules/core/include/opencv2/core/core.hpp (C++版)
- modules/core/include/opencv2/core/core_c.h (C版)
- modules/core/src/matrix.cpp (C++版)
- modules/core/src/array.cpp (C版)
その他†
- 何故か入力も出力もdepthがdouble(CV_64FかIPL_DEPTH_64F)の場合,何故かエラーする
補間用の関数が無い模様(OpenCV 2.1で再現)
- revision 3986で修正(OpenCV2.2以降に相当)¬e{rev3986:Changeset 3986 – OpenCV};
ジャンル:OpenCV:OpenCV 1.0:OpenCV 1.1:OpenCV 2.0:OpenCV 2.1:OpenCV 2.2:OpenCV 2.3:OpenCV 2.4準拠