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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Visual C++

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

OpenCV

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

Python

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

Q&A

解決済

1回答

6645閲覧

opencvでpythonのほうがC++より約10倍速い件について

tettyA

総合スコア93

Visual C++

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

OpenCV

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

Python

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

0グッド

1クリップ

投稿2021/05/05 14:31

編集2021/05/06 11:19

opencvを始めたばかりで他のサイトのコードを真似て作りました。
問題は画像Aと画像N(あるフォルダ内の画像A以外の画像)の一致度(率)を求めるコードです。
一般的にはC++のほうが早いと思いますがなぜかpythonに実行速度で劣ってしまっています。(C++:0.2秒程度,python 0.01~0.02秒程度)
detectAndCompute()DescriptorMatcher::match()関数がその原因ということが今のところ分かっています。
できる限り高速化をしてみたものの、依然として遅い状況です。
また、以下のC++のコード(にデバッグ用のコードと一致度を求めるコードを入れたやつ)を実行すると0x00007FF80D73D759 で例外がスローされました (opencvtest.exe 内): Microsoft C++ の例外: 'anonymous namespace'::ExifParsingError (メモリの場所 0x000000467D3CE470)。というエラーが出てきます。(実行に支障はないのですが気になるのでこれもわかる方はお願いします。)
なぜでしょうか。どなたかご回答お願いします。<(_ _)>

C++

1#pragma comment(lib,"opencv_world411d.lib") 2//#pragma comment(lib,"opencv_world411.lib") 3 4#include <opencv2/opencv.hpp> 5#include <iostream> 6#include <filesystem> 7#include <string> 8#include <vector> 9#include <map> 10const std::string TARGET_DIR = "C:\Users\"; 11 12#define TARGET_FILE "hoge.png" 13 14cv::BFMatcher bf(cv::NORM_HAMMING); 15int main() 16{ 17 cv::Mat targetimg = cv::imread(TARGET_DIR + TARGET_FILE, cv::IMREAD_GRAYSCALE); 18 cv::resize(targetimg, targetimg, cv::Size(200, 200)); 19 cv::Ptr<cv::Feature2D> detector = cv::AKAZE::create(); 20 std::vector<cv::KeyPoint> kp; 21 cv::Mat des; 22 detector->detectAndCompute(targetimg, cv::noArray(), kp, des);//特徴点の抽出 23 24 25 26 std::filesystem::directory_iterator files = std::filesystem::directory_iterator(TARGET_DIR); 27 std::vector<cv::KeyPoint> ckp; 28 cv::Mat cdes; 29 cv::Mat nowImg; 30 std::vector<cv::DMatch> matches; 31 std::size_t tmpsize; 32 33 auto nA = cv::noArray(); 34 for (auto file : files) { 35 36 if (file.path().filename() == TARGET_FILE || file.is_directory()) continue; 37 38 nowImg = cv::imread(file.path().string(), cv::IMREAD_GRAYSCALE); 39 cv::resize(nowImg, nowImg, cv::Size(200, 200)); 40 41 //ここから 42 detector->detectAndCompute(nowImg, nA, ckp, cdes); 43 44 bf.match(des, cdes, matches); 45 //ここまでが問題のコード 46 47 //一致度を求めるコード 48 49 } 50 return 0; 51}

python

1import cv2 2import smart_open.s3 3mydict={} 4 5TARGET_FILE = 'hoge.png' 6IMG_DIR = os.path.abspath("C:\Users\") 7IMG_SIZE = (200, 200) 8 9target_img_path = IMG_DIR +"\"+ TARGET_FILE 10target_img = imread(target_img_path, cv2.IMREAD_GRAYSCALE) 11target_img = cv2.resize(target_img, IMG_SIZE) 12 13bf = cv2.BFMatcher(cv2.NORM_HAMMING) 14# detector = cv2.ORB_create() 15detector = cv2.AKAZE_create() 16(target_kp, target_des) = detector.detectAndCompute(target_img, None) 17 18 19files = os.listdir(IMG_DIR) 20f=t.perf_counter() 21for file in files: 22 if file == '.DS_Store' or file == TARGET_FILE: 23 continue 24 25 comparing_img_path = IMG_DIR +"\"+ file 26 comparing_img = imread(comparing_img_path, cv2.IMREAD_GRAYSCALE) 27 comparing_img = cv2.resize(comparing_img, IMG_SIZE) 28 29 #ここから 30 (comparing_kp, comparing_des) = detector.detectAndCompute(comparing_img, None) 31 matches = bf.match(target_des, comparing_des) 32 #ここまでが問題のコード 33 34 #一致度を求めるコード

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

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

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

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

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

y_waiwai

2021/05/05 20:15

具体的な情報を出しましょう 遅いとか早いとか言われても、他人には意味不明です
Bull

2021/05/06 01:42

#pragma comment(lib,"opencv_world411d.lib") #pragma comment(lib,"opencv_world411.lib") デバッグ用のライブラリとリリース用のライブラリを両方指定しているのは何故ですか? それが原因かどうかは分かりませんが、二つ指定するとトラブルの原因になります。
jbpb0

2021/05/06 13:10

> C++:0.2秒程度,python 0.01~0.02秒程度 を確認した画像の画素数(縦x横)はいくつでしょうか?
tettyA

2021/05/06 13:43

resizeして200x200です。 していなければ489x610と458x519
jbpb0

2021/05/07 04:19

> 0x00007FF80D73D759 で例外がスローされました (opencvtest.exe 内): Microsoft C++ の例外: 'anonymous namespace'::ExifParsingError (メモリの場所 0x000000467D3CE470) 「ExifParsingError」ということから想像すると、画像ファイルのExifが壊れていて読み取りに失敗してるとか、Exif内のデータに矛盾があるとか、そういうことかもしれません 全く別の画像のセットを使って実行しても、そのエラーは出るのでしょうか?
tettyA

2021/05/07 11:08

出ませんでした。 たぶんそれが原因だと思います。
guest

回答1

0

ベストアンサー

「ここから」~「ここまでが問題のコード」の部分のみの実行時間を測ったら、c++, pythonどちらも画像1枚あたり約0.01秒で、変わりありませんでした
また、質問に書かれてるc++のエラーは出ませんでした
(実行して時間を測っただけで、処理結果が妥当かは見てません)

当方の環境は、下記の通りです

Windows 10 Pro 64bit

Visual Studio 2017 (64bit exeコンパイル)
インクルードファイル等の検索パスを環境変数で指定した上で、コマンドプロンプトで「cl /EHsc c++ソースファイル名」を実行してコンパイル
c++ソースの「#pragma comment(lib,"opencv_world411d.lib")」は削除し、「#pragma comment(lib,"opencv_world411.lib")」が有効
OpenCV公式から落としたインストーラー(opencv-4.1.1-vc14_vc15.exe)でインストールし、「build\x64\vc15」以下にあるlib, dllを使用

Python 3.7.10 (64bit)
opencv-contrib-python 4.5.1.48

投稿2021/05/07 02:00

編集2021/05/07 02:42
jbpb0

総合スコア7651

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

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

jbpb0

2021/05/07 04:33

forループ全体(imread, resize含む)の実行時間も、ほとんど同じでした わずかにpythonの方が遅かったですが、違いは1割未満でした なお、当方でテストに使用した画像が、約2000x2000画素と大きめだったためか、forループ内の実行時間の9割近くが、imreadにかかっていました
tettyA

2021/05/07 11:10

world411d.libはVC++のDebugでは使えなかったのですが、Releaseにすると問題なく実行でき、さらにかなり早くなりました。 ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問