. o4 w/ Q- [& w- q" y2 f% G( k3 ~ 使用opencv qt 以及 tensorflow2 进行神经网络分类5 o+ [: `7 I+ d2 _
工具选择 1 L# o; V5 X! U3 g我们将会学习使用图片分类器和合适的GUI界面,GUI界面使用QT,选择一个camera 或者一个视频文件作为输入进行分类,这里是实时进行分类,qt本身是一个跨平台的GUI设计工具,同时我们使用Tensorflow 和 opencv 去进行分类工作。" ` A3 g7 Y- e- e2 t+ ]
; {% Y( d [) Z! H$ a
opencv 本身具有一个深度学习推理模块,名字叫做dnn, 3.4.1 以上opencv版本, 使用dnn模块,我们可以加载和使用深度学习模型,这种模型来自于像tensorflow的第三方工具,当然他还支持caffe,darknet 等等,我们这里使用tensorflow 模型,使用 ssd_mobilenet_v1_coco 1 C) ?% E! t6 \3 W, ^# n! c - N7 J2 H- h4 @9 K8 B% z( l本身在windows 或者其他操作系统上应该都是可以的,我们以windows为例 7 n& b8 W! Z! M$ @& _* G8 J' _" d i: o- x8 m
需要的工具; }3 z' p; x8 x4 R# K/ s5 f
• 1 Microsoft Visual Studio 2019 ; E* U( t! `. w5 \7 `• Qt5 (https://www.qt.io) 8 G$ j6 m: r+ a/ C" w5 s ~• OpenCV 4 (https://opencv.org)2 ~- k t) p6 B7 L5 _. M r" o2 N
• CMake (https://cmake.org)( K* Z7 X- M! m6 l* e7 j, Y
• Python 64-bit (https://www.python.org) ! Y/ d/ x9 I3 D$ G# ]3 k9 i G+ u• TensorFlow2 (https://www.tensorflow.org) 3 Z7 u" p) b5 W4 o/ {- ]: Y( }" t" m& ~- i( c+ P! P
创建 Qt GUI Project 选择CMake+ j( X* i4 k: F, S( _' }
我们将会创建一个QT GUI 应用程序,编译方式选择CMake,当然了,不是一定要选择这个了,读者自己可以选择其他方式。 2 [- Q0 ~8 S; F# T0 \$ c 2 ]8 H! M3 Q" f# i* m& v# g这一这里选择CMake- Q0 \/ T" }* R# x) Q$ D0 f
, P6 X( d# M0 S$ C+ P' ?; ~! \
1 Z7 B$ i! k3 i( B5 W2 g
项目创建以后4 B* x$ Z e5 Q7 d% _
After the project is created, replace all of the contents of CMakeLists.txt file with the following (the comments in the following code are meant as a description to why each line exists at all):8 ~6 G% f8 r& V* V1 Q
2 w' b; N" T& I& \# Specify the minimum version of CMake(3.1 is currently recommended by Qt) 2 h2 e& g6 p( p" zcmake_minimum_required(VERSION 3.1)4 ~0 Y* N+ X" \
5 B$ H* K% v+ s1 v- M% d
# Specify project title - R& ^) R% ~% f; x' Wproject(ImageClassifier) / u/ s. S- L3 [/ Z$ _/ v, w$ q , A- }6 }" f+ _8 o" o* w6 J# To automatically run MOC when building(Meta Object Compiler)5 q# I0 B& W" \: U
set(CMAKE_AUTOMOC ON)( h& x0 a) G$ ]! W
4 r. E8 m' \3 S. { J4 D* W' U# To automatically run UIC when building(User Interface Compiler) ( F7 a- C* F0 W z5 Xset(CMAKE_AUTOUIC ON)5 v) Z) V' ~% r' X7 o" A
5 j3 M: A( {. w( y; A$ J# To automatically run RCC when building(Resource Compiler) 7 C$ T3 o8 _7 x. C# C- k) l1 `set(CMAKE_AUTORCC ON): H% C) N# F; N' P4 d
5 G- P+ b8 o# `( `. e# Specify OpenCV folder, and take care of dependenciesand includes7 g$ {# H$ ^/ _# _6 b' J
set(OpenCV_DIR "path_to_opencv") " @! s( q; r2 |+ ~" z9 Dfind_package(OpenCV REQUIRED) ) ]- q0 z* g7 T9 N0 B, Linclude_directories(${ OpenCV_INCLUDE_DIRS }) ( b1 H! h4 ~/ y8 J - K; Q' ]" h/ ?" z# D3 r9 B! Z# Take care of Qt dependencies& Q% F3 @# k1 e8 [. I4 ~7 f
find_package(Qt5 COMPONENTS Core Gui Widgets REQUIRED)& q8 E1 z0 q2 l9 o h' k- ^: i
0 ^) Q$ V& v# ^2 [ if (confidence > confidenceThreshold) + p" f% M3 Q$ F; z3 W0 Z { 7 n$ O8 {* j, g9 v+ |, d! q2 C% U using namespace cv;0 D, K) C: @& v9 A9 Z3 Z
! b8 v; g/ x! D
int objectClass = (int)(detections.at<float>(i, 1));. w9 ~4 F; y% L0 {
) S: D1 m0 ]6 B! A- K' v int left = static_cast<int>( . N" E7 D# N D9 _) {1 k detections.at<float>(i, 3) * image.cols);% A& z0 X8 Y4 Y
int top = static_cast<int>( ( R1 f( R! P6 r9 U' q/ b detections.at<float>(i, 4) * image.rows); 0 J, d0 b7 C2 W/ a3 c& q% C int right = static_cast<int>( ! ]3 {4 f% q# Z1 F% e detections.at<float>(i, 5) * image.cols); ], T* f; @. C* u1 A1 h1 n int bottom = static_cast<int>( # }( |$ U4 p/ @# m+ ` detections.at<float>(i, 6) * image.rows); , n& j) r9 i; ~8 z9 N1 B1 V1 }3 I* g
rectangle(image, Point(left, top), $ j0 O$ ~+ C/ L9 |% |. s Point(right, bottom), Scalar(0, 255, 0));* V; K* o0 F* a2 X. j7 h
String label = classNames[objectClass].toStdString(); . Z( ?, n: N, [! F8 T int baseLine = 0;7 @: V4 p! Z6 c/ h5 j1 B3 g7 _4 n
Size labelSize = getTextSize(label, FONT_HERSHEY_SIMPLEX,, i. x2 R2 t! T+ I" a, y
0.5, 2, &baseLine);1 U- y( J& f* T/ d
top = max(top, labelSize.height); ! c7 }! N7 W7 p: p" ~ rectangle(image, Point(left, top - labelSize.height),4 T+ G8 |8 l. s/ c- P
Point(left + labelSize.width, top + baseLine), ' M' K! m8 x4 ^$ o+ D- u Scalar(255, 255, 255), FILLED); : T% E, Q# o1 ?) c putText(image, label, Point(left, top),5 t7 Z. T3 r$ d! U& M% j3 j8 S
FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 0, 0)); " a5 G0 w3 t& J" f& W% I. b } * R8 q% w0 p; i+ l' Q: \6 J} ( U6 A9 U Z }& l6 c! i/ _ / U) D4 Z9 g5 T% m8 {pixmap.setPixmap( , w$ a% z& M+ I$ ^ QPixmap::fromImage(QImage(image.data, 3 a; [( [7 g$ j# ~) i( ^1 N. b/ ` image.cols, 4 ?* f" V3 T S5 V/ S4 h image.rows, 2 @+ r0 k3 J0 ~4 \+ D( s image.step,6 ^4 |) v3 h' A3 p% _+ y+ k
QImage::Format_RGB888).rgbSwapped())); ( |- {4 i0 a$ j1 L" R$ r+ |ui->videoView->fitInView(&pixmap, Qt::KeepAspectRatio);* K' ]; U! s4 P8 q
1 1 `" _* j( i5 H6 a* m2 8 L+ L M/ Y: ]. F3 * U$ ]1 K, Q* f0 I1 _5 {# J, l4 ' _$ p/ V6 g. ^5 t( q7 \5 ) a- P3 X- `! y4 o0 f0 E9 G6 # R8 O. i" w% R7 x7 * A# i% q0 i5 X, D7 M _0 Q8 f0 L8 " m5 Q9 z/ q' l& X; E1 t6 M' d T9; Q" K+ D: I" \. S& y
103 }3 p: A# W& L0 ~' w# O# S7 l
11, P6 p5 [4 ~, H! J+ }% B
12- w% `& w4 U. R! q
13 $ Z9 d) I4 B6 T14 $ ?0 ^& y/ f) c. F: R8 b+ g15$ d2 N, j% E! [7 Q1 b8 t4 w
16 ; p: X/ a4 U2 X* f172 C! H( h0 `: R! Z5 j
181 L) h# g" ^8 ]1 [: R& j5 r
19( Q* n- h; A) \; @
20 $ @2 N# @" ?+ q6 @( G) x21# ~0 ~6 k2 Z, i% F' `! k8 C5 `
22; M( d2 v7 d& G
23 $ C, @8 T# a# L, C( h: h24 3 d9 V3 B, m9 A x25 3 z: I. Z9 v8 S! D+ a26 5 T/ v. ^8 E4 Z6 d27) Z2 d% P" I7 ]' ]3 U1 U; c% ]
28: G7 Y5 m2 ]+ f6 l) u, V: t1 N& C
29 % Z. `* Z" N& z8 Q30 ; {' Z; ~# u; R4 R* ~) n& M5 F- T& V31 % o; A( R; A$ K: m32! A: t& N7 t$ w# D, U5 |
338 ]9 |' T$ N' A
341 g- Y( G5 s! e+ r5 l
35 7 m6 I$ |5 `8 ]; S# J/ ~36. @- W: Y' F+ |% D7 _" P! ? m
37 4 B' j/ v% P: ?0 Z- t; d( u1 {38 . |7 c, U6 v& h$ P5 E, O39 , w7 ~$ q3 |: f! _3 b40 8 _) a: D% y/ T$ c41 3 d2 a8 b- ?7 V- T+ X: o这样我们的程序基本就完成了, 不过这里我们还是需要预备一个TensorFlow 网络,同时需要获取tensorflow 模型+ S; p. ?7 j% n# j. {
# r6 P J& ^, F9 j, vTensorflow模型获取( ]4 `9 }% y$ O
首先,我们下载预先训练好的Tensorflow 模型,从下面这个网址3 ]+ W0 G7 E9 ]7 n* h1 U
8 m% U( Z* s' ^! f- k8 p4 J, w' ]0 T
https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/detection_model_zoo.md( Y8 S/ F2 w! D8 _' C& m% N
然后使用ssd_mobilenet_v1_coco文件,可以从下面下载:9 ?! e0 X( I+ R' ~7 S7 y9 m/ X3 j
( Q2 c5 A+ X- M' l2 c h/ }http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v1_coco_2017_11_17.tar.gz & o* h+ H1 g+ f$ h$ q4 U# @* O& H2 x0 A
Extract it to get ssd_mobilenet_v1_coco_2017_11_17 folder with the pre-trained files.' h6 y9 R X/ _6 z! L' K
我们必须拿到text graph 文件 ,模型,这些文件应该和opencv 兼容, 我们可以使用下面的ssd.py,从opencv的源代码的samples里面可以找到下面这个文件 ! K7 x6 |& k! M3 ?5 m/ n) p4 \. p- P9 A & w$ m! G) U$ _ |opencv-source-files\samples\dnn\tf_text_graph_ssd.py7 d2 g- r8 X+ M# F x$ J# s
; J, ]( j* c$ ~. b
当然也可以从opencv的github源码下面去下载 " n o0 U$ |7 H7 S 6 V% Y0 t1 [+ b2 Vhttps://github.com/opencv/opencv/blob/master/samples/dnn/tf_text_graph_ssd.py - u$ B- Q* p" g. t( r2 B1 w8 [7 B/ C9 M
拷贝ssd_mobilenet_v1_coco_2017_11_17 文件夹 并且像下面这样执行 ! O$ R5 B. s# F- O' K* UJust copy it to ssd_mobilenet_v1_coco_2017_11_17 folder and execute the following:8 D% ^; H v7 `7 M) }
$ B7 g( Q: n* {3 Etf_text_graph_ssd.py --input frozen_inference_graph.pb --output frozen_inference_graph.pbtxt & V2 H' S S! u$ ]新版可以这样执行: ( U0 L. l: a5 i' f; z$ ~! Ytf_text_graph_ssd.py --input frozen_inference_graph.pb --output frozen_inference_graph.pbtxt --config pipeline.config 9 p$ D0 t, P# ~( I8 ]7 ~: Z分类文件和模型可以从下面下载 9 J( O; U$ X n; a; Ohttps://github.com/tensorflow/models/blob/master/research/object_detection/data/mscoco_label_map.pbtxt 7 W, P2 p0 `$ L/ k- G' l; D' V* @ 9 L% x' a7 n: E# y, dThis file won’t be of use for us the way it is, so here is a here’s a simpler (CSV) format that I’ve prepared to use to display class names when detecting them:" P. s% t% d, n" E1 D/ |7 _- S
8 f3 ]1 G* q) J. [1 c5 shttp://amin-ahmadi.com/downloadfiles/qt-opencv-tensorflow/class-names.txt. a, E* c' Y) F) W# B+ Q% z# k
! D+ I% b# J) ^- U6 d
Now we have everything we need to run and test our classification app in actio 5 _( C! r" K- _, E8 @& R. G, Z0 v2 U2 U% L( V0 k
启动图片分类应用程序 / s0 e3 t1 z; w5 Y从QT Creator 中切换lab, 输入这些文件, 3 m& N6 l, e* u4 \% F6 M * u8 W, ^3 m( y- z9 ^- \7 N现在切换回去,就可以开始探测了,5 `" e J3 ~8 _/ M! U; u