qml+opencv(二)

本文介绍了一个基于OpenCV的人脸检测算法实现。通过使用Haar分类器进行人脸定位,并实现了简单的图像预处理步骤如灰度转换、图像缩放及直方图均衡化。此外,文章还展示了如何将该算法集成到OpenCV项目中。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实现人脸检测。opencv提供了Haar分类器,其在data文件下还提供了训练的数据,所以实现这个不是很难。
我继承OpenCVaction,实现了人脸检测的算法。

#ifndef OPENCVFACEDETECTACTION_H
#define OPENCVFACEDETECTACTION_H
#include "opencvaction.h"
 class OpenCVfaceDetectAction : public OpenCVaction { Q_OBJECT public: OpenCVfaceDetectAction(QObject *parent = 0); ~OpenCVfaceDetectAction(); void action(IplImage *imgin, IplImage *&imgout); signals: void a(); private: CvHaarClassifierCascade* m_cascade; CvMemStorage* m_storage; double m_scale; }; #endif // OPENCVFACEDETECTACTION_H #include "opencvfacedetectaction.h" #include <QDebug> const char* cascade_name = "data/haarcascade_frontalface_alt.xml"; OpenCVfaceDetectAction::OpenCVfaceDetectAction(QObject *parent): OpenCVaction(parent), m_cascade(NULL), m_storage(NULL), m_scale(1.3) { m_cascade = (CvHaarClassifierCascade*)cvLoad(cascade_name, 0, 0, 0); if (!m_cascade) { qDebug() << "load Cascade fail!"; } m_storage = cvCreateMemStorage(0); } OpenCVfaceDetectAction::~OpenCVfaceDetectAction() { if (m_cascade) { cvReleaseHaarClassifierCascade(&m_cascade); } cvReleaseMemStorage(&m_storage); } void OpenCVfaceDetectAction::action(IplImage *imgin, IplImage *&imgout) { imgout = cvCloneImage(imgin); if (!m_cascade) { qDebug() << "Cascade is invaild!"; return; } static CvScalar color = CV_RGB(255, 255, 255); //Image Preparation // IplImage* gray = cvCreateImage(cvGetSize(imgin), 8, 1); IplImage* small_img = cvCreateImage(cvSize(cvRound(imgin->width / m_scale), cvRound(imgin->height / m_scale)), 8, 1); cvCvtColor(imgin, gray, CV_BGR2GRAY); cvResize(gray, small_img, CV_INTER_LINEAR); cvEqualizeHist(small_img, small_img); //直方图均衡 //Detect objects if any // cvClearMemStorage(m_storage); double t = (double)cvGetTickCount(); CvSeq *objects = cvHaarDetectObjects(small_img, m_cascade, m_storage, 1.1, 2, 0, cvSize(50,50)); t = (double)cvGetTickCount() - t; qDebug() << "detection time =" << t / ((double)cvGetTickFrequency()*1000.) << "ms"; //Loop through found objects and draw boxes around them for(int i=0; i < (objects ? objects->total : 0); ++i) { CvRect* r = (CvRect*)cvGetSeqElem(objects, i); cvRectangle(imgout, cvPoint(r->x * m_scale, r->y * m_scale), cvPoint((r->x + r->width) * m_scale, (r->y + r->height) * m_scale), color, 2, CV_AA); } cvReleaseImage(&gray); cvReleaseImage(&small_img); emit a(); } 

在OpenCVshowFrame中,添加下面

 OpenCVfaceDetectAction *f = new OpenCVfaceDetectAction(); m_actions.push_back(f);

就ok了。
运行效果如下:
这里写图片描述

转载于:https://my.oschina.net/u/854744/blog/418190

### 如何在 QML 中集成与配置 OpenCV 要在 QML 中集成和配置 OpenCV,通常需要通过 C++ 后端实现 OpenCV 的功能,并将其暴露给 QML 层面进行调用。以下是具体方法: #### 1. 安装 OpenCV 库 确保已经在 Linux 或其他操作系统上成功安装了 OpenCV 库[^3]。如果尚未完成此步骤,则需按照官方文档或相关教程(如 Ubuntu 下的编译指南[^2])完成 OpenCV 的安装。 #### 2. Qt 项目设置 为了使 OpenCV 能够正常工作于 Qt 项目中,在 `.pro` 文件中添加必要的路径和链接库: ```plaintext INCLUDEPATH += /path/to/opencv/include LIBS += -L/path/to/opencv/lib \ -lopencv_core \ -lopencv_imgproc \ -lopencv_highgui \ -lopencv_videoio ``` 上述路径应替换为实际环境中 OpenCV 的头文件目录以及动态库所在位置[^1]。 #### 3. 创建自定义 QObject 类桥接 QMLOpenCV 由于 QML 不支持直接访问 OpenCV 功能,因此可以创建一个继承 `QObject` 的类作为桥梁。该类封装所需的功能并将它们注册到 QML 上下文中以便使用。 ##### 示例代码 (C++) ```cpp #include <QObject> #include <QString> #include <QImage> // 导入 opencv 头文件 #include <opencv2/core.hpp> #include <opencv2/imgcodecs.hpp> #include <opencv2/highgui.hpp> class ImageProcessor : public QObject { Q_OBJECT public: explicit ImageProcessor(QObject *parent = nullptr) : QObject(parent) {} // 将 cv::Mat 转换为 QImage 并返回其数据 URL 表示形式 QString processAndConvert(const QString &filePath); signals: private slots: }; QString ImageProcessor::processAndConvert(const QString &filePath){ cv::Mat img = cv::imread(filePath.toStdString()); if(img.empty()){ return ""; } // Convert from BGR to RGB since QImage uses the latter format. cv::cvtColor(img, img, cv::COLOR_BGR2RGB); QImage qImg((uchar*)img.data, img.cols,img.rows, static_cast<int>(img.step), QImage::Format_RGB888); QByteArray byteArray; QBuffer buffer(&byteArray); buffer.open(QIODevice::WriteOnly); qImg.save(&buffer,"PNG"); // writes image into byte array in PNG format return QStringLiteral("data:image/png;base64,") + QString::fromLatin1(byteArray.toBase64().constData()); } ``` #### 4. 注册类型至 QML 为了让上面定义好的 `ImageProcessor` 可用于 QML ,还需要把它注册成上下文属性或者作为一个新的可实例化对象类型提供出来。 ##### 方法 A: 设置为 Context Property ```cpp int main(int argc, char **argv){ QApplication app(argc, argv); QQmlApplicationEngine engine; ImageProcessor processor; engine.rootContext()->setContextProperty(QStringLiteral("imageProcessor"),&processor); const QStringqmlFile=QStringLiteral("qrc:/main.qml"); engine.load(qmlFile); returnapp.exec(); } ``` ##### 方法 B: 使用 plugin 方式加载 另一种更灵活的方式是把此类打包成插件供多个工程共享复用,这里不再赘述细节。 #### 5. 在 QML调用处理函数 一旦完成了以上准备工作之后就可以轻松地从 QML 页面上调用这些接口啦! ##### 主界面 .qml 文件片段 ```javascript import QtQuick 2.15 import QtQuick.Controls 2.15 ApplicationWindow{ visible:true width:640;height:480 Button{ text:"Load and Process" onClicked:{ var result=imageProcessor.processAndConvert("/absolute/path/image.jpg") console.log(result) myImageView.source=result } } ImageView{id:myImageView;} } ``` 这样就实现了基于 QML 对图像资源应用 OpenCV 进行预览显示等功能扩展^。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值