项目实战:Qt+OpenCV图像处理与识别算法平台(持续更新,当前v1.7.0)

简介: 项目实战:Qt+OpenCV图像处理与识别算法平台(持续更新,当前v1.7.0)

需求

  做算法过程中,需要一个平台来实时查看效果,记录处理过程,可以一键查看效果;

  OpenCV的各种算法在Qt效果调试;

  持续升级版本,敬请期待…(请点击收藏)


原理

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


版本说明

  


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

下载地址

  CSDN:https://download.csdn.net/download/qq21497936/12882003

  QQ群:1047134658(点击“文件”搜索“qtOpenCVTools”,群内与博文同步更新)

版本信息

  • v1.7.0 更改子窗口的类型设计模式,加载退出之前所在的Demo例程页面,兼容单通道图像,增加霍夫线变换、开运算、闭运算、形态学梯度、顶帽(礼帽)、黑帽、漫水填充(点击图片选点填充)

演示

  

  


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

下载地址

  CSDN:https://download.csdn.net/download/qq21497936/12587028

  QQ群:1047134658(点击“文件”搜索“qtOpenCVTools”,群内与博文同步更新)

版本信息

  • v1.5.0 增加对算法的结果进行输出、展示和保存,增加阈值化、自适应阈值化
  • v1.6.0 更改子窗口的设计模式,增加OTSU阈值化、双阈值化(中间区域、非中间区域)、半阈值化

演示

  

  


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

下载地址

  CSDN:https://download.csdn.net/download/qq21497936/12570673

  QQ群:1047134658(点击“文件”搜索“qtOpenCVTools”,群内与博文同步更新)

版本信息

  • v1.0.0 基础框架
  • v1.1.0 增加openCV图片读取与保存
  • v1.2.0 增加对比度与亮度、方框滤波、均值滤波和高斯滤波
  • v1.3.0 增加对bmp图片的支持,增加中值滤

腐蚀

  

膨胀

  

双边滤波

  

中值滤波

  

高斯滤波

  

均值滤波

  

方框滤波

  

对比度与亮度

  

图片打开与保存

  


涉及技术博文

  《OpenCV开发笔记(三十四):红胖子带你傻瓜式编译Qt+openCV3.4.1+opencv_contrib(全网最浅显易懂)

  《OpenCV开发笔记(四):OpenCV图片和视频数据的读取与存储

  《OpenCV开发笔记(十三):OpenCV图像对比度、亮度的调整

  《OpenCV开发笔记(十四):算法基础之线性滤波-方框滤波

  《OpenCV开发笔记(十五):算法基础之线性滤波-均值滤波

  《OpenCV开发笔记(十六):算法基础之线性滤波-高斯滤波

  《OpenCV开发笔记(十八):算法基础之非线性滤波-中值滤波

  《OpenCV开发笔记(十九):算法基础之非线性滤波-双边滤波

  《OpenCV开发笔记(二十一):算法基础之形态学滤波-膨胀

  《OpenCV开发笔记(二十二):算法基础之形态学滤波-腐蚀

  《OpenCV开发笔记(二十八):带你学习图像识别之阈值化

  《OpenCV开发笔记(二十九):带你学习图像识别之自适应阈值

  《OpenCV开发笔记(三十):带你学习图像识别之经典OTSU算法阈值化

  《OpenCV开发笔记(三十一):红胖子8分钟带你深入了解双阈值化(图文并貌+浅显易懂+程序源码)

  《OpenCV开发笔记(三十二):红胖子8分钟带你深入了解半阈值化(图文并貌+浅显易懂+程序源码)


核心代码

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);
}



相关文章
|
12月前
|
算法 计算机视觉
基于qt的opencv实时图像处理框架FastCvLearn实战
本文介绍了一个基于Qt的OpenCV实时图像处理框架FastCvLearn,通过手撕代码的方式详细讲解了如何实现实时人脸马赛克等功能,并提供了结果展示和基础知识回顾。
513 7
基于qt的opencv实时图像处理框架FastCvLearn实战
|
7月前
|
存储 算法 安全
.NET 平台 SM2 国密算法 License 证书生成深度解析
授权证书文件的后缀通常取决于其编码格式和具体用途。本文档通过一个示例程序展示了如何在 .NET 平台上使用国密 SM2 算法生成和验证许可证(License)文件。该示例不仅详细演示了 SM2 国密算法的实际应用场景,还提供了关于如何高效处理大规模许可证文件生成任务的技术参考。通过对不同并发策略的性能测试,开发者可以更好地理解如何优化许可证生成流程,以满足高并发和大数据量的需求。 希望这段描述更清晰地传达了程序的功能和技术亮点。
722 14
.NET 平台 SM2 国密算法 License 证书生成深度解析
|
5月前
|
机器学习/深度学习 存储 Kubernetes
【重磅发布】AllData数据中台核心功能:机器学习算法平台
杭州奥零数据科技有限公司成立于2023年,专注于数据中台业务,维护开源项目AllData并提供商业版解决方案。AllData提供数据集成、存储、开发、治理及BI展示等一站式服务,支持AI大模型应用,助力企业高效利用数据价值。
|
7月前
|
算法 安全 大数据
【算法合规新时代】企业如何把握“清朗·网络平台算法典型问题治理”专项行动?
在数字化时代,算法推动社会发展,但也带来了信息茧房、大数据杀熟等问题。中央网信办发布《关于开展“清朗·网络平台算法典型问题治理”专项行动的通知》,针对六大算法问题进行整治,明确企业需落实算法安全主体责任,建立健全审核与管理制度,并对算法进行全面审查和备案。企业应积极自查自纠,确保算法合规透明,防范风险,迎接新机遇。
|
8月前
|
存储 算法 安全
基于哈希表的文件共享平台 C++ 算法实现与分析
在数字化时代,文件共享平台不可或缺。本文探讨哈希表在文件共享中的应用,包括原理、优势及C++实现。哈希表通过键值对快速访问文件元数据(如文件名、大小、位置等),查找时间复杂度为O(1),显著提升查找速度和用户体验。代码示例展示了文件上传和搜索功能,实际应用中需解决哈希冲突、动态扩容和线程安全等问题,以优化性能。
|
9月前
|
机器学习/深度学习 前端开发 算法
婚恋交友系统平台 相亲交友平台系统 婚恋交友系统APP 婚恋系统源码 婚恋交友平台开发流程 婚恋交友系统架构设计 婚恋交友系统前端/后端开发 婚恋交友系统匹配推荐算法优化
婚恋交友系统平台通过线上互动帮助单身男女找到合适伴侣,提供用户注册、个人资料填写、匹配推荐、实时聊天、社区互动等功能。开发流程包括需求分析、技术选型、系统架构设计、功能实现、测试优化和上线运维。匹配推荐算法优化是核心,通过用户行为数据分析和机器学习提高匹配准确性。
651 5
|
12月前
|
机器学习/深度学习 人工智能 算法
【新闻文本分类识别系统】Python+卷积神经网络算法+人工智能+深度学习+计算机毕设项目+Django网页界面平台
文本分类识别系统。本系统使用Python作为主要开发语言,首先收集了10种中文文本数据集("体育类", "财经类", "房产类", "家居类", "教育类", "科技类", "时尚类", "时政类", "游戏类", "娱乐类"),然后基于TensorFlow搭建CNN卷积神经网络算法模型。通过对数据集进行多轮迭代训练,最后得到一个识别精度较高的模型,并保存为本地的h5格式。然后使用Django开发Web网页端操作界面,实现用户上传一段文本识别其所属的类别。
356 1
【新闻文本分类识别系统】Python+卷积神经网络算法+人工智能+深度学习+计算机毕设项目+Django网页界面平台
|
11月前
|
机器学习/深度学习 算法 计算机视觉
【Python篇】Python + OpenCV 全面实战:解锁图像处理与视觉智能的核心技能
【Python篇】Python + OpenCV 全面实战:解锁图像处理与视觉智能的核心技能
324 7
|
12月前
|
机器学习/深度学习 人工智能 算法
【果蔬识别系统】Python+卷积神经网络算法+人工智能+深度学习+计算机毕设项目+Django网页界面平台
【果蔬识别系统】Python+卷积神经网络算法+人工智能+深度学习+计算机毕设项目+Django网页界面平台。果蔬识别系统,本系统使用Python作为主要开发语言,通过收集了12种常见的水果和蔬菜('土豆', '圣女果', '大白菜', '大葱', '梨', '胡萝卜', '芒果', '苹果', '西红柿', '韭菜', '香蕉', '黄瓜'),然后基于TensorFlow库搭建CNN卷积神经网络算法模型,然后对数据集进行训练,最后得到一个识别精度较高的算法模型,然后将其保存为h5格式的本地文件方便后期调用。再使用Django框架搭建Web网页平台操作界面,实现用户上传一张果蔬图片识别其名称。
302 0
【果蔬识别系统】Python+卷积神经网络算法+人工智能+深度学习+计算机毕设项目+Django网页界面平台
WK
|
计算机视觉 Python
如何使用OpenCV进行基本图像处理
使用OpenCV进行基本图像处理包括安装OpenCV,读取与显示图像,转换图像颜色空间(如从BGR到RGB),调整图像大小,裁剪特定区域,旋转图像,以及应用图像滤镜如高斯模糊等效果。这些基础操作是进行更复杂图像处理任务的前提。OpenCV还支持特征检测、图像分割及对象识别等高级功能。
WK
150 4

热门文章

最新文章

推荐镜像

更多
  • qt