質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

4455閲覧

pythonからC++に画像を渡したい。

I_am_

総合スコア23

OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

1グッド

0クリップ

投稿2021/01/03 11:38

前提・実現したいこと

pythonプログラムでimreadした画像データをC++に渡したいです。

c++で画像処理したデータをBoost::pythonでPythonで使えるようにするのが目標です。
c++単体で動かすときには以下の方法で動作します。

C++単体のスクリプト

#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; }

問題点、わからないところ

基本的にはPython側で処理をしていて重い作業をC++で行う予定です。

Pythonで読み込んだデータをC++でOpencvで画像処理をする場合はどのように受け渡しをするのかが今まで行ったことがないのでわかりません。

Q.pythonでimreadしたデータを上記のように、Matという型の変数で受け取るとるのは間違っていますか?

それとも処理ごとにファイルの書き込みを行って、共有ファイルとして画像を毎回imreadしていくのでしょうか?

基本がわからないのでご教授いただけたら嬉しいです。

A_kirisaki👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

Pythonで読み込んだデータをC++でOpencvで画像処理をする

C++でやりたいことがOpenCVに用意されてる関数を実行することだけなら、Pythonでopencv-pythonまたはopencv-contrib-pythonをimportしてopencvの関数を実行するのと、上記は実質変わりません
Pythonでopencvの関数を実行する際には、OpenCVの共有ライブラリ内の関数がPythonから呼び出されて実行されるのですが、その共有ライブラリはC++のOpenCVのコードをコンパイルして作られたものだからです

もちろん、自分で画像処理をC++で書いて、それをPythonから呼び出すのであれば、A_kirisakiさんもお書きになっているように、ctypesとかcffiとかpybind11とか使って組み込む必要があります

投稿2021/01/03 12:09

jbpb0

総合スコア7651

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

A_kirisaki

2021/01/03 12:13

そういやそうですね、OpenCV 自体がバイナリのコードを呼び出してるんでした。全ての問題が釘に見えてしまうハンマーを持った人になってしまっていた
jbpb0

2021/01/03 12:26 編集

Python起動して import cv2 print(cv2.__file__) とやると、cv2(pythonのopencv)の正体が分かりますよね
ppaul

2021/01/03 12:35

pythonとC/C++のインタフェースには、比較的簡単に開発できるけれども実行時のオーバーヘッドの大きいctypesと開発の手間はかかるが実行時のオーバーヘッドの少ないPython/C APIがあります。numpyやscipyは当然Python/C APIです。 調べたことはありませんが、opencv-pythonなどもPython/C APIを使っているはずです。 したがって、自分でctypesを使って呼び出すと、むしろ遅くなります。
A_kirisaki

2021/01/03 12:46

>ppaul さん :+1: したい
I_am_

2021/01/03 12:55

自作をする予定があるので呼び出しをしようとしています。 Boostpythonではなくてctypesとかcffiとかpybind11を使用して組み込みを行う方がいいということでしょうか??
A_kirisaki

2021/01/03 13:01

> I_am_ さん Boost::Python は C++ の中で Python を動かす仕組みなので関係がひっくり返ってるかもしれません。Python でデータを読んでもらって C++ に渡すと考えたら逆の感じがしません?
guest

0

このようなケースでは Python が親プログラムとなり C++ が子プログラムとして関数を差し出しそれを Python が呼び出す、という形になります。そのようなことを実現するために ctypes というパッケージが用意されています。ただし渡せる型は限られていること、メモリの管理を覚える必要があることに注意して使ってください。

追記:
jbpb0 さんが述べられている通り OpenCV はコンパイル済みのバイナリを呼び出しますので C++ で呼び出しても実行速度はほぼ変わりません。C++ 側で追加の画像処理をガッツリ書く必要がある場合でないと有効でないでしょう。また、ppaul さんによればわたしの挙げた ctypes より Python/C API の方がより高速だそうです(知らんかった……)。

いずれにせよ問題点は「高速化」ということらしいですので OpenCV ならば GPU が使えないか検討すると良いかもしれません。

投稿2021/01/03 11:43

編集2021/01/03 12:57
A_kirisaki

総合スコア2853

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問