【QT+OpenCV】美图软件简易版

通过QT和OpenCV设计一款简易的美图软件,了解其中对于图片操作的方法

1.新建QT项目,在.pro文件中添加OpenCV通过cmake编译后的文件

2.在mainwindow.h中输入以下代码

 

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include 
#include    //opencv的头文件
#include                //QT有关图片的头文件
#include               //标签控件里面的图片格式头文件

using namespace  cv;

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    QImage MatToImage(Mat &m);        //将Mat格式转化成QImage类型
    void whiteFace(Mat &m);           //改变Mat中所有像素点的对比度或者亮度

private slots:
    void openActionSlot();    //打开图像文件的槽函数

    void on_constrastSlider_valueChanged(int value);  //对比度条的槽函数

    void on_brightSlider_valueChanged(int value);     //亮度条的槽函数

    void on_originalButton_pressed();             //原图按钮按下时的槽函数

    void on_originalButton_released();             //原图按钮松开时的槽函数

    void on_beautyButton_clicked();               //磨皮按钮的槽函数

    void on_matButton_clicked();                  //抠图按钮的槽函数

private:
    Ui::MainWindow *ui;
    QImage src;                //图片
    QString fileName;          //文件名
    float m_contrast;          //图片对比度
    int m_bringtnees;          //图片亮度
    Mat m_mat;                //原始Mat数据
    Mat rest;                //调整后的Mat数据
};

#endif // MAINWINDOW_H

2.在mainwindow.cpp中输入以下代码

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include    //打开文件的头文件
#include         //QT标准输出

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //点击打开,释放信号,执行打开文件的槽函数
    connect(ui->openAction, &QAction::triggered, this, &MainWindow::openActionSlot);

    //初始化对比度和亮度
    m_contrast = 1;
    m_bringtnees = 0;

    //初始化对比度slider,设置最大最小值,每个刻度值,标志
    ui->constrastSlider->setMinimum(-10);
    ui->constrastSlider->setMaximum(10);
    ui->constrastSlider->setSingleStep(1);
    ui->constrastSlider->setTickPosition(QSlider::TicksAbove);

    //初始化亮度slider, 设置最大最小和刻度
    ui->brightSlider->setMinimum(-50);
    ui->brightSlider->setMaximum(50);
    ui->brightSlider->setSingleStep(10);
}

MainWindow::~MainWindow()
{
    delete ui;
}

QImage MainWindow::MatToImage(Mat &m)   //Mat格式转化QImage类型
{
    switch (m.type()) {    //判断Mat的类型,从而返回不同类型的img
        case CV_8UC1:{
            // 通过QImage::QImage(uchar *data, int width, int height, int bytesPerLine,
             // QImage::Format format, QImageCleanupFunction cleanupFunction = nullptr,
              //void *cleanupInfo = nullptr),主要修改后两个非默认的参数
            QImage img((uchar*)m.data,m.cols,m.rows,m.cols*1,QImage::Format_Grayscale8);
            return img;
        }
        case CV_8UC3:{
            QImage img((uchar*)m.data,m.cols,m.rows,m.cols*3,QImage::Format_RGB888);
            return img.rgbSwapped();
        }
        case CV_8UC4:{
            QImage img((uchar*)m.data,m.cols,m.rows,m.cols*4,QImage::Format_ARGB32);
            return img;
        }
        default:{
            QImage img;
            return img;
        }
    }
}

void MainWindow::whiteFace(Mat &m)    //改变Mat中所有像素点的对比度或者亮度
{
    //理解Mat的原理,通过三层循环找到每一个像素点
    for(int i = 0; i(i,j)[k] = saturate_cast(m_contrast * m_mat.at(i,j)[k] + m_bringtnees);
            }
        }
    }
}

void MainWindow::openActionSlot()    //打开文件的槽函数
{
    //设置文件路径和打开文件的格式
     fileName = QFileDialog::getOpenFileName(this, "选择图片",
                        "C:\\Users\\67098\\Desktop","*.png *.xpm *.jpg");
    //如果打开文件不为空
     if(!fileName.isEmpty())
    {
        src.load(fileName);   //将图片导入图片src中
        ui->label->setPixmap(QPixmap::fromImage(src));  //将图片放置在标签中,转换格式

        //把QString转化成String类型
        QByteArray ba;
        ba.append(fileName);

        //用string格式读取该路径下的图片,保存至Mat格式
        m_mat = imread(ba.data());

        //初始化rest,输入高度,宽度,类型
        rest = Mat(m_mat.rows, m_mat.cols, m_mat.type());
    }
}

void MainWindow::on_constrastSlider_valueChanged(int value)  //对比度的槽函数
{


    m_contrast = 1 + (float)value / 10;   //对比度为当前值除以10加1

    whiteFace(rest);                      //将需要修改的rest传入改变像素对比度

    QImage src = MatToImage(rest);         //将修改后的rest转化成QImage格式,保存至src中
    ui->label->setPixmap(QPixmap::fromImage(src));  //用标签展示修改后的src
}

void MainWindow::on_brightSlider_valueChanged(int value)  //亮度的槽函数
{
    m_bringtnees = value;               //亮度为改变的值

    whiteFace(rest);                    //将需要修改的rest传入改变像素亮度
    QImage src = MatToImage(rest);        //将修改后的rest转化成QImage格式,保存至src中
    ui->label->setPixmap(QPixmap::fromImage(src));  //用标签展示修改后的src
}
void MainWindow::on_originalButton_pressed()    //原图按钮点击的槽函数
{
    QImage src = MatToImage(m_mat);             //将原始m_mat转化成QImage, 保存至src中
    ui->label->setPixmap(QPixmap::fromImage(src));  //用标签展示修改后的src
}

void MainWindow::on_originalButton_released()   //原图按钮松开的槽函数
{
    QImage src = MatToImage(rest);              //将修改后的rest转化成QImage格式,保存至src中
    ui->label->setPixmap(QPixmap::fromImage(src));  //用标签展示修改后的src
}

void MainWindow::on_beautyButton_clicked()     //磨皮按钮的槽函数
{
    int val = 40;                  //先设置val, 可以通过opencv搜索双边滤波和高斯滤波
    Mat bfMat;
    //双边滤波
    bilateralFilter(m_mat, bfMat, val, val*2, val/2);

    //非锐化掩蔽 图像增强
    GaussianBlur(bfMat, rest, Size(3,3), 1, 1);

    addWeighted(bfMat, 1.5, rest, -0.5, 0, rest);//将模糊的图片bfMat和之前修改的图片叠加在一块,保存至rest
    QImage src = MatToImage(rest);                //将修改后的rest转化成QImage格式,保存至src中
    ui->label->setPixmap(QPixmap::fromImage(src));  //用标签展示修改后的src
}

void MainWindow::on_matButton_clicked()    //抠图按钮的槽函数
{
    Mat hsvMat, destFrame;
    //先把BGR模型转换成HSV
    cvtColor(m_mat, hsvMat, COLOR_BGR2HSV);
    //确定hsvMat中需要抠图的像素范围,并保存至desFrame中,不在范围的将是黑色,在范围内的是白色
    inRange(hsvMat, Scalar(0, 1, 7), Scalar(170, 204, 254), destFrame);
    //这一段用来输出图片中100行的所有像素的值,可以通过该值确定背景色的范围,从而选择出需要抠图的像素范围
//    for(int i = 0; i < hsvMat.cols; i++)
//    {
//        qDebug() << hsvMat.at(100,i)[0] << hsvMat.at(100,i)[1] << hsvMat.at(100,i)[2];
//    }

    cvtColor(destFrame, destFrame, COLOR_GRAY2BGR);   //将desFrame变成BGR格式,并保存在desFrame中
    bitwise_and(m_mat, destFrame, rest);       //通过原始图片和抠图图片进行与运算,保存至rest中


    QImage src = MatToImage(rest);              //将修改后的rest转化成QImage格式,保存至src中
    ui->label->setPixmap(QPixmap::fromImage(src));   //用标签展示修改后的src
}

3.设置mainwindow.ui

【QT+OpenCV】美图软件简易版_第1张图片

 【QT+OpenCV】美图软件简易版_第2张图片

 4.点击编译,执行代码,先点击“打开”

【QT+OpenCV】美图软件简易版_第3张图片

 5.选择需要美化的图片

【QT+OpenCV】美图软件简易版_第4张图片

 6.修改对比度或者亮度

【QT+OpenCV】美图软件简易版_第5张图片

 【QT+OpenCV】美图软件简易版_第6张图片

 7.按下“原图”,变成原图,松开“原图”,变成修改后的图片

【QT+OpenCV】美图软件简易版_第7张图片

 8.点击“磨皮”,图片质感变得柔和

【QT+OpenCV】美图软件简易版_第8张图片

 9.点击抠图,因为代码中的抠图效果实现是通过排除背景色,所以如果人像中出现与背景色一致的颜色,则也会被处理

【QT+OpenCV】美图软件简易版_第9张图片

 

 

你可能感兴趣的:(opencv,qt,人工智能)