この記事はOpenCV Advent Calendar 2025の10日目の記事です。
2021年、2023年のAdvent Calendarで投稿した以下記事と同じ検証内容です。
OpenCVのリリースノート見ていると、DNNモジュールでちょいちょい互換性向上系の修正とか、高速化系の修正は入っているのですよね。
なので、推論速度早くなったかな。と思って改めて確認しています。
ちなみに、過去の投稿と同じモデルで検証しているので、YOLOv3など少々古いモデルを用いています。
※それでも動作しないモデルがちょいちょいありますが。。。
※後述しますが、YOLOv3はエラーが出て読み込めません
リリースノートを見るとYOLOv10などは対応しているようなので
レイヤーのサポート追加が放棄されているわけでは無さそうですが👀
結論
速、、、いや、やっぱ2023年からあんま変わってねーです。
※CPU推論
バージョン
以下のバージョンで確認しました。
pip show opencv-python
Name: opencv-python
Version: 4.12.0.88
(省略)
pip show onnxruntime
Name: onnxruntime
Version: 1.23.2
(省略)
計測環境
Google Colaboratory上でCPU推論を行い「%%time」や「%%timeit」を使用して推論時間を計測しています。
(本来はもっと厳密な方法と環境で計測すべきでしょうが、、、ご容赦を。。。🙇
参考:CPU情報
processor : 0
vendor_id : GenuineIntel
cpu family : 6
model : 79
model name : Intel(R) Xeon(R) CPU @ 2.20GHz
stepping : 0
microcode : 0xffffffff
cpu MHz : 2199.998
cache size : 56320 KB
physical id : 0
siblings : 2
core id : 0
cpu cores : 1
apicid : 0
initial apicid : 0
fpu : yes
fpu_exception : yes
cpuid level : 13
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc rep_good nopl xtopology nonstop_tsc cpuid tsc_known_freq pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch ssbd ibrs ibpb stibp fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm rdseed adx smap xsaveopt arat md_clear arch_capabilities
bugs : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs taa mmio_stale_data retbleed bhi its
bogomips : 4399.99
clflush size : 64
cache_alignment : 64
address sizes : 46 bits physical, 48 bits virtual
power management:
processor : 1
vendor_id : GenuineIntel
cpu family : 6
model : 79
model name : Intel(R) Xeon(R) CPU @ 2.20GHz
stepping : 0
microcode : 0xffffffff
cpu MHz : 2199.998
cache size : 56320 KB
physical id : 0
siblings : 2
core id : 0
cpu cores : 1
apicid : 1
initial apicid : 1
fpu : yes
fpu_exception : yes
cpuid level : 13
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc rep_good nopl xtopology nonstop_tsc cpuid tsc_known_freq pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch ssbd ibrs ibpb stibp fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm rdseed adx smap xsaveopt arat md_clear arch_capabilities
bugs : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs taa mmio_stale_data retbleed bhi its
bogomips : 4399.99
clflush size : 64
cache_alignment : 64
address sizes : 46 bits physical, 48 bits virtual
power management:
ONNXランタイム VS OpenCV DNNモジュール VGG16推論時間比較
CPUで推論した場合、ぼちぼち推論時間がかかるVGG16で比較してみます。
VGG16のONNXモデルは、ONNX Model Zoo の vgg16-7.onnx を使用しました👀
蜂(Bee)の画像で推論してみます。

※ぱくたその画像を使用
以降のスクリプトは、Qiita-AdventCalendar-OpenCV-20251210-01.ipynbをColaboratoryで。
ONNXランタイム
モデルをロードして
import onnxruntime
onnx_session = onnxruntime.InferenceSession('vgg16-7.onnx', providers=['CPUExecutionProvider'])
画像の前処理をして
import cv2 as cv
import numpy as np
# 前処理
input_image = cv.resize(image, dsize=(224, 224))
input_image = cv.cvtColor(input_image, cv.COLOR_BGR2RGB)
mean = [0.485, 0.456, 0.406]
std = [0.229, 0.224, 0.225]
input_image = (input_image / 255 - mean) / std
input_image = input_image.transpose(2, 0, 1).astype('float32')
input_image = input_image.reshape(-1, 3, 224, 224)
# 入力名・出力名取得
input_name = onnx_session.get_inputs()[0].name
output_name = onnx_session.get_outputs()[0].name
推論時間計測します。
%%timeit -r 7 -n 10
# 時間計測
onnx_session.run([output_name], {input_name: input_image})
上位5クラスの推論結果を出してみます。
result = np.array(result).squeeze()
print(np.argsort(result)[::-1][:5])

あっていそうですね👀
309:Bee(蜂)
308:fly(蝿)
94:hummingbird(ハチドリ)
95:jacamar(キツツキ目の鳥(キリハシ))
946:cardoon(菊科の植物(カルドン))
OpenCV dnnモジュール
モデルをロードして、バックエンドターゲットをCPUにして
import cv2 as cv
net = cv.dnn.readNet('vgg16-7.onnx')
net.setPreferableTarget(cv.dnn.DNN_TARGET_CPU)
画像の前処理をして
import numpy as np
# 前処理
input_image = cv.resize(image, dsize=(224, 224))
input_image = cv.cvtColor(input_image, cv.COLOR_BGR2RGB)
mean = [0.485, 0.456, 0.406]
std = [0.229, 0.224, 0.225]
input_image = (input_image / 255 - mean) / std
input_image = input_image.astype('float32')
input_blob = cv.dnn.blobFromImage(input_image)
out_layer_name = net.getUnconnectedOutLayersNames()
# 入力BLOB設定
net.setInput(input_blob, 'data')
推論時間計測します。
%%timeit -r 7 -n 10
# 時間計測
net.forward(out_layer_name)
上位5クラスの推論結果を出してみます。
result = np.array(result).squeeze()
print(np.argsort(result)[::-1][:5])

あっていそうですね👀
309:Bee(蜂)
308:fly(蝿)
94:hummingbird(ハチドリ)
95:jacamar(キツツキ目の鳥(キリハシ))
946:cardoon(菊科の植物(カルドン))
ONNXランタイム VS OpenCV dnnモジュール
dnnモジュールでの推論のほうが、速いですね👀
前回試した時、1~2割高速化できるって感じだったので、少し安定感増したかも?
| モデル | ONNXランタイム | dnnモジュール |
|---|---|---|
| VGG16 | 503ms | 393ms(78.1%) |
Winogradアルゴリズムによる高速化
「OpenCVのDNNモジュールが速いのは、Winogradアルゴリズム(若干の精度低下と引き換えにCNNの乗算回数を減らすアルゴリズム)による高速化がデフォルトで有効化されているから」と小耳にはさみました👀
と言うわけで、Winogradを無効化して試してみます。
ちなみに前回試したときは、このオプションは意味ありませんでした。
net.enableWinograd(False)
%%timeit -r 7 -n 10
# 時間計測
net.forward(out_layer_name)
net.enableWinograd(True)
%%timeit -r 7 -n 10
# 時間計測
net.forward(out_layer_name)
あ、推論速度違いますね。enableWinograd()に修正入ったのかしら。
ONNXランタイム VS OpenCV DNNモジュール その他いくつかのモデルの推論時間比較
VGG16では期待感ありましたが、、、
他のモデルだと結果がふるわず、、、👀
ただ、YOLOv4での推論速度が若干改善しているかも?
| モデル | ONNXランタイム | dnnモジュール |
|---|---|---|
| MobileNetV2 | 34ms | 50.5ms(149%) |
| ResNet50V1 | 150ms | 175ms(117%) |
| YOLOv4 | 1.36s | 1.35s(99%) |
| YOLOX-S | 547ms | 807ms(148%) |
上記の計測に使用したスクリプトは、Qiita-AdventCalendar-OpenCV-20251210-02.ipynbで公開しています。
試したかったけど OpenCV 4.12.0.88 のdnnモジュールで読みこめなかったモデルたち
yolov3-10.onnx
以下のエラーが発生して読み込めず。
error: OpenCV(4.12.0) /io/opencv/modules/dnn/src/onnx/onnx_graph_simplifier.cpp:1862: error: (-210:Unsupported format or combination of formats) Unsupported data type: BOOL in function 'getMatFromTensor'
MaskRCNN-10.onnx
以下のエラーが発生して読み込めず。
error: OpenCV(4.12.0) /io/opencv/modules/dnn/src/onnx/onnx_importer.cpp:1058: error: (-2:Unspecified error) in function 'handleNode'
以上。



