cv::Rect の使い方【OpenCV/C++】〜矩形領域を扱う基本型〜
cv::Rect は OpenCV で矩形領域を表す基本型です。左上座標 (x, y) と幅・高さ (width, height) の4つの値で矩形を定義し、ROI(関心領域)の切り出しや矩形描画など画像処理の至る所で使います。
最小の使い方はこれだけです。
cv::Rect roi(100, 50, 200, 150); // x, y, width, height
cv::Mat cropped = src(roi); // ROI切り出し
動作環境
- OpenCV 4.x
- C++17
g++ -std=c++17 main.cpp `pkg-config --cflags --libs opencv4`
基本の使い方
#include <opencv2/opencv.hpp>
#include <iostream>
int main()
{
// 画像読み込み
cv::Mat src = cv::imread("input.jpg");
if (src.empty()) {
std::cerr << "画像の読み込みに失敗しました" << std::endl;
return -1;
}
// cv::Rect を定義: x=100, y=50, width=200, height=150
cv::Rect roi(100, 50, 200, 150);
// 矩形が画像範囲内に収まっているか確認
cv::Rect imgRect(0, 0, src.cols, src.rows);
cv::Rect safeRoi = roi & imgRect; // 画像領域との AND で安全な矩形を取得
if (safeRoi.empty()) {
std::cerr << "矩形が画像範囲外です" << std::endl;
return -1;
}
// ROI 切り出し(コピーではなく参照)
cv::Mat cropped = src(safeRoi);
// 矩形を元画像に描画
cv::rectangle(src, safeRoi, cv::Scalar(0, 255, 0), 2);
// 各プロパティの確認
std::cout << "x : " << safeRoi.x << std::endl;
std::cout << "y : " << safeRoi.y << std::endl;
std::cout << "width : " << safeRoi.width << std::endl;
std::cout << "height : " << safeRoi.height << std::endl;
std::cout << "面積 : " << safeRoi.area() << std::endl;
std::cout << "左上 : " << safeRoi.tl() << std::endl;
std::cout << "右下 : " << safeRoi.br() << std::endl;
cv::imwrite("output.jpg", src);
cv::imwrite("cropped.jpg", cropped);
return 0;
}
実行すると以下のように表示されます。
x : 100
y : 50
width : 200
height : 150
面積 : 30000
左上 : [100, 50]
右下 : [300, 200]
行ごとの解説
| 行の内容 | 説明 |
|---|---|
cv::Rect roi(100, 50, 200, 150) |
(x, y, width, height) で矩形を定義 |
roi & imgRect |
& 演算子で2矩形の交差領域を取得(はみ出し防止に定番) |
src(safeRoi) |
cv::Mat::operator() に Rect を渡してROI参照を取得 |
safeRoi.tl() |
左上座標を cv::Point で返す |
safeRoi.br() |
右下座標を cv::Point で返す(x+width, y+height) |
safeRoi.area() |
width * height を返す |
引数と戻り値
cv::Rect はクラス(構造体)であり、複数のコンストラクタが用意されています。
コンストラクタ一覧
| コンストラクタ | 説明 |
|---|---|
Rect() |
全ゼロで初期化 |
Rect(int x, int y, int width, int height) |
最もよく使う形式 |
Rect(cv::Point pt, cv::Size sz) |
左上座標とサイズで指定 |
Rect(cv::Point pt1, cv::Point pt2) |
左上・右下の2点で指定 |
主なメンバと演算子
| メンバ / 演算子 | 型 / 戻り値 | 説明 |
|---|---|---|
x, y |
int |
左上座標 |
width, height |
int |
幅・高さ |
tl() |
cv::Point |
左上座標 |
br() |
cv::Point |
右下座標 |
area() |
int |
面積 (width * height) |
empty() |
bool |
width <= 0 または height <= 0 なら true |
contains(cv::Point) |
bool |
点が矩形内部にあるか |
rect1 & rect2 |
cv::Rect |
交差領域(AND) |
rect1 \| rect2 |
cv::Rect |
包含矩形(OR) |
rect + point |
cv::Rect |
矩形の平行移動 |
rect + size |
cv::Rect |
矩形のサイズ変更 |
⚠️
br()が返す点は「右下の1つ外側」です。x + width,y + heightと同値のため、ピクセルとして扱う場合は注意してください。
実践例
実践例1: 矩形同士の演算(AND / OR)
物体検出結果の重複判定や、複数領域の合算範囲を求めるときに使います。
#include <opencv2/opencv.hpp>
#include <iostream>
int main()
{
cv::Rect r1(50, 50, 200, 150);
cv::Rect r2(100, 100, 200, 150);
// 交差領域
cv::Rect intersection = r1 & r2;
std::cout << "交差領域: " << intersection << std::endl;
// 包含矩形
cv::Rect unionRect = r1 | r2;
std::cout << "包含矩形: " << unionRect << std::endl;
return 0;
}
交差領域: [150 x 100 from (100, 100)]
包含矩形: [250 x 200 from (50, 50)]
実践例2: Point・Size との変換
cv::Point や cv::Size と相互に組み合わせることで、動的な矩形生成が簡潔に書けます。
#include <opencv2/opencv.hpp>
#include <iostream>
int main()
{
cv::Point center(320, 240);
cv::Size halfSize(50, 50);
// 中心点からパッチ矩形を生成
cv::Rect patch(center - cv::Point(halfSize.width, halfSize.height),
cv::Size(halfSize.width * 2, halfSize.height * 2));
std::cout << "パッチ矩形: " << patch << std::endl;
// 矩形をオフセット移動
cv::Rect shifted = patch + cv::Point(10, 20);
std::cout << "移動後 : " << shifted << std::endl;
return 0;
}
パッチ矩形: [100 x 100 from (270, 190)]
移動後 : [100 x 100 from (280, 210)]
つまずきポイント
⚠️ ROI が画像範囲をはみ出すと assertion エラー
src(roi) で範囲外の Rect を渡すと、実行時に cv::Exception が発生します。必ず roi & imgRect で画像範囲と AND を取ってから使うか、contains や範囲チェックを挟んでください。
cv::Rect safeRoi = roi & cv::Rect(0, 0, src.cols, src.rows);
if (!safeRoi.empty()) { ... }
⚠️ br() はピクセル座標ではなく「1つ外側」
br() は (x + width, y + height) を返します。右下の「最後のピクセル」は (x + width - 1, y + height - 1) です。cv::rectangle に渡す場合は問題ありませんが、ループ境界などで間違えやすいです。
⚠️ ROI は参照コピー(ディープコピーではない)
cv::Mat cropped = src(roi); // 参照(src のメモリを共有)
cv::Mat copied = src(roi).clone(); // ディープコピー
src(roi) の結果はメモリを共有しています。ROI 画像を独立して加工したい場合は .clone() を忘れずに呼んでください。元画像を誤って書き換えるバグの原因になります。
関連する関数
cv::rectangle—cv::Rectを渡して矩形を描画するcv::Mat::operator()—cv::Rectを使って ROI を切り出すcv::Point— 左上・右下の座標を表す型。Rectと組み合わせて使うcv::Size— 幅・高さを表す型。Rectのコンストラクタで使用cv::boundingRect— 輪郭点群からcv::Rectを求める
まとめ
cv::Rect は (x, y, width, height) で矩形を定義する OpenCV の基本型で、ROI 切り出し・描画・矩形演算など至る所で使います。ROI は参照コピーなので .clone() の要否を意識すること、範囲外アクセスを防ぐために & 演算子で安全な矩形を取得することが実装上のポイントです。
🛠 画像処理のプロが開発するSDK/API
本ブログを運営するスワローインキュベートは、OpenCV ベースのなりすまし判定SDK/API(C++製・OpenCV 4.10)を開発しています。顔認証システムへの組み込み実績多数。

