zoukankan      html  css  js  c++  java
  • 项目实战:Qt+OpenCV图像处理与识别算法平台

     

    需求

      做算法过程中,需要一个平台来实时查看效果,记录处理过程,可以一键查看效果;
      OpenCV的各种算法在Qt效果调试;
      持续升级版本,敬请期待…

     

    原理

      基于Qt的OpenCV开发,依托Qt作为界面,OpenCV进行图像处理。

     

    涉及技术博文

     

    Demo:Qt+OpenCV算法平台 v1.4.0

    下载地址

      CSDN:https://download.csdn.net/download/qq21497936/12570673
      QQ群:1047134658(点击“文件”搜索“qtOpenCVTools”,群内与博文同步更新)

    腐蚀

      在这里插入图片描述

    膨胀

      在这里插入图片描述

    双边滤波

      在这里插入图片描述

    中值滤波

      在这里插入图片描述

    高斯滤波

      在这里插入图片描述

    均值滤波

      在这里插入图片描述

    方框滤波

      在这里插入图片描述

    对比度与亮度

      在这里插入图片描述

    图片打开与保存

      在这里插入图片描述

     

    核心代码

    common.h

    #ifndef COMMON_H
    #define COMMON_H
    
    #include <QImage>
    #include <QDebug>
    #include <QFileDialog>
    #include <QColorDialog>
    #include <QMessageBox>
    #include <QHash>
    // opencv
    #include "opencv/highgui.h"
    #include "opencv/cxcore.h"
    #include "opencv2/core/core.hpp"
    #include "opencv2/highgui/highgui.hpp"
    #include "opencv2/opencv.hpp"
    #include "opencv2/xphoto.hpp"
    // opencv_contrib
    #include <opencv2/xphoto.hpp>
    #include <opencv2/ximgproc.hpp>
    #include <opencv2/calib3d.hpp>
    
    cv::Mat image2Mat(QImage image);    // Qimage 转 cv::Mat
    QImage mat2Image(cv::Mat mat);      // cv::Mat 转 QImage
    
    #endif // COMMON_H
    

    common.cpp

    #include "common.h"
    
    cv::Mat image2Mat(QImage image)
    {
        cv::Mat mat;
        switch(image.format())
        {
        case QImage::Format_ARGB32:
        case QImage::Format_RGB32:
        case QImage::Format_ARGB32_Premultiplied:
            mat = cv::Mat(image.height(), image.width(), CV_8UC4, (void*)image.constBits(), image.bytesPerLine());
            cv::cvtColor(mat, mat, CV_BGRA2BGR);
            break;
        case QImage::Format_RGB888:
            mat = cv::Mat(image.height(), image.width(), CV_8UC3, (void*)image.constBits(), image.bytesPerLine());
            cv::cvtColor(mat, mat, CV_BGR2RGB);
            break;
        case QImage::Format_Indexed8:
            mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void*)image.constBits(), image.bytesPerLine());
            break;
        }
        return mat;
    }
    
    QImage mat2Image(cv::Mat mat)
    {
        if(mat.type() == CV_8UC1)
        {
            QImage image(mat.cols, mat.rows, QImage::Format_Indexed8);
            // Set the color table (used to translate colour indexes to qRgb values)
            image.setColorCount(256);
            for(int i = 0; i < 256; i++)
            {
                image.setColor(i, qRgb(i, i, i));
            }
            // Copy input Mat
            uchar *pSrc = mat.data;
            for(int row = 0; row < mat.rows; row ++)
            {
                uchar *pDest = image.scanLine(row);
                memcpy(pDest, pSrc, mat.cols);
                pSrc += mat.step;
            }
            return image;
        }
        else if(mat.type() == CV_8UC3)
        {
            const uchar *pSrc = (const uchar*)mat.data;
            QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_RGB888);
            return image.rgbSwapped();
        }
        else if(mat.type() == CV_8UC4)
        {
            const uchar *pSrc = (const uchar*)mat.data;
            QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_ARGB32);
            return image.copy();
        }
        else
        {
            return QImage();
        }
    }
    

    DemoContrastAndBrightnessWidget.h

    #ifndef DEMOCONTRASTANDBRIGHTNESSWIDGET_H
    #define DEMOCONTRASTANDBRIGHTNESSWIDGET_H
    
    #include <QWidget>
    #include "common.h"
    
    namespace Ui {
    class DemoContrastAndBrightnessWidget;
    }
    
    class DemoContrastAndBrightnessWidget : public QWidget
    {
        Q_OBJECT
    
    public:
        explicit DemoContrastAndBrightnessWidget(QWidget *parent = 0);
        ~DemoContrastAndBrightnessWidget();
    
    public:
        void setFilePath(QString filePath);
    
    protected:
        void updateInfo();
        void updateImage();
    
    private slots:
        void on_pushButton_openFile_clicked();
        void on_horizontalSlider_beta_sliderMoved(int position);
        void on_horizontalSlider_alpha_sliderMoved(int position);
        void on_pushButton_broswer_clicked();
        void on_spinBox_beta_valueChanged(int arg1);
        void on_doubleSpinBox_alpha_valueChanged(double arg1);
        void on_pushButton_showFile_clicked();
        void on_pushButton_backgroundColor_clicked();
    
    private:
        Ui::DemoContrastAndBrightnessWidget *ui;
    
    private:
        QString _filePath;
    
        cv::Mat _srcMat;
        QImage _srcImage;
        cv::Mat _dstMat;
        QImage _dstImage;
    };
    #endif // DEMOCONTRASTANDBRIGHTNESSWIDGET_H
    

    DemoContrastAndBrightnessWidget.cpp

    #include "DemoContrastAndBrightnessWidget.h"
    #include "ui_DemoContrastAndBrightnessWidget.h"
    
    DemoContrastAndBrightnessWidget::DemoContrastAndBrightnessWidget(QWidget *parent) :
        QWidget(parent),
        ui(new Ui::DemoContrastAndBrightnessWidget)
    {
        ui->setupUi(this);
    }
    
    DemoContrastAndBrightnessWidget::~DemoContrastAndBrightnessWidget()
    {
        delete ui;
    }
    
    void DemoContrastAndBrightnessWidget::setFilePath(QString filePath)
    {
        _filePath = filePath;
        ui->lineEdit_filePath->setText(_filePath);
    }
    
    void DemoContrastAndBrightnessWidget::updateInfo()
    {
        if(_srcMat.data == 0)
        {
            return;
        }
        // mat行列与图片高度是对角线反向的
        ui->label_size->setText(QString("%1 x %2").arg(_srcMat.rows).arg(_srcMat.cols));
        ui->label_channels->setText(QString("%1").arg(_srcMat.channels()));
        ui->label_depth->setText(QString("%1").arg(_srcMat.depth()));
        ui->label_type->setText(QString("%1").arg(_srcMat.type()));
    }
    
    void DemoContrastAndBrightnessWidget::updateImage()
    {
        if(_srcImage.isNull())
        {
            return;
        }
    
        cv::Mat srcMat = image2Mat(_srcImage);
    
        // 增强对比度
        float r;
        float g;
        float b;
        _dstMat = cv::Mat::zeros(srcMat.size(), srcMat.type());
        int alpha = ui->horizontalSlider_alpha->value();    // 小于1,则降低对比度
        int beta = ui->horizontalSlider_beta->value();     // 负数,则降低亮度
        for(int row = 0; row < srcMat.rows; row++)
        {
            for(int col = 0; col < srcMat.cols; col++)
            {
                b = srcMat.at<cv::Vec3b>(row, col)[0];
                g = srcMat.at<cv::Vec3b>(row, col)[1];
                r = srcMat.at<cv::Vec3b>(row, col)[2];
                // 对比度、亮度计算公式 cv::saturate_cast<uchar>(value):防止溢出
                _dstMat.at<cv::Vec3b>(row, col)[0] = cv::saturate_cast<uchar>(b * alpha / 100.0f + beta);
                _dstMat.at<cv::Vec3b>(row, col)[1] = cv::saturate_cast<uchar>(g * alpha / 100.0f + beta);
                _dstMat.at<cv::Vec3b>(row, col)[2] = cv::saturate_cast<uchar>(r * alpha / 100.0f + beta);
            }
        }
        _dstImage = mat2Image(_dstMat);
        ui->widget_image->setImage(_dstImage);
    }
    
    void DemoContrastAndBrightnessWidget::on_pushButton_openFile_clicked()
    {
        if(!_srcImage.load(_filePath))
        {
            qDebug() << __FILE__ << __LINE__ << "Failed to load image:" << _filePath;
            return;
        }
        qDebug() << __FILE__<< __LINE__ << (int)_srcImage.format();
        _srcMat = image2Mat(_srcImage);
        updateInfo();
        updateImage();
    }
    
    void DemoContrastAndBrightnessWidget::on_horizontalSlider_beta_sliderMoved(int position)
    {
        ui->spinBox_beta->setValue(position);
        updateImage();
    }
    
    void DemoContrastAndBrightnessWidget::on_horizontalSlider_alpha_sliderMoved(int position)
    {
        ui->doubleSpinBox_alpha->setValue(position / 100.0f);
        updateImage();
    }
    
    void DemoContrastAndBrightnessWidget::on_pushButton_broswer_clicked()
    {
        QString dir = ui->lineEdit_filePath->text();
        dir = dir.mid(0, dir.lastIndexOf("/"));
        QString filePath = QFileDialog::getOpenFileName(0, "打开图片", dir, "PNG;JPEG;BMP(*.png;*.jpg;*.bmp);;JPEG(*.jpg);;PNG(*.png);;BMP(*.bmp)");
        if(filePath.isEmpty())
        {
            return;
        }
        _filePath = filePath;
        ui->lineEdit_filePath->setText(_filePath);
    
    }
    
    void DemoContrastAndBrightnessWidget::on_spinBox_beta_valueChanged(int arg1)
    {
        ui->horizontalSlider_beta->setValue(arg1);
        updateImage();
    }
    
    void DemoContrastAndBrightnessWidget::on_doubleSpinBox_alpha_valueChanged(double arg1)
    {
        ui->horizontalSlider_alpha->setValue(arg1 * 100);
        updateImage();
    }
    
    void DemoContrastAndBrightnessWidget::on_pushButton_showFile_clicked()
    {
        if(_dstMat.data == 0)
        {
            QMessageBox::information(this, "提示", "使用opencv显示图片失败");
            return;
        }
        cv::imshow("showFile", _dstMat);
    }
    
    void DemoContrastAndBrightnessWidget::on_pushButton_backgroundColor_clicked()
    {
        QColor backgroundColor = ui->widget_image->getBackgroundColor();
        backgroundColor = QColorDialog::getColor(backgroundColor, this, "底色");
        if(!backgroundColor.isValid())
        {
           return;
        }
        QColor color(backgroundColor.red(), backgroundColor.green(), backgroundColor.blue());
        ui->widget_image->setBackgroundColor(color);
    }
    
     
  • 相关阅读:
    【MYSQL】某些有用的sql【持续更新中】
    【LDAP】什么时候需要使用LDAP?
    【LDAP】 objectClass 分类
    MySQL的锁机制
    spring的事务传播级别及场景
    @NotEmpty,@NotNull和@NotBlank的区别
    mysql的字段为bit时,插入数据报Data too long
    activeMQ启动报--找不到或无法加载主类
    【ListViewJson】【com.demo.app】【AppException】源码分析及其在工程中作用
    【ListViewJson】【com.demo.app】【AppConfig】源码分析及其在工程中作用
  • 原文地址:https://www.cnblogs.com/qq21497936/p/13226911.html
Copyright © 2011-2022 走看看