5 {6 d3 V2 \" x7 k0 \" ^- h使用opencv qt 以及 tensorflow2 进行神经网络分类$ s. P0 Z# q# {/ Z! o( K
工具选择. ], B% D7 Y" n* C' h. }
我们将会学习使用图片分类器和合适的GUI界面,GUI界面使用QT,选择一个camera 或者一个视频文件作为输入进行分类,这里是实时进行分类,qt本身是一个跨平台的GUI设计工具,同时我们使用Tensorflow 和 opencv 去进行分类工作。* o" U( W P8 w# ~0 H$ W8 H; D1 d
* X7 O! t/ ^7 W9 m; L$ d* k$ L
opencv 本身具有一个深度学习推理模块,名字叫做dnn, 3.4.1 以上opencv版本, 使用dnn模块,我们可以加载和使用深度学习模型,这种模型来自于像tensorflow的第三方工具,当然他还支持caffe,darknet 等等,我们这里使用tensorflow 模型,使用 ssd_mobilenet_v1_coco 2 H$ d5 P% e% I& X2 G' `' e% S# I$ S d! R- G. H9 R
本身在windows 或者其他操作系统上应该都是可以的,我们以windows为例 . A4 @) j3 N& t0 N- k & v0 r, S! j+ N, x需要的工具 K* o: t6 i7 B8 h( G5 l/ b• 1 Microsoft Visual Studio 2019) Z" I! j, G4 q8 O! ?, A
• Qt5 (https://www.qt.io) ( R( d: }0 ?- \, G+ w# ^• OpenCV 4 (https://opencv.org) ; d0 T; N/ z2 C) J1 ^• CMake (https://cmake.org) . O3 {: h% q+ Q7 X7 A+ W+ O" g• Python 64-bit (https://www.python.org)) W+ ]( Q' `4 G: V/ P
• TensorFlow2 (https://www.tensorflow.org); }. z+ ?% }7 D6 k; ]
# U2 }6 F& U, X' |9 h1 N. f8 @创建 Qt GUI Project 选择CMake, K! Y7 O( V& c- z" b( D8 o
我们将会创建一个QT GUI 应用程序,编译方式选择CMake,当然了,不是一定要选择这个了,读者自己可以选择其他方式。7 J! y# g5 o( f/ P) N
) \$ z3 g% S: ?) { R$ ]
这一这里选择CMake% r* u) O" S& _ C) ~4 ?
8 o: a, d; P- j
, P# f0 d) n- H- v: H0 P$ ^" [项目创建以后 ( p# b* X! N9 f. m7 ]! i1 DAfter 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): . d3 V A4 M) f L! Z5 N: d! `/ [; T. Q c, Y
# Specify the minimum version of CMake(3.1 is currently recommended by Qt)) T, F2 n8 X0 L9 V2 W# Z& n
cmake_minimum_required(VERSION 3.1); X0 c0 U8 U8 N( t% h5 `
4 M6 |) H* l$ I$ _* M* C' j# Specify project title* ]' h1 X5 H- v
project(ImageClassifier), y$ y% |+ N4 D5 V. F
$ I) l) z7 r$ j1 z% R- W
# To automatically run MOC when building(Meta Object Compiler)8 ?$ [. _( U$ o5 |# j& R
set(CMAKE_AUTOMOC ON)/ H# W$ ~( ]9 N, v' Y
& F7 s0 ?" p! b0 i/ T
# To automatically run UIC when building(User Interface Compiler) ( E3 `# B# ?# q+ Vset(CMAKE_AUTOUIC ON)0 l( _1 X' D& N3 F2 [
) W) K+ P, u* w. J
# To automatically run RCC when building(Resource Compiler) 1 ~# Y) R1 V! M4 r8 K+ pset(CMAKE_AUTORCC ON)# u, s( J Z2 _7 O7 W D4 e0 |$ ~
* P- A, N: z- o5 Z1 y
# Specify OpenCV folder, and take care of dependenciesand includes M7 `0 ]: z) aset(OpenCV_DIR "path_to_opencv")6 ^) J: k% ?9 Z- x5 c2 A |
find_package(OpenCV REQUIRED) # o" e1 `! G: t `include_directories(${ OpenCV_INCLUDE_DIRS }) 1 b+ Y% j$ Z. f3 B: V: y5 ~7 O + i2 ], T* E! H+ ?' w- n; G7 `% J# Take care of Qt dependencies6 w/ ?% X7 k' F) a* H
find_package(Qt5 COMPONENTS Core Gui Widgets REQUIRED)2 v) N! e& |2 ?1 v8 m+ Z
7 ? {2 _: _4 i7 r# add required source, header, uiand resource files 6 A4 [6 T5 n2 Z# V, Hadd_executable(${ PROJECT_NAME } "main.cpp" "mainwindow.h" "mainwindow.cpp" "mainwindow.ui") * C/ R% K: x- T4 p( r h! q$ T7 Y, G# ^& O* n2 M
# link required libs ( v# M% ]8 z0 q9 W2 h2 v) B$ E4 jtarget_link_libraries(${PROJECT_NAME} Qt5::Core Qt5::Gui Qt5::Widgets ${OpenCV_LIBS})5 m- L( M/ i& L
1; t5 i0 M9 {( N
2 9 l) o' o8 M3 x, N" S& G0 P- G& c3+ M7 o6 J) g! w; c
4 # f/ j% G; _" i, u* m" X/ O, o( b9 {5 # ]2 W' c0 \8 g6- I6 ]( J* n5 ]% [) [% W; g
7 x8 A7 l/ H8 T/ y- g, q8 6 U q0 l! P1 ~$ o9 4 e# s9 |8 f* h- ?& L# @107 O! ~0 ?; E0 |: v" }% O* I9 ]
11 & L8 C: V4 D4 w; u12 5 Q: u. l5 J! ]13 # e' C0 z1 l/ O! V8 ^. j$ @2 v14 - R% b, Y! E: ~; E15# }6 G8 G3 _- d* w
16* R/ @3 [. w' J* A% Q- ?
17) {) U/ w5 `5 A `! Z. l, k/ }
18 1 l1 L1 _& H& Z19 D/ ^0 z- P& Z$ P20$ o, m e8 t# J: U
21+ j! B( J* ]$ E& h
22& b u4 e7 ~" ?: e- L3 G
232 N0 b; D/ T+ v8 T4 A
24 , I9 _+ x$ s- T# m' @+ M3 k25 ; X- q7 R1 K/ w$ ~$ g. L26/ y8 R2 V4 x7 H. Q0 Q! l1 r% {
27. K' @% P/ h2 a$ |& m
28 " r/ A( }2 e4 d6 W2 S把里面正确的地址写好,把main.cpp 里面开始mainwindow.cpp 。 + |' x6 z2 d" _. u& v/ Z 7 [+ g+ e& z3 S5 q写好main.cpp5 ^( v) E9 R4 b8 `& R( p/ _7 c
#include "mainwindow.h"+ [5 V& h, T$ Q* K' O
#include <QApplication> - ?* M0 P/ r" K! S4 Y6 j' ~2 j2 |9 T: s" L0 l1 P x% M: |
int main(int argc, char* argv[])2 ], X/ b* E, O4 e) o/ g, G* t
{ 4 y0 S) Z1 {& O! M2 d, S- f QApplication a(argc, argv); ( W! j4 ~4 V. O/ a+ ?( j MainWindow w;' m2 R" o; u8 i6 E5 G1 S) H. A# E
w.show(); ' M6 A5 y7 B- P! \( q$ U' N4 }$ S* P5 ~6 N6 a$ G
return a.exec(); ' Q! r- t5 h, Y4 f# L `& H/ Z}1 I. x$ N. M( I, w' i7 u- _
1 - c7 G0 A. `: ~. M) |6 q7 O% q9 G2' S5 J* J- k" }/ a5 h+ H2 o4 W+ }+ V* K) \+ ]
3 ; D; ~, A/ `1 [9 Q+ ?42 g: p3 o4 {3 o: `' n
5 ( l- N' _, R8 M+ Q( A6 ! i' S( A: U7 Y6 M7 B/ m* p% P( E76 g! q. v% ?+ N
80 Q: H. S) v) v3 j# x
9 ; g5 U0 d9 L5 D10 # `- S; {7 y6 W11; n3 F8 \& `/ K
现在使用设计器加上一个窗体,7 z+ U/ j9 U. d8 p5 m$ u, N
! s: k. n% R/ \$ O+ @% e0 T+ {
选择Main Window * u( n+ m6 D7 ^" n% j$ b0 F, t# i$ I9 p3 L
$ U* }! `" h( f: p4 h4 C
像下面这样设计窗体就行了 8 j- M. d5 }' R0 B' B6 M& Z : G* b- }% `( w1 @7 U* |( t" g3 I; Z: @. v5 l3 |+ c1 D% i' r/ g
“mainwindow.h” 文件代码如下; o) K9 d c: U
- k- ?, D+ j# y. x+ ~6 e( X( x#include <QMainWindow> + J! y' ]" ~4 c, ~5 m# U#include <QMessageBox>. P1 f( o- t( y5 K" T- `
#include <QDebug>2 L+ z9 s# I' y
#include <QFile>$ l" Q3 x! `+ ^- V/ L
#include <QElapsedTimer> : {& k7 @% ~4 I#include <QGraphicsScene> 7 F9 x9 E+ e! }2 S' ?1 l1 G#include <QGraphicsPixmapItem> 7 U: m. L C, t, z# o- b' X#include <QCloseEvent> C( @- S1 N' F3 a
#include <QFileDialog>: k! F6 V- X. a( ]* j1 L, E
#include <opencv2/opencv.hpp> ' P$ Q! {- ]6 NWe will also need the following private members:- H* l l$ V, m5 ~
! h+ j, L e( w2 V' o) I# N6 Q
cv::dnn::Net tfNetwork;4 C* R, l4 r l( A
QGraphicsScene scene; % g* |. F" m4 l, F! i( CQGraphicsPixmapItem pixmap;+ R6 s- D& K5 J, W
bool videoStopped;3 Z m5 u3 n- A5 ?2 ]3 ~) O2 O
1 ) [2 U4 I) I; z. P20 V6 H. `; Y& X2 l. z. I7 E0 W& O" n
38 P8 S0 y% }5 B3 y0 K" h7 _
4 k% s. G! W8 X: e1 J4 b. w
5& }+ E7 H4 n' O x
6$ A- v! ^, N, y, R# P+ `# k: e
7 7 u2 C3 G: t8 _9 o8, G# F2 T0 ~4 T! F5 v
9 7 {+ m# f4 U6 {; ^ g- W' S10$ E5 _8 S& r& v' r( I* P5 m% ~0 u
117 W9 s$ G7 \/ s: q
124 v* n, o, |6 M1 {* y/ C. C) f
13 ! g1 f; |/ A* \/ e) l. w3 f14 % P" z5 }( @4 W$ T6 ]6 w$ b15 % d5 [0 D3 x, `165 s, k: ?6 ]1 n9 n9 x' {& v
tfNetwork 是opencv的深度网络分类器,场景scene and pixmaps 用来显示,变量 videoStopped 作为一个标记去停止视频. 我们的代码如下所示. , q; \: B+ T* i9 M% C" }+ U Y5 F$ U s( B/ |4 e" n0 Z" Z
#ifndef MAINWINDOW_H! k5 B8 U; w* W7 l7 g9 H+ {3 p
#define MAINWINDOW_H {. S5 ~0 }; [' w3 t# _4 C. |/ m . T0 |3 G$ C% Y) I! O#include <QMainWindow>. l5 {' o2 D) L3 m
#include <QMessageBox> $ g, m6 V5 U7 e6 A9 V' m, |1 V#include <QDebug> 7 l+ Y; G2 u q#include <QFile>9 `2 ? ~& }( Z* R/ u4 H3 B' p$ s. i
#include <QElapsedTimer> ; J8 d! T4 i1 l d V l( E#include <QGraphicsScene> ! F6 A1 J$ [! }, D5 |#include <QGraphicsPixmapItem> & S) h8 k* H* X. }#include <QCloseEvent> 7 ^+ s+ r: m' K6 B& d5 f& S5 E#include <QFileDialog> 1 Z0 ?( A4 Q( ~/ T9 U( ~3 X2 k#include <opencv2/opencv.hpp>; y/ [" J; l# p q$ b" R
& R& W% X! i) v4 Q$ w+ H1 j+ _( wThis 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: 1 y/ Y! W. `# d# [2 a& p. Y$ j) k2 N# ], k: ~; V r) H. ^. a3 g
http://amin-ahmadi.com/downloadfiles/qt-opencv-tensorflow/class-names.txt+ Q, d; S' _8 K6 O
! i* |; u* s& H! }1 v
Now we have everything we need to run and test our classification app in actio- k* {2 u- z! V3 r
) X) k4 H! _5 z; A6 j9 I
启动图片分类应用程序 * G' f- }/ A X% C5 s从QT Creator 中切换lab, 输入这些文件,, ~$ L( i) o2 L6 W0 M
! ?3 A/ ~: C: I( a. o8 M
现在切换回去,就可以开始探测了,8 j6 p3 k$ u0 f, }! {0 W1 h7 y
9 _7 o: h" d) _+ X# X" f1 f0 l5 ]' e
以下网页应该对我们有帮助: d4 F: I) x4 e- n, q" ~5 A" M1 b
https://github.com/opencv/opencv/tree/master/samples/dnn0 j, C: r, O, u- d1 r# }
https://www.tensorflow.org/tutorials/image_retraining & p$ x. S9 p# f————————————————! s' l' ~) f; o6 o8 q0 }
版权声明:本文为CSDN博主「qianbo_insist」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 , g. L& f% n& F2 G1 n, w% M f2 `# Z原文链接:https://blog.csdn.net/qianbo042311/article/details/126253546 " ~; y% X2 ^. M7 l) _" w" E- u0 U- R