cv::rectangle の使い方【OpenCV/C++】〜画像に矩形を描画する〜

OpenCV for C++
📌 準備: OpenCV の環境構築がまだの方はこちら → C++ 環境構築ガイドC#(OpenCvSharp)セットアップ

cv::rectangle の使い方【OpenCV/C++】〜画像に矩形を描画する〜

cv::rectangle は画像上に矩形(四角形)を描画する関数です。物体検出の結果表示・ROI の可視化・デバッグ用の注釈など、画像処理の現場で最も頻繁に使う描画系関数のひとつです。最小限のコードは次のとおりです。

cv::rectangle(img, cv::Point(x1, y1), cv::Point(x2, y2), cv::Scalar(0, 255, 0), 2);

動作環境

  • OpenCV 4.x
  • コンパイル: g++ -std=c++17 main.cpp $(pkg-config --cflags --libs opencv4) -o main

環境構築がまだの方は環境構築ガイドを先にどうぞ。


基本の使い方

白画像にグリーンの矩形を1本描画する最小構成です。

#include <opencv2/opencv.hpp>

int main()
{
    // 500x500 の白画像を用意
    cv::Mat img(500, 500, CV_8UC3, cv::Scalar(255, 255, 255));

    // 左上(100, 100) 〜 右下(400, 350) に緑の矩形を描画(線幅 3px)
    cv::rectangle(
        img,
        cv::Point(100, 100),   // 左上の頂点
        cv::Point(400, 350),   // 右下の頂点
        cv::Scalar(0, 255, 0), // 色: BGR で緑
        3                      // 線幅 [px]
    );

    cv::imshow("rectangle", img);
    cv::waitKey(0);
    return 0;
}

実行すると、500×500 の白いウィンドウ上に緑色の矩形が描画されます。左上 (100,100)・右下 (400,350) を角とする横長の四角形が線幅 3px で表示されます。

[ウィンドウ "rectangle" が開き、緑の矩形が表示される]

コード解説

  • cv::Mat(500, 500, CV_8UC3, cv::Scalar(255, 255, 255)) — 3チャンネル(BGR) の白画像を生成。
  • cv::Point(x, y) — 画像座標を表す構造体。原点は左上、x が列方向・y が行方向です。
  • cv::Scalar(B, G, R) — OpenCV の色指定は BGR 順。RGB と逆なので注意。
  • 線幅に cv::FILLED(または -1)を渡すと矩形を塗りつぶせます(後述)。

引数と戻り値

オーバーロード 1: 2頂点指定

void cv::rectangle(
    InputOutputArray img,
    Point pt1,
    Point pt2,
    const Scalar& color,
    int thickness = 1,
    int lineType  = LINE_8,
    int shift     = 0
);
引数 説明
img cv::Mat& 描画対象の画像(直接書き換えられる)
pt1 cv::Point 矩形の左上頂点
pt2 cv::Point 矩形の右下頂点
color cv::Scalar 描画色(BGR順)
thickness int 線幅 [px]。cv::FILLED or -1 で塗りつぶし
lineType int LINE_8(デフォルト)/ LINE_4 / LINE_AA(アンチエイリアス)
shift int 座標のサブピクセルビット数。通常 0

オーバーロード 2: Rect 指定

void cv::rectangle(
    InputOutputArray img,
    Rect rec,
    const Scalar& color,
    int thickness = 1,
    int lineType  = LINE_8,
    int shift     = 0
);

cv::Rect(x, y, width, height) を渡す形式です。検出結果が cv::Rect で返ってくる場合にそのまま使えて便利です。

戻り値: なし(void)。描画は img に直接反映されます。


実践例

例1: 塗りつぶし矩形で物体検出結果を可視化

実務では物体検出のバウンディングボックスを cv::Rect で受け取ることが多いです。半透明風の表現は addWeighted を使いますが、まず基本の塗りつぶし描画を示します。

#include <opencv2/opencv.hpp>

int main()
{
    // 画像ファイルを読み込む
    cv::Mat img = cv::imread("input.jpg");
    if (img.empty()) {
        std::cerr << "画像を読み込めませんでした" << std::endl;
        return -1;
    }

    // 検出結果を想定した矩形リスト(実際は検出器から取得)
    std::vector<cv::Rect> detections = {
        cv::Rect(50,  30,  200, 150),
        cv::Rect(300, 100, 180, 200),
    };

    for (const auto& rect : detections) {
        // 枠線(赤・線幅2)
        cv::rectangle(img, rect, cv::Scalar(0, 0, 255), 2);
    }

    cv::imshow("detections", img);
    cv::waitKey(0);
    return 0;
}
[ウィンドウ "detections" に 2つの赤い矩形枠が描画された画像が表示される]

例2: ラベル付き矩形(rectangle + putText の組み合わせ)

実務ではクラス名や信頼度スコアを矩形の上に重ねて表示することが多いです。

#include <opencv2/opencv.hpp>
#include <string>

int main()
{
    cv::Mat img(480, 640, CV_8UC3, cv::Scalar(30, 30, 30));

    cv::Rect   box(100, 120, 220, 160);
    std::string label = "person: 0.92";

    // 矩形を描画
    cv::rectangle(img, box, cv::Scalar(0, 255, 128), 2);

    // ラベル背景(塗りつぶし矩形で読みやすくする)
    cv::Rect labelBg(box.x, box.y - 24, 180, 24);
    cv::rectangle(img, labelBg, cv::Scalar(0, 255, 128), cv::FILLED);

    // テキストを描画
    cv::putText(
        img, label,
        cv::Point(box.x + 4, box.y - 5),
        cv::FONT_HERSHEY_SIMPLEX, 0.6,
        cv::Scalar(0, 0, 0), 1, cv::LINE_AA
    );

    cv::imshow("label box", img);
    cv::waitKey(0);
    return 0;
}
[ウィンドウ "label box" に緑枠の矩形と "person: 0.92" のラベルが表示される]

ラベル背景に cv::FILLED で小さな矩形を塗りつぶし、その上にテキストを乗せるパターンは物体検出の可視化で定番です。cv::putText の詳細はOpenCV/C++ putText の使い方を参照してください。


つまずきポイント

⚠️ BGR と RGB の混同

OpenCV は色を BGR 順で扱います。赤を指定したいときは cv::Scalar(0, 0, 255) です。cv::Scalar(255, 0, 0) は青になります。他のライブラリや HTML カラーコードに慣れていると必ずはまります。

⚠️ 座標が画像範囲外でもエラーにならない

cv::rectangle は座標が画像外にはみ出ても例外を投げません。ただし描画結果が意図どおりにならないだけでなく、cv::Rect を使う場合は幅・高さが負になると内部アサーションで落ちることがあります。検出器からの矩形は描画前に範囲チェックを入れましょう。

// 安全なクランプ例
rect &= cv::Rect(0, 0, img.cols, img.rows);
if (rect.empty()) continue;

⚠️ imread が空 Mat を返した状態で rectangle を呼ぶと落ちる

ファイルパスが誤っていたり、日本語パスを含む場合に img.empty() == true のまま cv::rectangle を呼ぶと assertion エラーでクラッシュします。必ず imread 直後に empty() チェックを入れてください。cv::imread の詳細はcv::imread の使い方【OpenCV/C++】を参照してください。


関連する関数

  • cv::circle — 円を描画する。検出中心点の表示に使う
  • cv::line — 直線を描画する
  • cv::putText — テキストを描画する。矩形ラベルとセットで使うことが多い → 記事へ
  • cv::Mat ROIcv::Rect で切り出した ROI に対して矩形描画を組み合わせる → cv::Mat ROI で画像の一部を切り出す方法
  • cv::imwrite — 描画済みの画像を保存する → cv::imwrite の使い方

rectangle / circle / line をまとめて学びたい場合はOpenCV/C++ rectangle・circle・line の使い方も参考にしてください。


まとめ

  • cv::rectangle は2頂点 (cv::Point) または cv::Rect で矩形を描画できる。
  • thickness = cv::FILLED で塗りつぶし、lineType = LINE_AA でアンチエイリアスが使える。
  • 物体検出結果の可視化では cv::Rect 形式 + cv::putText のラベルと組み合わせるのが定番パターン。

🛠 画像処理のプロが開発するSDK/API

本ブログを運営するスワローインキュベートは、OpenCV ベースのなりすまし判定SDK/API(C++製・OpenCV 4.10)を開発しています。顔認証システムへの組み込み実績多数。

→ なりすまし判定SDK/APIの詳細を見る
→ API仕様書・サンプルコード

タイトルとURLをコピーしました