cv::Scalar の使い方【OpenCV/C++】〜色・スカラー値の型を完全解説〜
cv::Scalar は OpenCV で色や数値をまとめて渡すための基本型です。cv::rectangle や cv::circle に色を指定するとき、cv::Mat::setTo で画像を塗りつぶすとき、どこにでも登場します。
最小の使い方はこうです。
cv::Scalar blue(255, 0, 0); // BGR 順: Blue=255
cv::Scalar white(255, 255, 255); // グレースケール・カラー共通
動作環境
- OpenCV 4.x(4.5 以降推奨)
- C++17
- ビルド例:
g++ -std=c++17 main.cpp `pkg-config --cflags --libs opencv4` -o main
基本の使い方
#include <opencv2/opencv.hpp>
#include <iostream>
int main()
{
// --- 1. Scalar の初期化 ---
cv::Scalar gray(128); // 1チャンネル: 輝度128
cv::Scalar bgr(255, 0, 0); // 3チャンネル: 青
cv::Scalar bgra(0, 255, 0, 128); // 4チャンネル: 緑+アルファ128
// --- 2. 要素へのアクセス ---
std::cout << "B=" << bgr[0]
<< " G=" << bgr[1]
<< " R=" << bgr[2] << std::endl;
// --- 3. Mat を Scalar で塗りつぶす ---
cv::Mat img(300, 400, CV_8UC3);
img.setTo(cv::Scalar(200, 200, 200)); // 明るいグレーで初期化
// --- 4. 図形描画に使う ---
cv::rectangle(img,
cv::Point(50, 50), cv::Point(350, 250),
cv::Scalar(0, 0, 255), // 赤
3); // 線幅3px
cv::circle(img,
cv::Point(200, 150), 80,
cv::Scalar(255, 128, 0), // 水色
cv::FILLED);
// --- 5. 結果確認(ファイル保存) ---
if (!cv::imwrite("output.png", img)) {
std::cerr << "保存失敗" << std::endl;
return 1;
}
std::cout << "output.png を保存しました" << std::endl;
return 0;
}
実行結果:
B=255 G=0 R=0
output.png を保存しました
output.png を開くと、明るいグレーの背景に赤い矩形と水色の塗りつぶし円が描かれた 400×300 の画像が確認できます。
各処理の解説
| 行 | 内容 |
|---|---|
cv::Scalar gray(128) |
要素1つだけ渡すと残り3つは自動で 0 になる |
bgr[0] |
添字アクセスで各チャンネルを取得。型は double |
img.setTo(cv::Scalar(...)) |
Mat 全画素を指定値で上書き。チャンネル数を揃える必要あり |
cv::Scalar(0, 0, 255) |
OpenCV は BGR 順。RGB と R/B が逆なので注意 |
cv::Scalar(255, 128, 0) |
引数は double で渡し、描画時に uchar へ変換される |
引数と戻り値
cv::Scalar は cv::Scalar_<double> の typedef です。コンストラクタは以下の通りです。
| コンストラクタ | 説明 |
|---|---|
Scalar() |
全要素 0.0 で初期化 |
Scalar(double v0) |
[v0, 0, 0, 0] |
Scalar(double v0, double v1, double v2=0, double v3=0) |
最大4要素まで指定 |
Scalar::all(double v) |
全要素を同じ値で初期化する静的メソッド |
要素は内部的に double val[4] に格納されます。添字 [0]〜[3] で読み書き可能です。
よく使うファクトリ
cv::Scalar::all(0) // 全チャンネルをゼロに(黒・消去用)
cv::Scalar::all(255) // 全チャンネルを255に(白・マスク用)
実践例
1. チャンネル数に合わせて Scalar を切り替える
グレースケール画像とカラー画像の両方に対応した描画関数を書く場合、チャンネル数で Scalar を分岐させます。
#include <opencv2/opencv.hpp>
#include <iostream>
// 画像のチャンネル数に合った「白」を返す
cv::Scalar makeWhite(const cv::Mat& img)
{
if (img.channels() == 1) {
return cv::Scalar(255);
} else {
return cv::Scalar(255, 255, 255);
}
}
int main()
{
cv::Mat gray(200, 200, CV_8UC1, cv::Scalar(0));
cv::Mat color(200, 200, CV_8UC3, cv::Scalar(0, 0, 0));
// 両方に同じロジックで白矩形を描画
cv::rectangle(gray, cv::Point(20, 20), cv::Point(180, 180), makeWhite(gray), 2);
cv::rectangle(color, cv::Point(20, 20), cv::Point(180, 180), makeWhite(color), 2);
cv::imwrite("gray_rect.png", gray);
cv::imwrite("color_rect.png", color);
std::cout << "gray_rect.png / color_rect.png を保存しました" << std::endl;
return 0;
}
実行すると、gray_rect.png には白い矩形枠が、color_rect.png にも同様の白い矩形枠が描かれた画像が保存されます。
2. Mat の特定チャンネルを Scalar で取得する
cv::mean の戻り値は cv::Scalar です。4チャンネル分の平均輝度が一度に取得できます。
#include <opencv2/opencv.hpp>
#include <iostream>
int main()
{
cv::Mat img = cv::imread("input.png");
if (img.empty()) {
std::cerr << "画像を読み込めませんでした" << std::endl;
return 1;
}
// 画像全体の BGR 各チャンネル平均
cv::Scalar meanVal = cv::mean(img);
std::cout << "平均 B=" << meanVal[0]
<< " G=" << meanVal[1]
<< " R=" << meanVal[2] << std::endl;
return 0;
}
実行すると、各チャンネルの平均輝度が以下のように出力されます。
平均 B=112.4 G=98.7 R=87.2
(数値は画像によって異なります)
つまずきポイント
⚠️ BGR と RGB の順序を間違える
OpenCV は BGR 順です。cv::Scalar(255, 0, 0) は赤ではなく青です。Web や他のライブラリから色コードを持ってくるときは必ず R と B を入れ替えてください。
// HTML #FF0000(赤)を OpenCV に渡す場合
cv::Scalar red(0, 0, 255); // ✅ BGR 順
cv::Scalar red(255, 0, 0); // ❌ これは青になる
⚠️ チャンネル数の不一致で assertion が発生する
CV_8UC1 の Mat に cv::Scalar(255, 255, 255) を setTo しても動作はしますが、cv::line や cv::rectangle の描画では内部チェックが走り、デバッグビルドで assertion が出ることがあります。チャンネル数に合った Scalar を渡すのが安全です。
⚠️ Scalar の要素型は double
cv::Scalar の内部型は double です。CV_8UC3 の Mat に使う場合、最終的に uchar(0〜255)にクランプされます。256 や -1 を渡しても assertion にはなりませんが、意図しない色になります。
cv::Scalar s(300, -10, 128);
// CV_8UC3 に setTo すると → [255, 0, 128] に飽和する
関連する関数
cv::mean— 画像の平均値をcv::Scalarで返すcv::sum— 画素値の合計をcv::Scalarで返すcv::rectangle/cv::circle/cv::line—cv::Scalarで色を指定する描画関数cv::Mat::setTo— Mat 全体をcv::Scalar値で塗りつぶす
まとめ
cv::Scalar は OpenCV の色・数値指定の基本型で、最大4チャンネルの double 値を保持します。OpenCV は BGR 順であること、内部型が double であることを押さえておけば、描画・初期化・統計関数のどこでも迷わず使えます。
🛠 画像処理のプロが開発するSDK/API
本ブログを運営するスワローインキュベートは、OpenCV ベースのなりすまし判定SDK/API(C++製・OpenCV 4.10)を開発しています。顔認証システムへの組み込み実績多数。

