[OpenCV学习笔记]Qt+OpenCV实现图像灰度反转、对数变换和伽马变换

这篇具有很好参考价值的文章主要介绍了[OpenCV学习笔记]Qt+OpenCV实现图像灰度反转、对数变换和伽马变换。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、介绍

1.1 灰度反转

灰度反转是一种线性变换,是将某个范围的灰度值映射到另一个范围内,一般是通过灰度的对调,突出想要查看的灰度区间。

S = L − 1 − r ( r ⊂ [ 0 , L − 1 ] ) S = L -1-r (r \subset [0,L-1]) S=L1r(r[0,L1])
比如在以下胸片图像中提取白色絮状形状,在黑色背景下看的不太明显,就可以使用灰度反转增强图像的可视化效果。
用qt实现图像灰度转变,Halcon/OpenCV学习,Qt实例学习,opencv,qt

output_img = input_img.clone();
for(int i = 0; i < input_img.rows; i++)
{
    for(int j = 0; j < input_img.cols; j++)
    {
        output_img.at<uchar>(i, j) = 255 - input_img.at<uchar>(i, j)
    }
}

1.2 图像对数变换

对数变换可以将图像中低灰度值的部分进行提升,显示出低灰度部分的特征,对高灰度值部分进行抑制,减少高灰度值部分的细节,从而实现增项图像俺不细节,优化图像的对比度。
S = c log ⁡ ( 1 + r ) S=c\log(1+r) S=clog(1+r)
其原理就是,对数曲线在像素值低的区域斜率大,在像素值高的地方斜率小。
用qt实现图像灰度转变,Halcon/OpenCV学习,Qt实例学习,opencv,qt
对数变换后图像的灰度值可能会超出0~255的区间,所以在对数变换后要进行归一化处理,将图像灰度值调节回0-255的区间。
用qt实现图像灰度转变,Halcon/OpenCV学习,Qt实例学习,opencv,qt

	Mat LogarithmImg = grayImg.clone();
    for(int i=0;i<grayImg.rows;i++)
    {
        for(int j=0;j<grayImg.cols;j++)
        {
            LogarithmImg.at<uchar>(i,j) = 6*log((double)grayImg.at<uchar>(i,j) + 1);
        }
    }
    normalize(LogarithmImg, LogarithmImg, 0, 255,NORM_MINMAX);
    convertScaleAbs(LogarithmImg,LogarithmImg);

1.3 图像伽马变换

图像的伽马变换其实就是通过非线性变换将图像中较暗区域的灰度值进行增强,对较亮区域的灰度值进行抑制,从而获得图像比较好的细节特征。
s = c r γ ( r ∈ [ 0 , 1 ] ) s=cr^\gamma (r\in[0, 1]) s=crγ(r[0,1])
r为灰度的输入值,c为灰度缩放系数,伽马因子控制整个变换的缩放程度。
用qt实现图像灰度转变,Halcon/OpenCV学习,Qt实例学习,opencv,qt

    Mat gammaImg = grayImg.clone();
    for(int i=0;i<grayImg.rows;i++)
    {
        for(int j=0;j<grayImg.cols;j++)
        {
            gammaImg.at<uchar>(i,j) = 6*pow((double)grayImg.at<uchar>(i,j), 0.5);
        }
    }
    normalize(gammaImg, gammaImg, 0, 255,NORM_MINMAX);
    convertScaleAbs(gammaImg,gammaImg);

2、效果图

使用lena图进行灰度反转、对数变换、伽马变化测试,在Qt上实现加载和变换。
用qt实现图像灰度转变,Halcon/OpenCV学习,Qt实例学习,opencv,qt

3、代码实现

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include "opencv2/opencv.hpp"
#include <QResizeEvent>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

using namespace cv;
class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:
    void on_btn_loadPic_clicked();

    void on_btn_InversionTrans_clicked();

    void on_btn_logarithmTrans_clicked();

    void on_btn_gammaTrans_clicked();

    void on_btn_resetPic_clicked();

private:
    Ui::Widget *ui;
    // 灰度图像
    Mat grayImg;
    // Mat图像类型转换为QImage
    QImage cvMat2QImage(const cv::Mat &mat);
};
#endif // WIDGET_H

widget.cpp

#pragma execution_character_set("utf-8")
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    this->setWindowTitle("OpenCV图像变换");
}

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


void Widget::on_btn_loadPic_clicked()
{
    Mat Img = imread("lena.png");
    cvtColor(Img, grayImg, COLOR_BGR2GRAY);

    QImage qImg_Gray = cvMat2QImage(grayImg);
    ui->lbl_grayPic->setPixmap(QPixmap::fromImage(qImg_Gray.scaled(ui->lbl_grayPic->size())));
}


void Widget::on_btn_InversionTrans_clicked()
{
    Mat InversionImg = grayImg.clone();
    for(int i=0;i<grayImg.rows;i++)
    {
        for(int j=0;j<grayImg.cols;j++)
        {
            InversionImg.at<uchar>(i,j) = 255 - grayImg.at<uchar>(i,j);
        }
    }
    QImage qImg_Inversion = cvMat2QImage(InversionImg);
    ui->lbl_InversionPic->setPixmap(QPixmap::fromImage(qImg_Inversion.scaled(ui->lbl_InversionPic->size())));
}


void Widget::on_btn_logarithmTrans_clicked()
{
    Mat LogarithmImg = grayImg.clone();
    for(int i=0;i<grayImg.rows;i++)
    {
        for(int j=0;j<grayImg.cols;j++)
        {
            LogarithmImg.at<uchar>(i,j) = 6*log((double)grayImg.at<uchar>(i,j) + 1);
        }
    }
    normalize(LogarithmImg, LogarithmImg, 0, 255,NORM_MINMAX);
    convertScaleAbs(LogarithmImg,LogarithmImg);
    QImage qImg_Logarithm = cvMat2QImage(LogarithmImg);
    ui->lbl_LogPic->setPixmap(QPixmap::fromImage(qImg_Logarithm.scaled(ui->lbl_LogPic->size())));
}


void Widget::on_btn_gammaTrans_clicked()
{
    Mat gammaImg = grayImg.clone();
    for(int i=0;i<grayImg.rows;i++)
    {
        for(int j=0;j<grayImg.cols;j++)
        {
            gammaImg.at<uchar>(i,j) = 6*pow((double)grayImg.at<uchar>(i,j), 0.5);
        }
    }
    normalize(gammaImg, gammaImg, 0, 255,NORM_MINMAX);
    convertScaleAbs(gammaImg,gammaImg);
    QImage qImg_Gamma = cvMat2QImage(gammaImg);
    ui->lbl_GammaPic->setPixmap(QPixmap::fromImage(qImg_Gamma.scaled(ui->lbl_GammaPic->size())));
}


void Widget::on_btn_resetPic_clicked()
{
    ui->lbl_grayPic->clear();
    ui->lbl_InversionPic->clear();
    ui->lbl_LogPic->clear();
    ui->lbl_GammaPic->clear();
}

QImage Widget::cvMat2QImage(const cv::Mat &mat)
{
    switch ( mat.type() )
    {
    // 8-bit  4 channel
    case CV_8UC4:
    {
        QImage image( (const uchar*)mat.data, mat.cols, mat.rows, static_cast<int>(mat.step), QImage::Format_RGB32 );
        return image;
    }

        // 8-bit  3 channel
    case CV_8UC3:
    {
        QImage image( (const uchar*)mat.data, mat.cols, mat.rows, static_cast<int>(mat.step), QImage::Format_RGB888 );
        return image.rgbSwapped();
    }

        // 8-bit  1 channel
    case CV_8UC1:
    {
        static QVector<QRgb>  sColorTable;
        // only create our color table once
        if ( sColorTable.isEmpty() )
        {
            sColorTable.resize( 256 );
            for ( int i = 0; i < 256; ++i )
            {
                sColorTable[i] = qRgb( i, i, i );
            }
        }
        QImage image( (const uchar*)mat.data, mat.cols, mat.rows, static_cast<int>(mat.step), QImage::Format_Indexed8 );
        image.setColorTable( sColorTable );
        return image;
    }
    default:
        qDebug("Image format is not supported: depth=%d and %d channels\n", mat.depth(), mat.channels());
        qWarning() << "cvMatToQImage - cv::Mat image type not handled in switch:" << mat.type();
        break;
    }
    return QImage();
}

4、源码展示

本小例程的代码放到我的开源gitte项目里,欢迎一起学习交流,也希望能收获你的小星星。
项目源码GrayTrans文章来源地址https://www.toymoban.com/news/detail-850359.html

到了这里,关于[OpenCV学习笔记]Qt+OpenCV实现图像灰度反转、对数变换和伽马变换的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • python学习-->opencv图像基本操作学习之灰度图转换

    好久没更新,趁今天要做核酸回不了宿舍,把今天的学习的opencv知识先记录一下! 运行环境是:pycharm 话不多说,献上代码再说: 首先我们先读取我们的图片进来! 跟着我们先尝试一下在打开我们的图片看看! 下面是实现的代码! 运行之后我的图片是这样的 我们可以看看图

    2024年02月08日
    浏览(60)
  • 学习笔记:Opencv实现图像特征提取算法SIFT

    2023.8.19 为了在暑假内实现深度学习的进阶学习,特意学习一下传统算法,分享学习心得,记录学习日常 SIFT的百科: SIFT = Scale Invariant Feature Transform, 尺度不变特征转换 全网最详细SIFT算法原理实现_ssift算法_Tc.小浩的博客-CSDN博客 在环境配置中要配置opencv: pip install opencv-c

    2024年02月12日
    浏览(48)
  • 学习笔记:Opencv实现拉普拉斯图像锐化算法

    2023.8.19 为了在暑假内实现深度学习的进阶学习,Copy大神的代码,记录学习日常 图像锐化的百科: 图像锐化算法-sharpen_lemonHe_的博客-CSDN博客 在环境配置中要配置opencv: pip install opencv-contrib-python Code and lena.png:注意你是否在data下由lena.png   附上lena.png  效果所示(解读):

    2024年02月12日
    浏览(49)
  • opencv 图像基础处理_灰度图像

    二值图像表示起来简单方便,但是因为其仅有黑白两种颜色,所表示的图像不够细腻。如果想要表现更多的细节,就需要使用更多的颜色。例如,图 2-3 中的 lena 图像是一幅灰度图像, 它采用了更多的数值以体现不同的颜色,因此该图像的细节信息更丰富。 通常,计算机会将

    2024年02月15日
    浏览(57)
  • opencv读取灰度图像

    本文档创建于2023年3月10日 本文记录了C++版opencv读取灰度图像的不同方式及区别 作者:RobotFreak C++版的 opencv 读取灰度图像可以有不同的方法,这里列出几种方法,并简述它们的区别。 这里用到的两张图片为lena.jpg(彩色)和lena.bmp(灰度) 图像本身就是灰度图像,直接使用

    2024年02月06日
    浏览(66)
  • opencv图像灰度化

      图像灰度化就是将图像的亮度值(R,G,B)按照一定的方式映射到0-255之间的灰度值上,为了使图像看起来不那么单调,需要将图像的亮度值进行变换。下面简单介绍下 opencv中的灰度化函数: 1、先将图像的像素值转换为R,G,B三个分量,其中R分量用于图像灰度变换,G分量用于

    2024年02月09日
    浏览(43)
  • OpenCV图像处理-灰度处理

    灰度的线性变换将图像中的所有像素点的值按 线性变换函数 进行变换。 在曝光不足或过度的情况下,图像的灰度值会局限在一个很小的范围内,这时在显示器上看到的将是一个模糊不清、似乎没有层次的图像。 针对这一情况,使用一个线性单值函数对图像内的每一个像素做

    2024年02月08日
    浏览(106)
  • Opencv 图像处理:图像基础操作与灰度转化

    本文已收录于Opencv系列专栏: 深入浅出OpenCV ,专栏旨在详解Python版本的Opencv,为计算机视觉的开发与研究打下坚实基础。免费订阅,持续更新。 1.图像格式 图像压缩比: 通过编码器压缩后的图象数字大小和原图象数字大小的压缩比。 BMP 格式 Windows系统下的 标准位图格式 ,

    2024年02月04日
    浏览(51)
  • QT+opencv【opencv学习篇】OpenCV 读取、显示和保存图像

    目录   一、OpenCV 读取图像 OpenCV 读取函数 参数: 二、OpenCV 显示图像 imshow函数 imshow函数功能 imshow函数原型 三、OpenCV 保存图像 四、结果和代码   OpenCV 允许我们对图像执行多种操作,但要做到这一点,需要读取一个图像文件作为输入,然后我们可以对其执行各种操作。Ope

    2024年02月16日
    浏览(48)
  • 基于opencv的c++图像处理(灰度变换)

    基于opencv的c++接口,实现常用的图像灰度变换方法,包括了线性变换、图像反转、对数变换和伽马变换。 函数 cv::normalize 标准化缩放和移动输入数组元素 当 normType=NORM_MINMAX 时(仅适用于密集数组)。可选掩码指定要规范化的子数组。这意味着在子数组上计算范数或 min-n-ma

    2024年02月04日
    浏览(72)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包