一、下载安装OpenCV
1、linux: sudo apt install libopencv-dev
2、winodws:打开OpenCV官网:http://opencv.org/Release下载OpenCV
二、 主要源码
1、在pro中引用lib
LIBS += -lopencv_core -lopencv_highgui -lopencv_imgproc -lopencv_videoio -lopencv_imgcodecs
2、创建OpenCVCamera类
因为需要把采集的每一帧图像缓存起来显示,所以用到了QQuickImageProvider,注释部分是测试opcencv算法,
大家可以放开试用一下效果。
opencvcamera.h
#ifndef OPENCVCAMERA_H
#define OPENCVCAMERA_H
#include <QObject>
#include <QImage>
#include <QQuickImageProvider>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
class OpenCVCamera : public QObject, public QQuickImageProvider
{
Q_OBJECT
public:
explicit OpenCVCamera(QObject *parent = nullptr);
~OpenCVCamera();
//返回的image
QImage requestImage(const QString& id, QSize* size, const QSize& requestedSize) override;
//设置图像
static void setImage(const QImage &image);
signals:
void imageReady(QImage img);
public slots:
void startCapture();
void stopCapture();
void gaussian_noise(Mat &image);
void add_salt_pepper_noise(Mat &image);
private:
cv::VideoCapture m_cap;
static QImage ms_image;
};
#endif // OPENCVCAMERA_H
opencvmera.cpp
#include "opencvcamera.h"
#include <QDebug>
#include <QThread>
#include <QCoreApplication>
QImage OpenCVCamera::ms_image(":/ima/EMSbig.png");
OpenCVCamera::OpenCVCamera(QObject *parent) : QQuickImageProvider(QQmlImageProviderBase::Image)
{
}
OpenCVCamera::~OpenCVCamera()
{
stopCapture(); // 程序退出时释放资源
}
QImage OpenCVCamera::requestImage(const QString &id, QSize *size, const QSize &requestedSize)
{
qDebug()<<"ImageProvider::requestImage"<<id;
return ms_image ;
}
void OpenCVCamera::setImage(const QImage &image)
{
qDebug()<<"ImageProvider::setImage"<<image;
ms_image = image;
//这里为了检查图像是否正常,做了一个保存
// ms_image.save(QCoreApplication::applicationDirPath()+"/ima/2.jpg");
}
void OpenCVCamera::startCapture()
{
if (!m_cap.isOpened()) { // 如果尚未打开摄像头,则打开默认摄像头(设备号为0)
m_cap.open(0);
}
Mat frame; // 创建Mat对象用于存储图像帧
while (true) {
// QThread::currentThread()->msleep(80); // too much wait
m_cap >> frame; // 从摄像头读取一帧图像
if (!frame.empty()) { // 如果成功读取到了图像
//Mat转QImage 颜色
cvtColor(frame,frame,CV_BGR2RGB);
// 中值滤波
medianBlur(frame, frame, 5);
// gaussian_noise(frame);
// Mat result1, result2, result3, result4;
// blur(frame, result1, Size(5, 5));
// imshow("result-1", result1);
// GaussianBlur(frame, result2, Size(5, 5), 0);
// imshow("result-2", result2);
// medianBlur(frame, result3, 5);
// imshow("result-3", result3);
// fastNlMeansDenoisingColored(frame, result4, 15, 15, 10, 30);
// imshow("result-4", result4);
// Mat retumage;
//高斯模糊
// GaussianBlur(frame,retumage,Size(5,5),0,0);
//双倍模糊
// cv::bilateralFilter(frame,retumage,15,120,10,4);
//灰度化
// cvtColor(frame,retumage,CV_BGR2GRAY);
// cvtColor(retumage,retumage,CV_GRAY2BGR);
QImage img(frame.data, frame.cols, frame.rows, static_cast<int>(frame.step), QImage::Format_RGB888); // 将Mat转换成QImage
// imagemEditada.save(QCoreApplication::applicationDirPath()+"/ima/2.jpg");
OpenCVCamera::setImage(img);
emit imageReady(img); // 发射信号,将QImage对象传递给QML界面
}
if (waitKey(30) >= 0) { // 每30ms读取一帧
}
}
}
void OpenCVCamera::stopCapture()
{
if (m_cap.isOpened()) { // 如果摄像头已打开,则释放资源
m_cap.release();
}
}
void OpenCVCamera::gaussian_noise(Mat &image)
{
Mat noise = Mat::zeros(image.size(), image.type());
randn(noise, (15, 15, 15), (30, 30, 30));
Mat dst;
add(image, noise, dst);
imshow("gaussian noise", dst);
dst.copyTo(image);
}
void OpenCVCamera::add_salt_pepper_noise(Mat &image)
{
RNG rng(12345);
int h = image.rows;
int w = image.cols;
int nums = 10000;
for (int i = 0; i < nums; i++) {
int x = rng.uniform(0, w);
int y = rng.uniform(0, h);
if (i % 2 == 1) {
image.at<Vec3b>(y, x) = Vec3b(255, 255, 255);
}
else {
image.at<Vec3b>(y, x) = Vec3b(0, 0, 0);
}
}
imshow("salt pepper", image);
}
3 、在main.cpp注册OpenCVCamera类到QML上下文中,注册 ImageProvider, 并且指定前缀, 该前缀在qml中使用, image:// 前缀表示 图片来自于 ImageProvider
qmlRegisterType<OpenCVCamera>("com.example.opencv", 1, 0, "OpenCVCamera");
engine.addImageProvider("imageprovider",new OpenCVCamera());
4、在main.qml中
Button{
text: "Start"
onClicked: {
camera.startCapture();
}
}
Button{
text: "Stop"
onClicked: {
camera.stopCapture();
}
}
Image{
id: bigImageItem
width: parent.height
height:parent.height
cache: false
anchors.right: parent.right //基于父控件靠右对齐
source: "qrc:/windowRes/EMSbig.png"
fillMode: Image.PreserveAspectCrop
}
OpenCVCamera {
id: camera
property int imgid: 1
onImageReady: {
imgid++;
bigImageItem.source = "image://imageprovider/" +imgid;//需要使用 source: "image://标识符/图片id" 的格式来加载;
}
}
这次就写到这里,我想做两部分来写视频采集,第一部分写怎么实现,第二部分写有关移植到开发板上运行,因为我的开发板没有支持uvc,看不到效果,下次实现了就分享给大家。