このセクションは,多くのユーザが cv::Mat を使って処理したいと思う内容をまとめた「チートシート」です.以下のコードでは,正しい名前空間が利用されていることを仮定しています:
using namespace cv;
using namespace std;
IplImage や CvMat を cv::Mat に変換します,また逆に cv::Mat を IplImage や CvMat に変換します:
// どこかで IplImage *iplimg; が宣言され,確保されており,
// さらに cv::Mat Mimg が定義されていることを仮定しています.
Mat img(iplimg); // IplImage から Mat 画像 "img" を作成します.
Mimg = iplimg; // または,あらかじめ定義された cv::Mat Mimg ヘッダに
// iplimg のデータをセットします(コピーはされません).
// IplImage または CvMat への変換です.データはコピーされません.
IplImage ipl_img = img;
CvMat cvmat = img; // cv::Mat -> CvMat の変換です.
画像に対する矩形型の部分領域 (ROI – “Region of Interest”) を扱う簡単な方法:
// 矩形を作成します.
Rect roi(10, 20, 100, 50);
// それを指す cv::Mat ヘッダ(メモリの確保はされません).
Mat image_roi = image(roi);
多少高度になりますが,画像の円形領域から効率的にサンプリングしたいならば,次のような方法があります (以下では,サンプリングの代わりに BGR 画像への描画を行います):
// この関数は,それぞれの y に対する x の境界座標を出力します.
// RxV[y1] = x1 は, y=y1 の場合に, -x1 <=x<=x1 が円の内部
// にあることを意味します.
void getCircularROI(int R, vector < int > & RxV)
{
RxV.resize(R+1);
for( int y = 0; y <= R; y++ )
RxV[y] = cvRound(sqrt((double)R*R - y*y));
}
// 緑色の円を描画します.
// ( "[1]" は "BGR" 画像に対しての添字であり,
// 青と赤のチャンネルは変更されないことに注意してください).
// これは,単に円領域からどのように「サンプリング」を行うかを示す例です.
void drawCircle(Mat &image, int R, Point center)
{
vector<int> RxV;
getCircularROI(R, RxV);
Mat_<Vec3b>& img = (Mat_<Vec3b>&)image; // 画像の 3 チャンネルポインタ
for( int dy = -R; dy <= R; dy++ )
{
int Rx = RxV[abs(dy)];
for( int dx = -Rx; dx <= Rx; dx++ )
img(center.y+dy, center.x+dx)[1] = 255;
}
}