# Qt5.12 opencv4.5.3 Mingw编译 yolo 识别屏幕,并模拟鼠标动作()
#opencv编译安装
请参照这里:https://blog.csdn.net/weixin_42322013/article/details/88808230
遇到问题:[ 37%] Built target IlmImf
[ 37%] Built target libprotobuf
C:/Qt/Qt5.14.2/Tools/mingw730_64/bin/…/lib/gcc/x86_64-w64-mingw32/7.3.0/…/…/.
./…/x86_64-w64-mingw32/bin/ld.exe: i386 architecture of input file `CMakeFiles
opencv_core.dir/objects.a(vs_version.rc.obj)’ is incompatible with i386:x86-64 o
utput
collect2.exe: error: ld returned 1 exit status
mingw32-make[2]: *** [modules\core\CMakeFiles\opencv_core.dir\build.make:1630: b
in/libopencv_core453d.dll] Error 1
mingw32-make[1]: *** [CMakeFiles\Makefile2:1749: modules/core/CMakeFiles/opencv_
core.dir/all] Error 2
mingw32-make: *** [Makefile:165: all] Error 2
解决方法:
cmake里面手动添加:OPENCV_VS_VERSIONINFO_SKIP
cmake界面按钮: add Entry —>>> BOOL —>>> OPENCV_VS_VERSIONINFO_SKIP 打钩
————————————————
因为opencv 4.5.1 和4.5.2 安装时部分内容无法下载,导致安装失败,最后采用4.5.3 安装成功
yolo:
yolo可采用yolo3 yolo4 yolofaster等
参考的是:https://blog.csdn.net/nihate/article/details/108850477
并进行了小修改:
qt界面:
qt界面采用的是自带教程中的截图demo。即screenshot。
流程:
截图,将截图图像转换未Mat 类型,传给目标检测,得到结果再转为pixmap格式,用lable显示,主框架一个线程,目标检测在另一个线程,同时得到人物目标屏幕位置,操控鼠标动作。
#include "cudpthread.h"
#include <QDebug>
#include <QGuiApplication>
#include <QWindow>
CUdpThread::CUdpThread( QWidget *parent )
{
stopFlag=false;
// qDebug()<< parent->objectName();
//w=parent;
number=0;
mouseact = new MouseAct(); //鼠标事件
}
CUdpThread::~CUdpThread()
{
stopFlag=false;
}
//更改之后加入组播
void CUdpThread::run()
{
YOLO yolo_model(yolo_nets[2]);
QScreen *screen = QGuiApplication::primaryScreen();
if (!screen)
{
return;
}
Mat srcimg;
int i=0;
do{
originalPixmap = screen->grabWindow(0);
srcimg= QPixmapToCvMat(originalPixmap);
yolo_model.detect(srcimg);
waitKey(1);
if(yolo_model.xy.size()>2)
{
mouseact->getClickedPos();
qDebug()<<mouseact->pos.x<<mouseact->pos.y;
mouseact->doPressAct(yolo_model.xy.at(0),yolo_model.xy.at(1),0);//执行鼠标动作。
}
originalPixmap = cvMatToQPixmap(srcimg);
emit signalSendData(originalPixmap); //发送其他信号
i++;
if(i%100 == 1) {
qDebug()<<i;
emit SendaudioData( stopFlag);
}
}while(stopFlag);
}
void CUdpThread::ReadPendingDatagrams(bool flag)
{
stopFlag = flag;
run();
}
QImage CUdpThread::cvMatToQImage( const cv::Mat &inMat ){
switch ( inMat.type() )
{
case CV_8UC4:
{
QImage image( inMat.data,
inMat.cols, inMat.rows,
static_cast<int>(inMat.step),
QImage::Format_ARGB32 );
return image;
}
// 8-bit, 3 channel
case CV_8UC3:
{
QImage image( inMat.data,
inMat.cols, inMat.rows,
static_cast<int>(inMat.step),
QImage::Format_RGB888 );
return image.rgbSwapped();
}
// 8-bit, 1 channel
case CV_8UC1:
{
#if QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)
QImage image( inMat.data,
inMat.cols, inMat.rows,
static_cast<int>(inMat.step),
QImage::Format_Grayscale8 );//Format_Alpha8 and Format_Grayscale8 were added in Qt 5.5
#else//这里还有一种写法,最后给出
static QVector<QRgb> sColorTable;
// only create our color table the first time
if ( sColorTable.isEmpty() )
{
sColorTable.resize( 256 );
for ( int i = 0; i < 256; ++i )
{
sColorTable[i] = qRgb( i, i, i );
}
}
QImage image( inMat.data,
inMat.cols, inMat.rows,
static_cast<int>(inMat.step),
QImage::Format_Indexed8 );
image.setColorTable( sColorTable );
#endif
return image;
}
default:
qWarning() << "CVS::cvMatToQImage() - cv::Mat image type not handled in switch:" << inMat.type();
break;
}
return QImage();
}
QPixmap CUdpThread::cvMatToQPixmap( const cv::Mat &inMat ){
return QPixmap::fromImage( cvMatToQImage( inMat ) );
}
cv::Mat CUdpThread::QImageToCvMat( const QImage &inImage, bool inCloneImageData ){
switch ( inImage.format() )
{
// 8-bit, 4 channel
case QImage::Format_ARGB32:
case QImage::Format_ARGB32_Premultiplied:
{
cv::Mat mat( inImage.height(), inImage.width(),
CV_8UC4,
const_cast<uchar*>(inImage.bits()),
static_cast<size_t>(inImage.bytesPerLine())
);
return (inCloneImageData ? mat.clone() : mat);
}
// 8-bit, 3 channel
case QImage::Format_RGB32:
case QImage::Format_RGB888:
{
if ( !inCloneImageData )
{
qWarning() << "CVS::QImageToCvMat() - Conversion requires cloning because we use a temporary QImage";
}
QImage swapped = inImage;
if ( inImage.format() == QImage::Format_RGB32 )
{
swapped = swapped.convertToFormat( QImage::Format_RGB888 );
}
swapped = swapped.rgbSwapped();
return cv::Mat( swapped.height(), swapped.width(),
CV_8UC3,
const_cast<uchar*>(swapped.bits()),
static_cast<size_t>(swapped.bytesPerLine())
).clone();
}
// 8-bit, 1 channel
case QImage::Format_Indexed8:
{
cv::Mat mat( inImage.height(), inImage.width(),
CV_8UC1,
const_cast<uchar*>(inImage.bits()),
static_cast<size_t>(inImage.bytesPerLine())
);
return (inCloneImageData ? mat.clone() : mat);
}
default:
qWarning() << "CVS::QImageToCvMat() - QImage format not handled in switch:" << inImage.format();
break;
}
return cv::Mat();
}
cv::Mat CUdpThread::QPixmapToCvMat( const QPixmap &inPixmap, bool inCloneImageData ){
return QImageToCvMat( inPixmap.toImage(), inCloneImageData );
}