こんにちは!
以前、Pythonで線画を作ってみるという記事を書きました。
Python以外にJava、C++でも同様のことができるようなので、C++で実装してみます。
要件
・カメラを起動する
・エッジを抽出する
・画像として保存する
環境構築
端末はMacbook Proです。
C++はすでに使える状態なので、OpenCVをインストールします。
brew install opencv
さあ、やるぞ!と気合を入れていたものの、OpenCVのインストールが終わりません。
依存関係のライブラリもインストールしているので、かなり時間がかかるようです。
結局、40分くらいでやっと終わりました。
コード
今回実装したコードです。
4枚保存したら終了するようにしました。
#include <opencv2/opencv.hpp>
#include <iostream>
int main() {
// カメラをオープン
cv::VideoCapture capture(0);
if (!capture.isOpened()) {
std::cerr << "カメラが開けません。" << std::endl;
return -1;
}
int frame_count = 0;
int saved_images = 0;
// カメラがオープンしている間ループ
while (saved_images < 4) {
// フレームをキャプチャ
cv::Mat frame;
capture >> frame;
if (frame.empty()) {
std::cerr << "フレームの取得に失敗しました。" << std::endl;
break;
}
// グレースケールに変換
cv::Mat gray;
cv::cvtColor(frame, gray, cv::COLOR_BGR2GRAY);
// コントラストの調整
cv::equalizeHist(gray, gray);
// ガウシアンブラーの適用
cv::GaussianBlur(gray, gray, cv::Size(5, 5), 0);
// エッジ検出で線画を生成
cv::adaptiveThreshold(gray, gray, 255, cv::ADAPTIVE_THRESH_MEAN_C, cv::THRESH_BINARY, 11, 7);
// 生成した画像を表示
cv::imshow("Line Drawing Camera", gray);
// 10フレームごとに画像を保存
if (frame_count % 10 == 0) {
std::string filename = "line_drawing_" + std::to_string(frame_count) + ".jpg";
cv::imwrite(filename, gray);
std::cout << filename << " を保存しました。" << std::endl;
saved_images++;
}
frame_count++;
// 'q'が押されたらループを抜ける
if (cv::waitKey(1) == 'q') {
break;
}
}
// カメラをリリースしてウィンドウを閉じる
capture.release();
cv::destroyAllWindows();
return 0;
}
こちらもシンプルなコードですね。
コンパイル
C++なので、コンパイルが必要です。
以下のコマンドを実行。
g++ -std=c++11 -o line_drawing line_drawing.cpp `pkg-config --cflags --libs opencv4`
$ ls
line_drawing* line_drawing.cpp
実行ファイルが生成されました。
実行
それでは、実行してみます!
./line_drawing
...あれ?起動しない。
エラーは発生していないので、時間がかかっているだけでしょうか。
しばらく待ってみます。。
Pythonと同様に、線画になってますね!
相変わらずメガネはくっきりです。
まとめ
今回は、C++でOpenCVを利用してみました。
かなり久しぶりにC++をさわりましたが、様々な言語で実装してみるのも面白いですね
ラズパイとかを使って、線画を撮影できるカメラがあってもいいな、と思いました。
引き続き、色々とチャレンジしてみます!