基于QT+Opencv的红眼去除

**

基于QT+Opencv的红眼去除

**
最近老师布置了一个讨论专题,是关于红眼去除,对于我一个初学者来说,当然是一脸懵了,不过还好百度上有一些资源可以 参考,在几天的了解下,也是成功完成了。
我主要参考:https://blog.csdn.net/LuohenYJ/article/details/90035284
里面讲清楚了红眼去除的原理,以及附带程序;
刚开始并不是完全看懂,但是温故而知新,看了几遍也有了一些理解。
我做的这个红眼实验包括打开图像,红眼处理,保存处理后图像到指定位置。
以下是我在做的过程遇到的一些问题,分享给和我一样的初学者。
首先打开QT,进行窗口的设计:
基于QT+Opencv的红眼去除_第1张图片
这个过程中,一定要记住自己设置的对象名称,如果和程序中不一样的话,会报错,而且不容易发现,我就是记错了,导致我找了半天。
基于QT+Opencv的红眼去除_第2张图片

接下来就是在.pri的地方添加Opencv的路径,因为后面的程序需要调用opencv库。

程序实现

定义私有成员:

// An highlighted block
QGraphicsScene sceneL, sceneR;//场景,新增的
QPixmap pixmapL,pixmapR;//图像,新增的

构造函数定义:

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->openButton->setEnabled(true);
    ui->eyeOutButton->setEnabled(false);
    ui->saveButton->setEnabled(false);
    //关联场景和视图
    ui->graphicsViewL->setScene(&sceneL);
    ui->graphicsViewR->setScene(&sceneR);
}

槽函数:
打开图像:

void MainWindow::on_openButton_clicked()
{
    if(ui->openButton->text()=="关闭图像"){
            sceneL.clear();
            ui->openButton->setText("打开图像");

            ui->saveButton->setEnabled(false);
            ui->eyeOutButton->setEnabled(false);
            return;
      }
      QString fileName = QFileDialog::getOpenFileName(
                                this,
                                "打开图像",
                                QDir::currentPath(),
                                "Images (*.png *.bmp *.jpg *.tif)");
      if (!fileName.isNull()){
            QFileInfo file(fileName);
            if(pixmapL.load(file.absoluteFilePath())){
                sceneL.clear(); //清除原有图像信息
                sceneL.addPixmap(pixmapL);
                ui->openButton->setText("关闭图像");
                ui->saveButton->setEnabled(false);
                ui->eyeOutButton->setEnabled(true);

             }
         }
         return;
}

保存图像:

void MainWindow::on_saveButton_clicked()
{
    QString fileName = QFileDialog::getSaveFileName(
                           this,
                           "保存图像",
                           QDir::currentPath(),
                           "Images (*.png *.bmp *.jpg *.tif)");
   if(pixmapR.save(fileName,0,100))
       QMessageBox::information(this,
                            tr("OK"),
                            tr("保存成功"));
   else
       QMessageBox::information(this,
                            tr("NG"),
                            tr("保存失败"));

   return;
}

红眼处理:

void MainWindow::on_eyeOutButton_clicked()
{
    ImageConversion imgConversion;
    if(!pixmapL.isNull()){
    // Read image 读彩色图像
        Mat img = imread("F:/Qt/hongyanshiyan/hongyan/red_eyes1.jpg", CV_LOAD_IMAGE_COLOR);

        // Output image 输出图像
        Mat imgOut = img.clone();

        // Load HAAR cascade 读取haar分类器
        CascadeClassifier eyesCascade("E:/openCV/openCVwithContrib-3.3.1build/install/etc/haarcascades/haarcascade_eye.xml");

        // Detect eyes 检测眼睛
        std::vector<Rect> eyes;
        //前四个参数:输入图像,眼睛结果,表示每次图像尺寸减小的比例,表示每一个目标至少要被检测到4次才算是真的
        //后两个参数:0 | CASCADE_SCALE_IMAGE表示不同的检测模式,最小检测尺寸
        eyesCascade.detectMultiScale(img, eyes, 1.3, 4, 0 | CASCADE_SCALE_IMAGE, Size(100, 100));

        // For every detected eye 每只眼睛都进行处理
        for (size_t i = 0; i < eyes.size(); i++)
        {
            // Extract eye from the image. 提取眼睛图像
            Mat eye = img(eyes[i]);

            // Split eye image into 3 channels. 颜色分离
            vector<Mat>bgr(3);
            split(eye, bgr);

            // Simple red eye detector 红眼检测器,获得结果掩模
            Mat mask = (bgr[2] > 150) & (bgr[2] > (bgr[1] + bgr[0]));

            // Clean mask 清理掩模
            //填充孔洞
            fillHoles(mask);
            //扩充孔洞
            dilate(mask, mask, Mat(), Point(-1, -1), 3, 1, 1);

            // Calculate the mean channel by averaging the green and blue channels
            //计算b通道和g通道的均值
            Mat mean = (bgr[0] + bgr[1]) / 2;
            //用该均值图像覆盖原图掩模部分图像
            mean.copyTo(bgr[2], mask);
            mean.copyTo(bgr[0], mask);
            mean.copyTo(bgr[1], mask);

            // Merge channels
            Mat eyeOut;
            //图像合并
            cv::merge(bgr, eyeOut);

            // Copy the fixed eye to the output image.
            // 眼部图像替换
            eyeOut.copyTo(imgOut(eyes[i]));
        }

        // Display Result
        //imshow("Red Eyes", img);
        //imshow("Red Eyes Removed", imgOut);
        //waitKey(0);
        pixmapR=imgConversion.cvMatToQPixmap(imgOut);
        waitKey(0);
        sceneR.clear();
        sceneR.addPixmap(pixmapR);
        ui->saveButton->setEnabled(true);
    }
        return ;

}

额外函数:

void fillHoles(Mat &mask)
{
    Mat maskFloodfill = mask.clone();
    //漫水填充
    floodFill(maskFloodfill, cv::Point(0, 0), Scalar(255));
    Mat mask2;
    //反色
    bitwise_not(maskFloodfill, mask2);
    //或运算
    mask = (mask2 | mask);
}

红眼处理过程遇到的问题:

在这里插入图片描述
解决办法:
把xml文件和输入图片改为了绝对路径,成功解决问题。

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