OpenCV/C++で画像処理入門 vol.3 〜画像に図形を描画してみよう〜
2019.01.11
こんにちは、代表の大野です。
OpenCV/C++で画像処理入門シリーズの第3回目です。
前回は、画像を白黒にしたり、画像を切り取る操作を
OpenCVを通じて行いました。
今日は、画像に図形を描画する内容を書いていきたいと思います。
環境があれば、ぜひみなさんも一緒に
プログラムを書いて体験してみてくださいね。
バックナンバー
vol1. 画像を表示してみよう
vol2. 画像を加工してみよう
今回やること
- 画像に丸を描画してみよう
- 画像に長方形を描画してみよう
環境
マシン :mac OS Mojave 10.14.1
言語 :C++
ライブラリ:OpenCV 3.4.3
コンパイラ:Clang / LLVM
準備 & 画像の用意
OpenCVのインストールなどは
バックナンバーから、参考にしてください。
今回のサンプルは
ティータイムスワワちゃんを用いることにします。
ティータイム スワワちゃん(teatimesuwawachan.jpg)
width : 600px
height : 600px
では、さっそくいってみましょう。
画像に丸を描画してみよう
スワワちゃんの好物は、アールグレイの紅茶です。
休憩時間によく飲んでいるようなのですが、
今回は、せっかくなので
アールグレイの入ったティーポットに焦点を当てていきましょう。
こちらの画像は
縦横600pxの正方形の画像です。
前回ご紹介したcv::Rectであれば
左上頂点座標を取得すればよかったのですが、
丸を描く場合は、
どこの座標を円の中心にして、半径何pxの円を描くか
という指定が必要になります。
ティーポットのだいたいの中心座標を
調べてみると
(macであればプレビューなどで確認できます)
(x, y) = (95, 355)
あたりかなとわかります。
半径は95pxぐらいかな。
では、試しに、
ティーポットを綺麗に囲えているかどうか
実際に丸を描いてみましょう。
わかりやすいように青枠の丸にしてみたいと思います。
<ソースプログラム>
circle.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #include <opencv2/opencv.hpp> int main() { cv::Mat img, dst; img = cv::imread("teatimesuwawachan.jpg"); dst = img.clone(); cv::circle(dst, cv::Point(95,355), 95, cv::Scalar(255,0,0), 5); cv::imshow("input", img); cv::imshow("output", dst); cv::waitKey(0); return 0; } |
さて、今回もプログラムについて、
順々に説明していきたいと思います。
1 2 3 4 | cv::Mat img, dst; img = cv::imread("teatimesuwawachan.jpg"); dst = img.clone(); |
今回もわかりやすいように、cv::Mat型のオブジェクトを
入力画像用のimgと出力画像用のdstの2つを宣言しておきました。
imgには、サンプル画像である画像ファイルを
cv::imread()関数で取り込みます。
さて、ここで新しくclone()というものが出てきました。
clone()は、cv::Matクラスで定義されている関数で
元のオブジェクトを画素、データ型、サイズなどを
すべてコピーするための関数です。
また、clone()はコピー元の画像を変更しないようにもなっているため
入力画像と出力画像の違いを明確に見たい場合には、
ぜひclone()を使ってみてください。
ということで、今回のソースコードでは、
imgに取り込まれているサンプル画像データを
dstにそっくりそのままコピーしていることになります。
この時点では、
imgもdstも中身は、全く同じ状態です。
1 | cv::circle(dst, cv::Point(95,355), 95, cv::Scalar(255,0,0), 5); |
さて、肝心の丸を描く部分です。
circle()関数と、わかりやすい名前の関数なので
二度と忘れることもないでしょう。
大事なのは引数ですね。
第一引数 dst … 丸を描く対象となるcv::Mat
第二引数 cv::Point(95,355) … 丸を描く中心座標(x座標が95, y座標が355)
第三引数 95 … 半径サイズ(px)
第四引数 cv::Scalar(255,0,0) … BGRカラー指定(blueが255, greenが0, redが0)
第五引数 5 … 丸枠の線の太さ
第一引数は、出力画像用のdstを入れればOK。
第二引数は、OpenCVで2次元座標を扱うcv::Pointクラスで、座標を指定しましょう。
cv::Point()クラスは、第一引数がx座標(int型)、第二引数がy座標(int型)になります。
第三引数は、描く丸の半径サイズです。直径ではないところに注意。
第四引数は、丸枠の色の指定を行います。cv::Scalarは、値を配列のように格納するもので
ここでは、BGR(青緑赤)の順に256階調で、指定しましょう。
HTML/CSSに慣れている人は、RGBの順で指定しがちですが、
あくまで、「BGR」の順なので気をつけましょう。
今回は青枠にするので、B=255(max)、G=0、R=0になります。
最後に第五引数で、丸枠の線の太さを指定します。
今回は少々目立つように5pxにしました。
では実際にビルドをして実行してみましょう。
<ビルド & 実行>
ターミナル など
1 2 | c++ $(pkg-config --cflags --libs opencv) circle.cpp ./a.out |
dst(output)のほうには、ちゃんとティーポットに
青枠で丸が描かれていますね。
画像に長方形を描画してみよう
同じ要領で今度は、ティーポットを長方形で囲んでみたいと思います。
長方形を描く場合は、
長方形で囲いたい部分の
- 左上の頂点のxy座標
- 右下の頂点のxy座標
の2つが必要になります。
ティーポットを囲うには、
左上座標が、
(x, y) = (0, 295)
右下座標が
(x, y) = (180, 430)
ぐらいですかね。
では、プログラムを見てみましょう。
<ソースプログラム>
rectangle.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #include <opencv2/opencv.hpp> int main() { cv::Mat img, dst; img = cv::imread("teatimesuwawachan.jpg"); dst = img.clone(); cv::rectangle(dst, cv::Point(0,295), cv::Point(180,430), cv::Scalar(255,0,0), 5); cv::imshow("input", img); cv::imshow("output", dst); cv::waitKey(0); return 0; } |
先ほどの、「circle」が「rectangle」に変わっただけです。
cv::rectangleもその名の通り、
長方形を描画するものです。
第一引数 dst … 出力先のcv::Mat
第二引数 cv::Point( 0,295) … 描く長方形の左上の座標
第三引数 cv::Point(180,430) … 描く長方形の右下の座標
第四引数 cv::Scalar(255,0,0) … BGRカラー指定
第五引数 5 … 丸枠の線の太さ
第二引数、第三引数には
先ほど説明した、cv::Pointで、長方形の左上と右下の座標の値を決定します。
第二引数が、左上の頂点座標、第三引数が右下の頂点座標です。
対角線を引けるように指定するということですね。
あとは、丸のときと同じ、第四引数と第五引数を用いて
青枠で太さを5にしてあります。
ではビルドをして実行してみましょう。
<ビルド & 実行>
ターミナルなど
1 2 | c++ $(pkg-config --cflags --libs opencv) rectangle.cpp ./a.out |
今度は、ちゃんとティーポットを囲んだ
長方形が描画されているのがわかりますね?
まとめ
さて、今回は、丸と長方形を描画してみましたが
OpenCVには他にも
線を描画 line()
矢印を描画 arrowedLine()
楕円を描画 ellipse()
なども描画できたりするので
どんな引数をとるのかを調べながら
実装してみると面白いと思います。
というわけで、今日はここまで。
OpenCV/C++で画像処理入門シリーズ
vol1. 画像を表示してみよう
vol2. 画像を加工してみよう
↓↓↓ぜひチェックしてください
~提供中のヒューマンセンシング技術~
◆人物検出技術
歩行者・来店者数計測やロボット搭載も
https://humandetect.pas-ta.io
◆視線検出技術
アイトラッキングや次世代UIに
https://eyetrack.pas-ta.io
◆生体判定技術
eKYC・顔認証のなりすまし対策を!
https://bio-check.pas-ta.io
◆目検出技術
あらゆる目周りデータを高精度に取得
https://pupil.pas-ta.io
◆音声感情認識技術
会話から怒りや喜びの感情を判定
https://feeling.pas-ta.io
◆虹彩認証技術
目の虹彩を利用した生体認証技術
https://iris.pas-ta.io