学习分享  1、效果图 2、camerathread.h 3、camerathread.cpp 4、mainwindow.h 5、mainwindow.cpp 6、main.cpp   
 
 
# ifndef  CAMERATHREAD_H # define  CAMERATHREAD_H # include  <QObject> # include  <QThread> # include  <QDebug> # include  <QImage> # include  <unistd.h> # include  <iostream> # include  <QDateTime> # include  <opencv2/opencv.hpp> using  namespace   std; 
using  namespace   cv; 
class  CameraThread  : public  QThread { Q_OBJECT
public : static  CameraThread * camerathread; static  CameraThread * getInstance ( ) ; void  run ( ) ; bool  getIsRun ( )  const ; void  setIsRun ( bool  value) ; int  getFrame_width ( )  const ; int  getFrame_height ( )  const ; void  detecCarDaw ( Mat & frame, CascadeClassifier & cascade, double  scale) ; bool  getIsStop ( )  const ; void  setIsStop ( bool  value) ; bool  getIsRecord ( )  const ; void  setIsRecord ( bool  value) ; VideoWriter getWriter ( )  const ; bool  getIsPersistent ( )  const ; void  setIsPersistent ( bool  value) ; bool  getIsRun_s ( )  const ; void  setIsRun_s ( bool  value) ; 
signals: void  sendQImage ( Mat frame) ; 
private : CameraThread ( ) ; CascadeClassifier cascade; VideoCapture cap; Mat frame; VideoWriter writer; bool  isRun; int  frame_width; int  frame_height; int  recordNum;  bool  isRun_s;  bool  isStop;  bool  isRecord;  bool  isPersistent; 
} ; # endif  # include  "camerathread.h" *  CameraThread:: camerathread = nullptr ; 
CameraThread *  CameraThread :: getInstance ( ) 
{ if ( CameraThread:: camerathread == nullptr ) { CameraThread:: camerathread = new  CameraThread  ( ) ; } return  CameraThread:: camerathread; 
} 
CameraThread :: CameraThread ( ) 
{ this -> isRun = true ; cap. open ( 0 ) ; this -> frame_width =  static_cast < int > ( cap. get ( CAP_PROP_FRAME_WIDTH) ) ; this -> frame_height =  static_cast < int > ( cap. get ( CAP_PROP_FRAME_HEIGHT) ) ; int  fourcc =  VideoWriter :: fourcc ( 'X' ,  'V' ,  'I' ,  'D' ) ; Size frameSize ( frame_width,  frame_height) ; this -> isRun_s= false ; this -> isStop= false ; this -> isRecord= false ; this -> isPersistent= false ; this -> recordNum= 0 ; } bool  CameraThread :: getIsStop ( )  const 
{ return  isStop; 
} void  CameraThread :: setIsStop ( bool  value) 
{ isStop =  value; 
} bool  CameraThread :: getIsRecord ( )  const 
{ return  isRecord; 
} void  CameraThread :: setIsRecord ( bool  value) 
{ isRecord =  value; if ( this -> isRecord ==  false  &&  writer. isOpened ( ) ) { qDebug ( ) << "手动关闭" << endl; writer. release ( ) ; this -> recordNum = 0 ; } 
} VideoWriter CameraThread :: getWriter ( )  const 
{ return  writer; 
} bool  CameraThread :: getIsPersistent ( )  const 
{ return  isPersistent; 
} void  CameraThread :: setIsPersistent ( bool  value) 
{ isPersistent =  value; 
} bool  CameraThread :: getIsRun_s ( )  const 
{ return  isRun_s; 
} void  CameraThread :: setIsRun_s ( bool  value) 
{ isRun_s =  value; 
} 
void  CameraThread :: detecCarDaw ( Mat & frame,  CascadeClassifier & cascade,  double  scale) 
{ Mat gray; cvtColor ( frame, gray, CV_BGR2GRAY) ; Mat smalling ( cvRound ( frame. rows/ scale) , cvRound ( frame. cols/ scale) , CV_8UC1) ; resize ( gray, smalling, smalling. size ( ) , 0 , 0 , INTER_LINEAR) ; equalizeHist ( smalling, smalling) ; vector< Rect> cars; cascade. detectMultiScale ( smalling, cars, 1.1 , 2 , 0 | CV_HAAR_SCALE_IMAGE, Size ( 30 , 30 ) ) ; vector< Rect> :: const_iterator iter; for ( iter = cars. begin ( ) ; iter!= cars. end ( ) ; iter++ ) { rectangle ( frame, cvPoint ( cvRound ( iter-> x* scale) , cvRound ( iter-> y* scale) ) , cvPoint ( cvRound ( ( iter-> x+ iter-> width) * scale) , cvRound ( ( iter-> y+ iter-> height) * scale) ) , Scalar ( 0 , 255 , 0 ) , 2 , 8 ) ; } 
} int  CameraThread :: getFrame_height ( )  const 
{ return  frame_height; 
} int  CameraThread :: getFrame_width ( )  const 
{ return  frame_width; 
} bool  CameraThread :: getIsRun ( )  const 
{ return  isRun; 
} void  CameraThread :: setIsRun ( bool  value) 
{ isRun =  value; 
} 
void  CameraThread :: run ( ) 
{ cascade. load ( "D:/OpenCV/cars.xml" ) ; while ( this -> isRun == true ) { if ( cap. read ( frame) ) { cvtColor ( frame, frame, CV_BGR2RGB) ; detecCarDaw ( frame, cascade, 2 ) ; emit sendQImage ( frame) ; if ( this -> isStop == false ) { if ( this -> isRun_s ==  true ) { if ( cap. read ( frame) ) { if ( this -> isRecord== true ) { if ( this -> recordNum == 0 ) { QDateTime current_date_time = QDateTime :: currentDateTime ( ) ; QString current_date = current_date_time. toString ( "yyyy-MM-dd-hh-mm-ss" ) ; QString filename = "D:/Qtsoft/videoDemo/data/" + current_date+ ".avi" ; qDebug ( ) << "filename=" << filename; writer. open ( filename. toStdString ( ) . c_str ( ) , CV_FOURCC ( 'M' , 'J' , 'P' , 'G' ) , 30.0 , Size ( frame. cols, frame. rows) , true ) ; } if ( ! writer. isOpened ( ) ) { qDebug ( ) << "录制路径失败!!!" << endl; } else { if ( this -> recordNum< 300 ) { writer<< frame; this -> recordNum++ ; } else { qDebug ( ) << "已经到300帧结束录制" ; writer. release ( ) ; this -> recordNum = 0 ; if ( this -> isPersistent== true ) { this -> isRecord = true ; } else  if ( this -> isPersistent == false ) { this -> isRecord = false ; } } } } cvtColor ( frame, frame, CV_BGR2RGB) ; } msleep ( 10 ) ; } } } } } # ifndef  MAINWINDOW_H # define  MAINWINDOW_H # include  <QMainWindow> # include  "camerathread.h" namespace  Ui { 
class  MainWindow ; 
} class  MainWindow  :  public  QMainWindow { Q_OBJECTpublic : explicit  MainWindow ( QWidget * parent =  nullptr ) ; ~ MainWindow ( ) ; void  paintEvent ( QPaintEvent *  Eevent) ; 
private : Ui:: MainWindow * ui; CameraThread * ct; 
QImage image; Mat frame; 
private  slots: void  isChecked ( Mat frame) ; void  on_pushButton_clicked ( ) ; void  on_checkBox_clicked ( bool  checked) ; 
} ; # endif  # include  "mainwindow.h" # include  "ui_mainwindow.h" MainWindow :: MainWindow ( QWidget * parent)  : QMainWindow ( parent) , ui ( new  Ui:: MainWindow) 
{ ui-> setupUi ( this ) ; this -> ct = CameraThread :: getInstance ( ) ; connect ( this -> ct, SIGNAL ( sendQImage ( Mat) ) , this , SLOT ( isChecked ( Mat) ) , Qt:: BlockingQueuedConnection) ; this -> ct-> start ( ) ; 
waitKey ( 40 ) ; 
} MainWindow :: ~ MainWindow ( ) 
{ delete  ui; 
} void  MainWindow :: paintEvent ( QPaintEvent * Eevent) 
{ ui-> label-> setPixmap ( QPixmap :: fromImage ( this -> image) ) ; QImage q_image =  QImage ( frame. data, frame. cols, frame. rows, QImage:: Format_RGB888) ; ui-> label-> setPixmap ( QPixmap :: fromImage ( q_image) ) ; ui-> label-> setScaledContents ( true ) ; 
} void  MainWindow :: isChecked ( Mat frame) 
{ this -> image = QImage ( frame. data, frame. cols, frame. rows, QImage:: Format_RGB888) ; this -> image =  this -> image. scaled ( ui-> label-> width ( ) , ui-> label-> height ( ) ) ; this -> frame =  frame. clone ( ) ; this -> update ( ) ; 
} void  MainWindow :: on_pushButton_clicked ( ) 
{ if ( this -> ct-> getWriter ( ) . isOpened ( ) ) { qDebug ( ) << "已经有录制项目:请先结束录制,再操作" ; return ; } this -> ct-> setIsRun_s ( true ) ; this -> ct-> setIsRecord ( true ) ; } void  MainWindow :: on_checkBox_clicked ( bool  checked) 
{ if ( checked== true ) { this -> ct-> setIsRecord ( true ) ; this -> ct-> setIsPersistent ( true ) ; } else  if ( checked== false ) { this -> ct-> setIsPersistent ( false ) ; } 
} # include  "mainwindow.h" # include  <QApplication> int  main ( int  argc,  char  * argv[ ] ) 
{ QApplication a ( argc,  argv) ; MainWindow w; w. show ( ) ; return  a. exec ( ) ; 
}