日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

QT+OpenCV照片动画风格转换

發布時間:2025/3/21 c/c++ 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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); }

運行結果:

參考鏈接:
https://zhuanlan.zhihu.com/p/24416498
http://blog.csdn.net/liyuanbhu/article/details/46662115
http://blog.csdn.net/AP1005834/article/details/51263012

總結

以上是生活随笔為你收集整理的QT+OpenCV照片动画风格转换的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。