| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413 |
- #include "InteractiveFace.h"
- InteractiveFace::InteractiveFace(QObject *parent) : QQuickImageProvider(QQuickImageProvider::Image)
- {
- initEngine();
- if (hasCamera())
- {
- // initCamera();
- }
- // 图像取1s 10帧
- m_timerId = startTimer(100);
- }
- bool InteractiveFace::hasCamera()
- {
- return !QMediaDevices::videoInputs().isEmpty();
- }
- InteractiveFace::~InteractiveFace()
- {
- destroyEngine();
- }
- void InteractiveFace::initEngine()
- {
- const char* appId = "FTN3G4pk8n2RKwjD955sRapRjbYQFefwhHd4sBZMYEz6";
- const char* sdkKey = "BjJomNU2bQc2SYhT7NNqwvFd9zfc72Q7nneh75r3NT3x";
- const char* licenseFilePath = "./offlineLicense.dat";
- // 超过5次不再尝试获取授权文件
- int iLoopCount = 5;
- do{
- MPChar activeDeviceInfo;
- ASFGetActiveDeviceInfo(&activeDeviceInfo);
- ASF_ActiveFileInfo activeFileInfo;
- MRESULT res = -1;
- if ((res = ASFGetActiveFileInfo(&activeFileInfo)) == MOK)
- {
- qDebug() << "获取版本信息成功";
- break;
- }
- else{
- FileLogger::writeToFile("deviceInfo","ArcSoftDeviceInfo.txt",activeDeviceInfo,FileLogger::WriteMode::OVERWRITE);
- if(res == 0x1601A){
- if((res = ASFOfflineActivation((MPChar)licenseFilePath)) == MOK)
- {
- qDebug() << "授权成功";
- }
- }
- }
- break;
- }while(iLoopCount--);
- // 初始化引擎
- MRESULT res = ASFInitEngine(ASF_DETECT_MODE_VIDEO,
- ASF_OP_ALL_OUT,
- 1,
- ASF_FACE_DETECT | ASF_FACERECOGNITION,
- &m_engine);
- if (res != MOK)
- {
- qDebug() << " 初始化引擎失败" << res;
- }
- }
- void InteractiveFace::destroyEngine()
- {
- }
- void InteractiveFace::cameraPlay()
- {
- // 如果相机不是播放状态
- if (!m_camera.isActive())
- {
- QCameraDevice cameraDevice = QMediaDevices::defaultVideoInput();
- if (cameraDevice.isNull())
- {
- qWarning() << "系统中没有检测到任何摄像机设备";
- return;
- }
- m_camera.setCameraDevice(cameraDevice);
- // 确保图像宽度是4的倍数(虹软人脸识别要求)
- if (m_camera.cameraFormat().resolution().width() % 4 != 0)
- {
- QList<QCameraFormat> cameraFormats = cameraDevice.videoFormats();
- for (int i = 0; i < cameraFormats.size(); ++i)
- {
- const QCameraFormat &cameraFormat = cameraFormats.at(i);
- if (cameraFormat.resolution().width() % 4 == 0)
- {
- m_camera.setCameraFormat(cameraFormat);
- break;
- }
- }
- }
- m_session.setCamera(&m_camera);
- m_session.setVideoSink(&m_videoSink);
- m_camera.start();
- }
- }
- void InteractiveFace::cameraStop()
- {
- if (m_camera.isActive())
- {
- m_camera.stop();
- m_camera.setActive(false);
- m_camera.setCameraDevice(QCameraDevice());
- m_session.setCamera(nullptr);
- m_session.setVideoSink(nullptr);
- }
- }
- void InteractiveFace::initCamera()
- {
- m_camera.setCameraDevice(QMediaDevices::defaultVideoInput());
- QCameraDevice device = QMediaDevices::defaultVideoInput();
- QList<QCameraFormat> formats = device.videoFormats();
- // 选择最适合的格式
- for (const QCameraFormat &format : formats)
- {
- // qDebug() << "fps---" << format.maxFrameRate() << format.resolution().width() << format.resolution().height();
- if (format.maxFrameRate() >= 10.0 && format.resolution().width() % 4 == 0)
- {
- m_camera.setCameraFormat(format);
- break;
- }
- }
- m_session.setCamera(&m_camera);
- m_session.setVideoSink(&m_videoSink);
- }
- void InteractiveFace::destroyCamera()
- {
- }
- QString InteractiveFace::getImageUrl()
- {
- // image://InteractiveFaceImage/(0-9999)
- return QString("image://") +
- QString(INTERACTIVE_FACE_IMAGE_URL) +
- QString("/") +
- // 取随机数,确保图片刷新(Qt机制,两次url地址相同,图片不会显示)
- QString::number(QRandomGenerator::global()->bounded(10000));
- }
- // 设置图像采集回调
- void InteractiveFace::setCameraImageGatherCallBack(QJSValue callback)
- {
- m_imageGatherCallback = callback;
- }
- // 设置发现人脸回调
- void InteractiveFace::setCameraImageAppearCallBack(QJSValue callback)
- {
- m_imageAppearCallback = callback;
- }
- // 设置人脸停留回调
- void InteractiveFace::setCameraImageRemainCallBack(QJSValue callback)
- {
- m_imageRemainCallback = callback;
- }
- void InteractiveFace::setCameraImageCallBack(QJSValue gatherCallback,
- QJSValue appearCallback,
- QJSValue remainCallback)
- {
- m_imageGatherCallback = gatherCallback;
- m_imageAppearCallback = appearCallback;
- m_imageRemainCallback = remainCallback;
- }
- void InteractiveFace::setCallBackFaceStatus(QJSValue isAppearCallback)
- {
- m_isAppearCallback = isAppearCallback;
- }
- void InteractiveFace::cameraImagePlay()
- {
- if (!hasCamera())
- {
- return;
- }
- if (!m_camera.isActive())
- {
- cameraPlay();
- m_laseEpoch = 0;
- m_laseCount = 0;
- m_FrameId = 0;
- }
- }
- void InteractiveFace::cameraImageStop()
- {
- if (!hasCamera())
- {
- return;
- }
- cameraStop();
- }
- QImage InteractiveFace::requestImage(const QString &, QSize *, const QSize &)
- {
- return m_image;
- }
- void InteractiveFace::timerEvent(QTimerEvent *event)
- {
- if (event->timerId() == m_timerId)
- {
- if (!hasCamera())
- {
- return;
- }
- if (m_camera.isActive())
- {
- QMutexLocker locker(&m_mutex);
- QVideoFrame currentFormat = m_videoSink.videoFrame();
- QImage image; // 图像
- QPainter painter; // 画笔
- // 过滤无效帧, 前10帧不做处理
- if(++m_FrameId <= 10)
- {
- m_image = image.copy();
- if (m_imageGatherCallback.isCallable())
- {
- QJSValueList args;
- args << getImageUrl();
- m_imageGatherCallback.call(args);
- }
- return;
- }
- if (currentFormat.isValid())
- {
- if (currentFormat.map(QVideoFrame::ReadOnly))
- {
- image = currentFormat.toImage();
- // image = image.scaled(QSize(800, 600), Qt::KeepAspectRatio, Qt::SmoothTransformation);
- }
- currentFormat.unmap();
- }
- if (!image.isNull())
- {
- // image底部框
- painter.begin(&image);
- painter.setRenderHint(QPainter::Antialiasing);
- painter.setFont(QFont("Arial", 24));
- painter.setBrush(QColor(255, 255, 255, 127));
- painter.setPen(Qt::NoPen);
- painter.drawRect(QRect(0, image.height() - 50, image.width(), 50));
- QImage convertedImage = image.convertToFormat(QImage::Format_RGB888);
- ASVLOFFSCREEN offscreen = {0};
- offscreen.u32PixelArrayFormat = ASVL_PAF_RGB24_B8G8R8;
- offscreen.i32Width = convertedImage.width();
- offscreen.i32Height = convertedImage.height();
- offscreen.pi32Pitch[0] = convertedImage.bytesPerLine();
- offscreen.ppu8Plane[0] = (MUInt8*)convertedImage.bits();
- if (offscreen.ppu8Plane[0])
- {
- if (m_engine != NULL)
- {
- ASF_MultiFaceInfo detectedFaces = {0};
- MRESULT res = ASFDetectFaces(m_engine,
- offscreen.i32Width,
- offscreen.i32Height,
- offscreen.u32PixelArrayFormat,
- offscreen.ppu8Plane[0],
- &detectedFaces);
- if (res != MOK)
- {
- qDebug() << "检测人脸失败" << res;
- }
- bool isAppear;
- // 获取第一个人脸
- if (res == MOK && detectedFaces.faceNum == 1) {
- isAppear = true;
- if (m_laseCount <= 0)
- {
- m_laseCount = 1;
- m_laseEpoch = QDateTime::currentSecsSinceEpoch();
- }
- if (m_imageAppearCallback.isCallable())
- {
- m_image = image.copy();
- QJSValueList args;
- args << getImageUrl();
- m_imageAppearCallback.call(args);
- }
- MRECT mrect = detectedFaces.faceRect[0];
- qint64 epoch = QDateTime::currentSecsSinceEpoch() - m_laseEpoch;
- if (epoch <= 1)
- {
- painter.setPen(QPen(Qt::blue, 3));
- painter.drawText(QRect(0, image.height() - 50, image.width(), 50),
- Qt::AlignCenter,
- QString("检测到人脸,即将拍摄").arg(epoch));
- // 绘制人脸框
- painter.setPen(QPen(Qt::green, 2));
- painter.setBrush(Qt::NoBrush);
- painter.drawRect(QRect(mrect.left,
- mrect.top,
- mrect.right - mrect.left,
- mrect.bottom - mrect.top));
- }
- else if (epoch > 1 && epoch <= 4)
- {
- painter.setPen(QPen(Qt::blue, 3));
- painter.drawText(QRect(0, image.height() - 50, image.width(), 50),
- Qt::AlignCenter,
- QString("%1").arg(5 - epoch));
- // 绘制人脸框
- painter.setPen(QPen(Qt::green, 2));
- painter.setBrush(Qt::NoBrush);
- painter.drawRect(QRect(mrect.left,
- mrect.top,
- mrect.right - mrect.left,
- mrect.bottom - mrect.top));
- }
- else if (epoch >= 5)
- {
- if (m_imageRemainCallback.isCallable())
- {
- QJSValueList args;
- args << getImageUrl();
- m_imageRemainCallback.call(args);
- }
- }
- }
- else if (res == MOK && detectedFaces.faceNum >= 2)
- {
- isAppear = true;
- m_laseCount--;
- painter.setPen(QPen(Qt::red, 3));
- painter.drawText(QRect(0, image.height() - 50, image.width(), 50),
- Qt::AlignCenter,
- QString("请保持单人入镜,请保持光线充足"));
- }
- else
- {
- isAppear = false;
- m_laseCount--;
- painter.setPen(QPen(Qt::red, 3));
- painter.drawText(QRect(0, image.height() - 50, image.width(), 50),
- Qt::AlignCenter,
- QString("请保持真人操作,请保持光线充足"));
- }
- if (m_isAppearCallback.isCallable())
- {
- QJSValueList args;
- args << isAppear;
- m_isAppearCallback.call(args);
- }
- }
- }
- painter.end();
- m_image = image.copy();
- if (m_imageGatherCallback.isCallable())
- {
- QJSValueList args;
- args << getImageUrl();
- m_imageGatherCallback.call(args);
- }
- }
- }
- }
- }
- // 获取图像
- QImage InteractiveFace::getImage()
- {
- QMutexLocker locker(&m_mutex);
- return m_image.copy();
- }
|