失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > QT+OpenCV照片动画风格转换

QT+OpenCV照片动画风格转换

时间:2024-04-13 07:37:46

相关推荐

QT+OpenCV照片动画风格转换

前言

用OpenCV将摄像头采集到的图片转换成动画风格,加上了QT界面。这个小实验并不复杂,后面直接贴代码。

代码

在QT creator中建的工程,只上部分比较重要的代码了,其他都是一样的。

mainWindow.h:定义了一些槽函数以及中间变量。

#ifndef MAINWINDOW_H#define MAINWINDOW_H#include <QMainWindow>#include <QTimer>#include <QDebug>#include <opencv2/opencv.hpp>#include <iostream>namespace Ui {class MainWindow;}class MainWindow : public QMainWindow{Q_OBJECTpublic:explicit MainWindow(QWidget *parent = 0);~MainWindow();QImage cvMat2QImage(const cv::Mat & mat);void cartoonize(cv::Mat & src, cv::Mat & dst);void cartoonize_v2(cv::Mat & src, cv::Mat & dst);private slots:void on_pushButton_clicked();void on_pushButton_2_clicked();void on_pushButton_3_clicked();void readFrame();private:Ui::MainWindow *ui;bool cartoonize_flag;QImage dst_image;QTimer *timer;cv::VideoCapture camera;cv::Mat frame;cv::Mat cartoon_image;};#endif // MAINWINDOW_H

mainWindow.cpp:具体定义了那些函数。

#include "mainwindow.h"#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow){ui->setupUi(this);this->timer = new QTimer(this);this->cartoonize_flag = false;this->connect(this->timer, SIGNAL(timeout()), this, SLOT(readFrame()));}MainWindow::~MainWindow(){delete ui;}//从摄像头读取一帧图像void MainWindow::readFrame(){this->camera >> this->frame;if(frame.empty()){std::cerr<<"ERROR: Couldn't grab a camera frame."<< std::endl;exit(1);}if(this->cartoonize_flag){//this->frame.copyTo(this->cartoon_image);cartoonize(this->frame, this->cartoon_image);cv::cvtColor(this->cartoon_image, this->cartoon_image, cv::COLOR_BGR2RGB);}else{cv::cvtColor(this->frame, this->cartoon_image, cv::COLOR_BGR2RGB);//this->frame.copyTo(this->cartoon_image);}// the image must be converted into RGB, but not the default BGR in OpenCVthis->dst_image = cvMat2QImage(this->cartoon_image);//在GraphicView中显示图像QGraphicsScene *scene = new QGraphicsScene;scene->addPixmap(QPixmap::fromImage(this->dst_image));ui->graphicsView->setScene(scene);ui->graphicsView->show();}//打开摄像头,映射到按键1的槽函数void MainWindow::on_pushButton_clicked(){//Open Camerathis->camera.open(0);if(!this->camera.isOpened()){std::cerr << "Could not access the camera or video!" << std::endl;exit(1);}this->camera.set(cv::CAP_PROP_FRAME_WIDTH, 640);this->camera.set(cv::CAP_PROP_FRAME_HEIGHT, 480);this->timer->start(33);}//是否进行卡通化转换标志,映射到按键2的槽函数void MainWindow::on_pushButton_2_clicked(){//Cartoonizingthis->cartoonize_flag = !this->cartoonize_flag;}//关闭摄像头,映射到按键3的槽函数void MainWindow::on_pushButton_3_clicked(){//Close Camerathis->timer->stop();this->camera.release();exit(1);}//OpenCV中Mat类型转换为Qt中的QImage类型QImage MainWindow::cvMat2QImage(const cv::Mat & mat){//if(!mat.empty())//{//bgr->rgb//cv::cvtColor(mat, mat, cv::COLOR_BGR2RGB);//}switch(mat.type()){case CV_8UC1:{QImage img(mat.cols, mat.rows, QImage::Format_Indexed8);img.setColorCount(255);for(int i=0;i<256;i++){img.setColor(i, qRgb(i,i,i));}uchar * pSrc = mat.data;for(int row=0;row<mat.rows;row++){uchar *pDest = img.scanLine(row);memcpy(pDest, pSrc, mat.cols);pSrc += mat.step;}return img;}case CV_8UC3:{const uchar * pSrc = (const uchar *)mat.data;QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_RGB888);return image.copy();}case CV_8UC4:{const uchar * pSrc = (const uchar *)mat.data;QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_ARGB32);return image.copy();}default:{qDebug() << "ERROR: Mat could not be converted to QImage.";return QImage();}}}//卡通化处理void MainWindow::cartoonize(cv::Mat & src, cv::Mat & dst){cv::Mat gray;cv::cvtColor(src, gray, cv::COLOR_BGR2GRAY);//转成灰度图const int MEDIAN_BLUR_FILTER_SIZE = 7;cv::medianBlur(gray, gray, MEDIAN_BLUR_FILTER_SIZE);//中值滤波cv::Mat edges;const int LAPLACIAN_FILTER_SIZE = 5;cv::Laplacian(gray, edges, CV_8U, LAPLACIAN_FILTER_SIZE);//边缘检测,也可用canny检测或是其他算法cv::Mat mask;const int EDGES_THRESHOLD = 65;cv::threshold(edges, mask, EDGES_THRESHOLD, 255, cv::THRESH_BINARY_INV);//二值化,生成边缘掩码,注意是cv::THRESH_BINARY_INVmask.copyTo(dst);//为了保证处理速度,将图像大小压缩一倍cv::Size srcSize = src.size();cv::Size newSize;newSize.width = srcSize.width / 2;newSize.height = srcSize.height / 2;cv::Mat newImg = cv::Mat(newSize, CV_8UC3);cv::resize(src, newImg, newSize, 0, 0, cv::INTER_LINEAR);//做两次双边滤波cv::Mat tmp = cv::Mat(newSize, CV_8UC3);int repetitions = 3;for(int i=0;i<repetitions;i++){int ksize = 9;double sigmaColor = 11;double sigmaSpace = 5;cv::bilateralFilter(newImg, tmp, ksize, sigmaColor, sigmaSpace);cv::bilateralFilter(tmp, newImg, ksize, sigmaColor, sigmaSpace);}cv::Mat resImg;cv::resize(newImg, resImg, srcSize, 0, 0, cv::INTER_LINEAR);//调整回原来的大小dst.setTo(0);resImg.copyTo(dst, mask);}

运行结果:

参考链接:

/p/24416498

/liyuanbhu/article/details/46662115

/AP1005834/article/details/51263012

如果觉得《QT+OpenCV照片动画风格转换》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。