cv::line の使い方【OpenCV/C++】〜画像に直線を描画する〜
cv::line は2点間に直線を描画する関数です。座標・色・太さ・線種を指定するだけで使えます。
cv::line(img, pt1, pt2, color, thickness, lineType, shift);
動作環境
- OpenCV 4.x
- コンパイル例:
g++ -std=c++17 main.cpp $(pkg-config --cflags --libs opencv4)
環境構築がまだの方は環境構築ガイドを先にどうぞ。
基本の使い方
#include <opencv2/opencv.hpp>
int main()
{
// 500x500 の白い画像を用意
cv::Mat img(500, 500, CV_8UC3, cv::Scalar(255, 255, 255));
// 左上から右下への赤い直線(太さ3)
cv::line(img,
cv::Point(50, 50), // 始点
cv::Point(450, 450), // 終点
cv::Scalar(0, 0, 255), // BGR: 赤
3, // 太さ
cv::LINE_AA); // アンチエイリアス
cv::imshow("line sample", img);
cv::waitKey(0);
return 0;
}
実行結果:
白い 500x500 の画像の左上(50,50)から右下(450,450)へ、
赤色・太さ3のアンチエイリアス直線が表示されます。
コードの解説
cv::Mat img(500, 500, CV_8UC3, cv::Scalar(255, 255, 255))— キャンバスとなる白い画像を生成。実務ではcv::imreadで読み込んだ画像をそのまま渡すことが多いです。cv::Point(50, 50)— ピクセル座標。x(列)が先、y(行)が後 という点に注意。cv::Scalar(0, 0, 255)— OpenCV は BGR 順。赤を指定するには R チャンネル(第3引数)に255を渡します。cv::LINE_AA— アンチエイリアス線種。斜め線や細い線でギザギザが抑えられます。
引数と戻り値
| 引数 | 型 | 説明 |
|---|---|---|
img |
cv::InputOutputArray |
描画先の画像(上書き) |
pt1 |
cv::Point |
始点座標 |
pt2 |
cv::Point |
終点座標 |
color |
cv::Scalar |
BGR カラー |
thickness |
int |
線幅(ピクセル)。デフォルト 1 |
lineType |
int |
線種(後述)。デフォルト cv::LINE_8 |
shift |
int |
座標の小数ビット数。通常 0 |
戻り値: なし(void)
lineType の選択肢
| 定数 | 値 | 説明 |
|---|---|---|
cv::LINE_4 |
4 | 4近傍接続(最速・荒い) |
cv::LINE_8 |
8 | 8近傍接続(デフォルト) |
cv::LINE_AA |
16 | アンチエイリアス(なめらか) |
表示品質を重視するなら cv::LINE_AA を使うのが実務では基本です。保存用途や精度計測用途では cv::LINE_8 で十分なケースもあります。
実践例
実践例1: グリッド線の描画
画像にグリッド(格子線)を引くユーティリティはデバッグや可視化でよく使います。
#include <opencv2/opencv.hpp>
int main()
{
cv::Mat img(480, 640, CV_8UC3, cv::Scalar(30, 30, 30)); // 暗めの背景
const int step = 80; // グリッド間隔(ピクセル)
const cv::Scalar color(100, 100, 100); // グレー
// 縦線
for (int x = 0; x < img.cols; x += step)
cv::line(img, cv::Point(x, 0), cv::Point(x, img.rows - 1), color, 1, cv::LINE_AA);
// 横線
for (int y = 0; y < img.rows; y += step)
cv::line(img, cv::Point(0, y), cv::Point(img.cols - 1, y), color, 1, cv::LINE_AA);
cv::imshow("grid", img);
cv::waitKey(0);
return 0;
}
640x480 の暗い背景に、80px 間隔のグレーのグリッドが表示されます。
実践例2: 検出結果に線分を重ねて可視化
カメラ画像やファイル画像に線分を重ねる典型的なユースケースです。cv::imread で読んだ画像をそのまま渡します。
#include <opencv2/opencv.hpp>
int main()
{
cv::Mat img = cv::imread("input.jpg");
if (img.empty())
{
std::cerr << "画像を読み込めませんでした" << std::endl;
return 1;
}
// 検出ライン(例: 水平基準線)を黄色で描画
int cy = img.rows / 2;
cv::line(img,
cv::Point(0, cy),
cv::Point(img.cols - 1, cy),
cv::Scalar(0, 255, 255), // BGR: 黄色
2,
cv::LINE_AA);
cv::imwrite("output.jpg", img);
std::cout << "保存完了: output.jpg" << std::endl;
return 0;
}
input.jpg の中央に水平な黄色い直線を描画し、output.jpg として保存します。
imread・imwrite の詳しい使い方はこちらの記事も参考にしてください。
– cv::imread の使い方【OpenCV/C++】
– cv::imwrite の使い方【OpenCV/C++】
つまずきポイント
⚠️ 座標が画像範囲外でもクラッシュしない
cv::line は始点・終点が画像サイズを超えていても assertion エラーにはなりません。OpenCV 内部でクリッピングされるため、意図しない座標を渡しても描画は実行されます。座標計算にバグがあっても気づきにくいので、デバッグ時は std::cout などで座標値を確認してください。
⚠️ BGR と RGB の混同
OpenCV の cv::Scalar は BGR 順です。cv::Scalar(255, 0, 0) は赤ではなく青になります。Web や他ライブラリで RGB 表記に慣れていると嵌まりやすいポイントです。
⚠️ グレースケール画像への描画
CV_8UC1(グレースケール)画像に cv::Scalar(0, 0, 255) のようなカラー値を渡すと、第1引数の値(ここでは 0)のみ使われ黒い線になります。カラーの線を引きたい場合は事前に cv::cvtColor で BGR 変換してから描画してください。
関連する関数
cv::line は図形描画関数群の一つです。あわせて使うことが多い関数を紹介します。
- cv::rectangle — 矩形を描画
- cv::circle — 円を描画
- cv::putText — テキストを描画
これらをまとめて確認したい場合は cv::rectangle・cv::circle・cv::line の使い方まとめ も参照してください。
テキスト描画については cv::putText の使い方【OpenCV/C++】 で詳しく解説しています。
まとめ
cv::line(img, pt1, pt2, color, thickness, lineType)の6引数で直線を描画できます。- 品質が重要な場面では
cv::LINE_AA(アンチエイリアス)を指定してください。 - BGR 順と座標範囲外クリッピングの挙動を把握しておくと実装で迷いません。
🛠 画像処理のプロが開発するSDK/API
本ブログを運営するスワローインキュベートは、OpenCV ベースのなりすまし判定SDK/API(C++製・OpenCV 4.10)を開発しています。顔認証システムへの組み込み実績多数。

