OpenCV/C++で画像処理入門 vol.2 〜画像を加工してみよう〜

2018.12.28

 

 

こんにちは、代表の大野です。

OpenCV/C++で画像処理入門シリーズの第2回目です。

 

前回は、画像処理の前準備として
まずは、OpenCV/C++を使って、
画像を表示するところをやりました。

 

今回は、いよいよ画像を加工する簡単な処理を
プログラムを交えてご紹介することにします。

 

環境があれば、ぜひみなさんも一緒に
プログラムを書いて体験してみてください。

 

バックナンバー


OpenCV/C++で画像処理入門 vol.1 〜画像を表示してみよう〜

 

 

今回やること


1. 画像を白黒にしてみよう

2. 画像を切り取ってみよう

 

環境


マシン  :mac OS Mojave 10.14.1
言語   :C++
ライブラリ:OpenCV 3.4.3
コンパイラ:Clang / LLVM

 

準備 & 画像の用意


OpenCVのインストールなどは
バックナンバーから、参考にしてください。

https://swallow-incubate.com/archives/blog/20181221/

 

今回も、サンプルはスワワちゃんに登場してもらいます。

 

いんきゅべーと秘書 スワワちゃん(suwawachan.jpg)

 

 

1.画像を白黒にしてみよう


さて、今日はまず最初に
画像を白黒にする処理をやってみましょう。

 

スワワちゃんは
白と黒、赤と黄色の4色といった
非常にシンプルな色構成にされています。

 

果たして白黒になると
かわいさは失われてしまうのでしょうか?(笑)

 

では、ソースプログラムを見てみましょう。

 

<ソースプログラム>

mono.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <opencv2/opencv.hpp>

int main()
{
  cv::Mat img;
  img = cv::imread("suwawachan.jpg");

  cv::cvtColor(img, img, cv::COLOR_BGR2GRAY);

  cv::imshow("title", img);
  cv::waitKey(0);

  return 0;
}

前回のソースプログラムと
ほとんど同じです。

 

違うのは、cv::cvtColor()関数の行が挿入されています。

 

そう、これが実際に画像を
白黒に変える処理を行なってくれます。

 

ちょっと詳しく説明すると、

 

cvtColor()関数は、色を変える関数です。

 

名前もその名の通り
Convert Color(色を変える)
ですね。

1
 cv::cvtColor(img, img, cv::COLOR_BGR2GRAY);

 

第一引数には、入力画像となるcv::Mat
第二引数には、出力画像となるcv::Mat

 

ここでは、第一引数も第二引数も
ともにimgにしているので、
imgを上書きする形になっています。

 

大事なのが、第三引数で、
RGBをグレースケールにするように指定する定数です。

 

これもずばり名前の通り

 

COLOR(色を)  BGR(RGBから) to GRAY(グレースケールに)

 

なので、分かり易すぎるんですが、

 

RGBが、「BGR」になっていることや
from to のto が「2」になっているので注意です。
(実際には、cv::COLOR_RGB2GRAYでも動くと思いますが…)

 

<ビルド & 実行>
といったところで、
先ほどのソースファイルを
ファイルに保存したところで

 

ターミナルから、ビルドをして実行してみましょう。

 

ターミナル

1
2
c++ $(pkg-config --cflags --libs opencv) mono.cpp
./a.out

 

<表示>

 

こんなウィンドウが立ち上がったでしょうか?

 

ちゃんとグレースケールの画像になっていますね。

 

色の成分は失われていますが
かわいさの成分は失われていません。

 

おおむね成功です。

 

 

2.画像を切り取ってみよう


続いて、画像を一定のサイズで
切り取る処理をやってみましょう。

 

 

サンプルとなるスワワちゃんの画像は
全身が表示されていますが、

 

今回は、ポニーテールリボンだけ
切り取ってみたいと思います。

 

では、ソースプログラムを見てみましょう。

 

 

<ソースプログラム>

cutout.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <opencv2/opencv.hpp>

int main()
{
  cv::Mat img, dst;
 
  img = cv::imread("suwawachan.jpg");
  dst = cv::Mat(img, cv::Rect(130,0,200,140));

  cv::imshow("input", img);
  cv::imshow("output", dst);
  cv::waitKey(0);

  return 0;
}

 

今回は、入力画像用cv::Matとは別に
出力画像用cv::Matである「dst」を新たに宣言しました。(コンマ区切りで同型宣言です。)

1
 cv::Mat img, dst;

 

また、imgを読み込んだ次の行に
画像を切り取る処理が書かれています。

1
 dst = cv::Mat(img, cv::Rect(130,0,200,140));

 

ここで、はじめて出てきたのが
このcv::Rectです。

 

cv::Rectは、長方形を表す型だと思ってください。
引数が4つ指定されていますが、

 

第一引数(130) … 始点となるx座標
第二引数( 0) … 始点となるy座標
第三引数(200) … 横幅(width)
第四引数(140) … 縦幅(height)

 

になります。

 

ここでは、cv::Rectは

 

「画像座標(130,0)の位置を始点として
 横200px(右方向)、縦140px(下方向)」

 

を指定していることになります。

 

 

では実際にビルドをして実行してみましょう。

 

<ビルド & 実行>

 

ターミナル

1
2
c++ $(pkg-config --cflags --libs opencv) cutout.cpp
./a.out

 

 

outputのタイトルになっている方で、
無事ポニテリボンだけ切り取られましたね。

 

普段は、フォトショップなどで
がんばって画像を切り取っている人は

 

今日からは、

 

「OpenCV/C++で画像切り取り」

 

をやると
オフィスでドヤれること間違いなしです。

 

時間がある人は、
今度は自分で、
メガネ部分だけ切り取る処理をやってみてください。

 

 

まとめ


さて、この記事を持ちまして、
当社からの2018年のブログは最後となります。

 

スタッフ一同でお届けしたブログはいかがでしたでしょうか?
要望や改善点などあれば、ぜひお知らせくださいね。

 

当社は、
明日2018年12月29日(土)より
2019年01月06日(日)まで
年末年始休業とさせていただきます。

 

本年も、当社ならびに当ブログにご愛顧いただき
ありがとうございました。

 

来年もどうぞよろしくお願いいたします。

 

みなさま、よいお年を!


Top