概要
- macOS に OpenCV 4.3 をインストール
- OpenCV 4.3 と C++ で基本的な処理を実行する
- Hello World 画像生成
- 画像ファイルをウィンドウ表示
- カメラからの映像をリアルタイムにエッジ抽出
- 画像から顔の位置を検出
環境
- macOS Catalina
- Clang 11
$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.15.4
BuildVersion: 19E287
$ clang++ --version
Apple clang version 11.0.3 (clang-1103.0.32.59)
Target: x86_64-apple-darwin19.4.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
インストール
Homebrew でインストール
$ brew install opencv
$ brew info opencv
opencv: stable 4.3.0 (bottled)
Open source computer vision library
https://opencv.org/
/usr/local/Cellar/opencv/4.3.0 (771 files, 224.5MB) *
ヘッダファイルの場所
$ ls -C /usr/local/include/opencv4/opencv2 | expand
alphamat.hpp highgui.hpp sfm.hpp
aruco img_hash shape
aruco.hpp img_hash.hpp shape.hpp
bgsegm.hpp imgcodecs stereo
bioinspired imgcodecs.hpp stereo.hpp
bioinspired.hpp imgproc stitching
calib3d imgproc.hpp stitching.hpp
calib3d.hpp intensity_transform.hpp structured_light
ccalib line_descriptor structured_light.hpp
ccalib.hpp line_descriptor.hpp superres
core ml superres.hpp
core.hpp ml.hpp surface_matching
core_detect.hpp objdetect surface_matching.hpp
cvconfig.h objdetect.hpp text
datasets opencv.hpp text.hpp
dnn opencv_modules.hpp tracking
dnn.hpp optflow tracking.hpp
dnn_superres.hpp optflow.hpp video
dpm.hpp phase_unwrapping video.hpp
face phase_unwrapping.hpp videoio
face.hpp photo videoio.hpp
features2d photo.hpp videostab
features2d.hpp plot.hpp videostab.hpp
flann quality xfeatures2d
flann.hpp quality.hpp xfeatures2d.hpp
freetype.hpp rapid.hpp ximgproc
fuzzy reg ximgproc.hpp
fuzzy.hpp rgbd xobjdetect.hpp
gapi rgbd.hpp xphoto
gapi.hpp saliency xphoto.hpp
hfs.hpp saliency.hpp
highgui sfm
ライブラリファイルの場所
$ ls /usr/local/lib | grep libopencv | grep a$ | column -c 80 | expand
libopencv_alphamat.a libopencv_objdetect.a
libopencv_aruco.a libopencv_optflow.a
libopencv_bgsegm.a libopencv_phase_unwrapping.a
libopencv_bioinspired.a libopencv_photo.a
libopencv_calib3d.a libopencv_plot.a
libopencv_ccalib.a libopencv_quality.a
libopencv_core.a libopencv_rapid.a
libopencv_datasets.a libopencv_reg.a
libopencv_dnn.a libopencv_rgbd.a
libopencv_dnn_objdetect.a libopencv_saliency.a
libopencv_dnn_superres.a libopencv_sfm.a
libopencv_dpm.a libopencv_shape.a
libopencv_face.a libopencv_stereo.a
libopencv_features2d.a libopencv_stitching.a
libopencv_flann.a libopencv_structured_light.a
libopencv_freetype.a libopencv_superres.a
libopencv_fuzzy.a libopencv_surface_matching.a
libopencv_gapi.a libopencv_text.a
libopencv_hfs.a libopencv_tracking.a
libopencv_highgui.a libopencv_video.a
libopencv_img_hash.a libopencv_videoio.a
libopencv_imgcodecs.a libopencv_videostab.a
libopencv_imgproc.a libopencv_xfeatures2d.a
libopencv_intensity_transform.a libopencv_ximgproc.a
libopencv_line_descriptor.a libopencv_xobjdetect.a
libopencv_ml.a libopencv_xphoto.a
Hello World 画像生成
ソースコード: hello.cpp
#include <opencv2/opencv.hpp>
int main(int argc, char* argv[]) {
// 画像データを入れるオブジェクト
cv::Mat image(256, 256, CV_8UC3);
// テキストを描画する
cv::String text = "Hello, world";
cv::Point org(0, 100);
int fontFace = cv::FONT_HERSHEY_SIMPLEX;
double fontScale = 1.0;
cv::Scalar color(0, 255, 127); // Blue, Green, Red
cv::putText(image, text, org, fontFace, fontScale, color);
// 画像を出力する
cv::String path = "hello-world.png";
cv::imwrite(path, image);
return 0;
}
OpenCV 4 を使うには C++11 準拠のコンパイラが必要。
clang++ でコンパイルする際には -std=c++11 オプションを付ける。
OpenCV is now C++11 library and requires C++11-compliant compiler. Minimum required CMake version has been raised to 3.5.1.
必要なライブラリファイルを -l オプションで指定する必要がある。
- opencv_core (cv::Mat など基本機能を使う際に必要)
- opencv_imgproc (cv::putText など描画機能を使う際に必要)
- opencv_imgcodecs (cv::imwrite など画像入出力機能を使う際に必要)
hello.cpp のビルドを実行。
$ clang++ -std=c++11
-I/usr/local/include/opencv4 \
-L/usr/local/lib/opencv4 \
-lopencv_core -lopencv_imgproc -lopencv_imgcodecs \
hello.cpp
生成された a.out を実行すると Hello World 画像が出力される。
$ ./a.out
画像ファイルをウィンドウに表示
ソースコード: showimage.cpp
#include <iostream>
#include <string>
#include <opencv2/highgui.hpp>
int main(int argc, char* argv[]) {
// コマンドライン引数を読む
if (argc < 2) {
std::cerr << "画像ファイルのパスを指定してください。" << std::endl;
return -1;
}
std::string path = argv[1];
try {
// ファイルから画像を読み込む
cv::Mat image = cv::imread(path);
// 画像をウィンドウに表示する
cv::String winname = path;
cv::imshow(winname, image);
// キーが押されるまで待つ
cv::waitKey();
} catch (const cv::Exception& e) {
const char* err_msg = e.what();
std::cerr << "エラー発生: " << err_msg << std::endl;
return -1;
}
return 0;
}
ウィンドウ表示機能 (cv::imshow) を使うので opencv_highgui ライブラリをリンクしてビルドする。
$ clang++ -std=c++11 \
-I/usr/local/include/opencv4 \
-L/usr/local/lib/opencv4 \
-lopencv_core -lopencv_imgcodecs -lopencv_highgui \
showimage.cpp
生成された a.out を実行すると指定した画像がウィンドウ表示される。
$ ./a.out hello-world.png
カメラからの映像をリアルタイムにエッジ抽出
公式ドキュメント OpenCV: Introduction に載っているサンプルコードをほぼそのまま使用する。
ソースコード: videocapture.cpp
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
using namespace cv;
int main(int, char**) {
VideoCapture cap(0);
if(!cap.isOpened()) return -1;
Mat frame, edges;
namedWindow("edges", WINDOW_AUTOSIZE);
for (;;) {
cap >> frame;
// 色をグレースケールに
cvtColor(frame, edges, COLOR_BGR2GRAY);
// ガウスフィルターで画像をぼかす
GaussianBlur(edges, edges, Size(7,7), 1.5, 1.5);
// キャニー法によるエッジ抽出
Canny(edges, edges, 0, 30, 3);
// ウィンドウを表示
imshow("edges", edges);
if(waitKey(30) >= 0) break;
}
return 0;
}
Video I/O 機能を使うので opencv_videoio ライブラリをリンクしてビルドする。
$ clang++ -std=c++11 \
-I/usr/local/include/opencv4 \
-L/usr/local/lib/opencv4 \
-lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_videoio \
videocapture.cpp
生成された a.out を実行すると、カメラからの映像をリアルタイムにエッジ抽出したものがウィンドウに表示される。
$ ./a.out hello-world.png
画像から顔の位置を検出
ソースコード: facedetect.cpp
#include <iostream>
#include <string>
#include <vector>
#include <opencv2/opencv.hpp>
int main(int argc, char* argv[]) {
// コマンドライン引数を読む
if (argc < 3) {
std::cerr << "画像ファイルのパスを指定してください。" << std::endl;
return -1;
}
std::string input_image_path = argv[1];
std::string output_image_path = argv[2];
// 画像を読み込む
// アルファチャンネル付きに対応するため IMREAD_UNCHANGED を使う
cv::Mat input_image = cv::imread(input_image_path, cv::IMREAD_UNCHANGED);
// Haar 特徴ベースのカスケード分類器による物体検出の準備
// 顔検出用のカスケード分類器を使用
std::string face_cascade_name =
"/usr/local/share/opencv4/haarcascades/haarcascade_frontalface_alt.xml";
cv::CascadeClassifier face_cascade;
if (!face_cascade.load(face_cascade_name)) {
std::cerr << "分類器の読み込みに失敗しました。" << std::endl;
return -1;
};
// 顔を検出
std::vector<cv::Rect> faces;
face_cascade.detectMultiScale(input_image, faces);
// 出力画像データを入れるオブジェクト
// アルファチャンネル付きに対応するため CV_8UC4 を使う
// CV_<bit-depth>{U|S|F}C(<number_of_channels>)
// CV_8U: ビット深度=符号なし8ビット整数(0〜255)
// C4: チャンネル数=4
cv::Mat output_image(input_image.size(), CV_8UC4);
// 入力画像データを出力画像データにコピー
input_image.copyTo(output_image);
for (size_t i=0; i<faces.size(); i++) {
// 検出した顔の座標を出力
std::cout << "Face: " << faces[i] << std::endl;
// 顔の位置に楕円を描画
cv::Point center(faces[i].x + faces[i].width / 2, faces[i].y + faces[i].height / 2);
cv::Size size(faces[i].width / 2, faces[i].height / 2);
cv::Scalar color(255, 0, 255, 255); // Blue, Green, Red, Alpha
double angle = 0;
double startAngle = 0;
double endAngle = 360;
int thickness = 4;
cv::ellipse(output_image, center, size, angle, startAngle, endAngle, color, thickness);
}
// 画像を出力
cv::imwrite(output_image_path, output_image);
return 0;
}
物体検出機能を使うので opencv_objdetect ライブラリをリンクしてビルドする。
$ clang++ -std=c++11 \
-I/usr/local/include/opencv4 \
-L/usr/local/lib/opencv4 \
-lopencv_core -lopencv_imgcodecs -lopencv_objdetect -lopencv_imgproc \
facedetect.cpp
生成された a.out の引数に入力画像ファイルパスと出力画像ファイルパスを指定して実行する。
いくつかの画像で試す。
File:Lenna (test image).png - Wikipedia
$ ./a.out lenna.png lenna-output.jpg
Face: [175 x 175 from (215, 202)]
これでも糖質制限ダイエット中の三銃士を連れてきたよ|無料の写真素材はフリー素材のぱくたそ
$ ./a.out 150711109603_TP_V.jpg 150711109603_TP_V-output.jpg
Face: [133 x 133 from (1115, 151)]
Face: [187 x 187 from (681, 116)]
カルビを焼く自分を想像する自分を想像する自分を想像する看護師 | 看護師フリー写真素材サイト スキマナース
$ ./a.out cut32_karubi2-1200x801.jpg cut32_karubi2-1200x801-output.jpg
Face: [66 x 66 from (714, 108)]
Face: [97 x 97 from (473, 181)]
Face: [148 x 148 from (98, 273)]
集合している人たちのイラスト(世界) | かわいいフリー素材集 いらすとや
$ ./a.out group_young_world.png group_young_world-output.png
Face: [292 x 292 from (729, 165)]
Face: [295 x 295 from (431, 177)]
Face: [249 x 249 from (997, 354)]
参考資料
- OpenCV 4.3.0
- OpenCV: Introduction
- OpenCV: Basic Drawing
- OpenCV: Drawing Functions
- OpenCV: Image file reading and writing
- OpenCV: High-level GUI
- OpenCV: cv::Mat Class Reference
- OpenCV: cv::CascadeClassifier Class Reference
- 第1回 OpenCVとは? 最新3.0の新機能概要とモジュール構成 (1/2):OpenCV入門【3.0対応】 - @IT
- 第5回 初めてのOpenCV開発 ― coreモジュール【OpenCV 3.1.0】 (1/2):OpenCV入門【3.0対応】 - @IT