visual Studio MFC 平台实现图像增强中的线性变换(负变换)和非线性变换(对数与幂律)

MFC 实现数字图像处理中的图像增强操作

本文使用visual Studio MFC 平台实现图像增强中典型的三种图像增强的方法中的两大类,包括线性变换–>负变换,非线性变换–>对数变换和幂律变换;其中第三大类分段式变换可以参考MFC实现图像增强–分段式变换(灰度级切片,对比度拉伸,Bit-plane slicing)
关于基础工程的创建请参考
01-Visual Studio 使用MFC 单文档工程绘制单一颜色直线和绘制渐变颜色的直线

02-visual Studio MFC 绘制单一颜色三角形、渐变颜色边框三角形、渐变填充三角形、边框渐变的正方形与填充渐变的正方形实例
03-visual Studio MFC 平台实现对灰度图添加椒盐噪声,并进行均值滤波与中值滤波

文章目录

  • MFC 实现数字图像处理中的图像增强操作
    • 一、线性(负变换和单位变换)
      • 线性变换的原理
      • 线性变换-负变换实现
      • 线性变换--负变换效果图
    • 对数(对数和对数逆变换)
      • 对数变换的原理
      • 对数变换原理
      • 对数逆变换原理
      • 应用场景
      • 对数变换的实现
      • 实现效果图
    • 幂律(n次幂和n次根变换)
      • 幂律(n次幂和n次根变换)的原理
      • 幂律(n次幂和n次根变换)的代码实现
      • 实现效果图

一、线性(负变换和单位变换)

线性变换的原理

图像增强中的线性变换是一种基本的像素值变换方法,通常涉及负变换和单位变换。

  1. 负变换: 负变换是通过反转图像的灰度级别,使得原来的较亮的像素变暗,较暗的像素变亮。这可以通过下面的公式表示:

    s = L − r s = L - r s=Lr

    其中,$ s $ 是输出像素的灰度级别,$ L $ 是灰度级别的最大值,$ r $ 是输入像素的灰度级别。这样的变换能够产生图像的底片效果,强调图像中原本较亮的区域。

  2. 单位变换: 单位变换是一种线性变换,它保持图像的原始灰度级别不变。单位变换的公式如下:

    s = r s = r s=r

    这种变换并不改变图像的外观,但在图像增强中,它可能作为其他变换的基础或作为恢复操作的一部分。

这两种变换是线性的,因为它们都可以表示为输入像素值 $ r $ 与某个常数或者 $ L $的线性关系。线性变换是图像处理中一类简单而有效的操作,但对于一些更高级的增强技术,可能需要非线性的操作。

线性变换-负变换实现

void CMFCApplication1View::OnNegativetransform()
{// TODO: 在此添加命令处理程序代码if (gray_data != nullptr) {// 创建临时数组用于对比度拉伸处理unsigned char* neg_transformed_data = new unsigned char[bmpWidth * bmpHeight];// 负变换的处理代码for (int i = 0; i < bmpWidth * bmpHeight; ++i) {neg_transformed_data[i] = 255 - gray_data[i];}// 获取绘图设备CClientDC dc(this);CDC* pDC = &dc;// 绘制负变换后的灰度图m_pBmp->drawGrayBmp(pDC, neg_transformed_data, bmpWidth, bmpHeight, offset_left + 700, offset_top);// 在图片下方添加文字GdiplusStartupInput gdiplusStartupInput;ULONG_PTR gdiplusToken;GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, nullptr);{Graphics graphics(pDC->m_hDC);Gdiplus::Font font(L"Arial", 12);SolidBrush brush(Color(255, 128, 0, 128));  // 文字颜色为紫色// 文字的位置PointF point(offset_left +700, offset_top + bmpHeight + 10);// 绘制文字graphics.DrawString(L"负变换后的灰度图", -1, &font, point, &brush);}GdiplusShutdown(gdiplusToken);// 释放负变换后的数据的内存delete[] neg_transformed_data;}else {// 处理图像未加载的情况AfxMessageBox(_T("未加载图片"));}
}

线性变换–负变换效果图

在这里插入图片描述

对数(对数和对数逆变换)

对数变换的原理

图像增强中的对数变换是一种常用的变换方法,它可以调整图像的灰度级分布,增强图像的对比度。对数变换的原理如下:

对数变换原理

对数变换的公式为:

s = c ⋅ log ⁡ ( 1 + r ) s = c \cdot \log(1 + r) s=clog(1+r)

其中:

  • s 是输出像素值(变换后的像素值),
  • r 是输入像素值(原始像素值),
  • c 是常数,用于调整变换的幅度。

对数变换的特点是对较低灰度级的输入像素值进行拉伸,对较高灰度级的像素值进行压缩,从而增强了图像的对比度。

对数逆变换原理

对数逆变换是对数变换的反操作,可以将经过对数变换的图像恢复到原始状态。对数逆变换的公式为:

r = exp ⁡ ( s c ) − 1 r = \exp\left(\frac{s}{c}\right) - 1 r=exp(cs)1

其中:

  • r r r 是原始像素值,
  • s s s 是经过对数变换后的像素值,
  • c c c 是与对数变换中的 c c c 相同的常数。

对数逆变换的目的是使图像能够从经过对数变换的状态回到原始状态。

应用场景

对数变换常用于增强图像的低灰度级部分,特别是当图像的信息主要集中在较低灰度级时。例如,在医学图像处理中,对数变换常用于增强 X 射线图像的细节。

总体而言,对数变换适用于对比度较低的图像,能够提升图像的显示效果。

对数变换的实现

void CMFCApplication1View::OnLogtransform()
{// TODO: 在此添加命令处理程序代码if (gray_data != nullptr){// 创建临时数组用于对数变换处理unsigned char* log_transformed_data = new unsigned char[bmpWidth * bmpHeight];// 对数变换的处理代码const double c = 40.0;  // 可根据需要调整的常数for (int i = 0; i < bmpWidth * bmpHeight; ++i) {log_transformed_data[i] = static_cast<unsigned char>(c * log(1 + gray_data[i]));}// 获取绘图设备CClientDC dc(this);CDC* pDC = &dc;// 绘制对数变换后的灰度图m_pBmp->drawGrayBmp(pDC, log_transformed_data, bmpWidth, bmpHeight, offset_left , offset_top+ bmpHeight+50);// 在图片下方添加文字GdiplusStartupInput gdiplusStartupInput;ULONG_PTR gdiplusToken;GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, nullptr);{Graphics graphics(pDC->m_hDC);Gdiplus::Font font(L"Arial", 12);SolidBrush brush(Color(255, 128, 0, 128));  // 文字颜色为紫色// 文字的位置PointF point(offset_left , offset_top + 2*bmpHeight+50);// 绘制文字graphics.DrawString(L"对数变换后的灰度图", -1, &font, point, &brush);}GdiplusShutdown(gdiplusToken);// 释放对数变换后的数据的内存delete[] log_transformed_data;}else {// 处理图像未加载的情况AfxMessageBox(_T("未加载图片"));}
}

实现效果图

幂律(n次幂和n次根变换)

在这里插入图片描述

幂律(n次幂和n次根变换)的原理

幂律变换(Power Law Transformation)是一种图像增强的方法,通过对图像的像素值进行非线性映射来调整图像的对比度。该变换的一般形式如下:

g ( x , y ) = c ⋅ [ f ( x , y ) ] γ g(x, y) = c \cdot [f(x, y)]^{\gamma} g(x,y)=c[f(x,y)]γ

其中:

  • g ( x , y ) g(x, y) g(x,y) 是输出图像的像素值。
  • f ( x , y ) f(x, y) f(x,y) 是输入图像的像素值。
  • c c c 是常数,用于缩放输出的像素值范围。
  • γ \gamma γ是幂律指数,控制像素值的非线性映射。

通过调整 $ \gamma $的值,可以实现不同程度的图像增强。当 γ > 1 \gamma > 1 γ>1 时,会增强图像的高亮部分,降低暗部的对比度;而当 0 < γ < 1 0 < \gamma < 1 0<γ<1 时,会增强暗部的对比度,减小亮部的差异。

在实际应用中,一般会将 f ( x , y ) f(x, y) f(x,y) 归一化到 [0, 1] 的范围,应用变换后再将结果缩放到原图像的像素值范围。

幂律变换的应用场景包括调整图像的对比度、增强细节等。这种变换在图像处理和计算机视觉中经常用于图像增强的预处理阶段。

幂律(n次幂和n次根变换)的代码实现

//幂律(n次幂和n次根变换)
void CMFCApplication1View::OnPowerlawtransform()
{// TODO: 在此添加命令处理程序代码if (gray_data != nullptr) {// 创建临时数组用于幂律变换处理unsigned char* power_law_transformed_data = new unsigned char[bmpWidth * bmpHeight];double gamma = 2.0; // 幂律指数,可以根据需要调整// 幂律变换的处理代码for (int i = 0; i < bmpWidth * bmpHeight; ++i) {double normalized_pixel_value = static_cast<double>(gray_data[i]) / 255.0;double transformed_value = 255.0 * pow(normalized_pixel_value, gamma);power_law_transformed_data[i] = static_cast<unsigned char>(transformed_value);}// 获取绘图设备CClientDC dc(this);CDC* pDC = &dc;// 绘制幂律变换后的灰度图m_pBmp->drawGrayBmp(pDC, power_law_transformed_data, bmpWidth, bmpHeight, offset_left+250, offset_top + bmpHeight + 50);
}

实现效果图

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/193081.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android Termux 安装Kali Linux 或 kali Nethunter史诗级详细教程

Android Termux 安装Kali Linux 或 kali Nethunter史诗级详细教程 一、Termux配置1、下载安装2、配置存储和换源3、基本工具安装 二、Kali Linux安装1、下载安装脚本2、更换apt源3、图形化安装 三、Kali Nethunter安装1、下载安装脚本2、更换apt源3、图形化连接 四、报错汇总1、…

2023年5月电子学会青少年软件编程 Python编程等级考试一级真题解析(判断题)

2023年5月Python编程等级考试一级真题解析 判断题(共10题,每题2分,共20分) 26、在编写较长的Python程序时,所有代码都不需要缩进,Python会自动识别代码之间的关系 答案:错 考点分析:考查python代码书写格式规范,python编写较长的程序时,需要明确严格的缩进,不然有…

【ArcGIS Pro微课1000例】0044:深度学习--面部模糊(马赛克)

本文讲解ArcGIS Pro中通过深度学习工具实现人脸面部模糊,起到马赛克的作用。 文章目录 一、效果对比二、工具介绍三、案例实现一、效果对比 原始图片: 深度学习后的模糊照片: 二、工具介绍 本工具为ArcGIS Pro工具箱中的深度学习工具中的:使用深度学习分类像素,如下所示…

vue3中自定义hook函数

使用Vue3的组合API封装的可复用的功能函数 自定义hook的作用类似于vue2中的mixin技术 自定义Hook的优势: 很清楚复用功能代码的来源, 更清楚易懂 案例: 收集用户鼠标点击的页面坐标 hooks/useMousePosition.ts文件代码&#xff1a; import { ref, onMounted, onUnmounted …

Java LeetCode篇-深入了解关于栈的经典解法(栈实现:中缀表达式转后缀)

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 中缀表达式转后缀说明 1.1 实现中缀表达式转后缀思路 2.0 逆波兰表达式求值 2.1 实现逆波兰表达式求值思路 3.0 有效的括号 3.1 实现有效的括号思路 4.0 栈的压…

法学毕业生个人简历16篇

想要从众多法学毕业求职者中脱颖而出&#xff0c;找到心仪的相关工作&#xff1f;可以参考这16篇精选的法学专业应聘简历案例&#xff0c;无论是应届比预算还是有工作经验&#xff0c;都能从中汲取灵感&#xff0c;提升简历质量。希望对大家有所帮助。 法学毕业生简历模板下载…

RPG项目01_脚本代码

基于“RPG项目01_场景及人物动画管理器”&#xff0c;我们创建一个XML文档 在资源文件夹下创建一个文件夹&#xff0c; 命名为Xml 将Xnl文档拖拽至文件夹中&#xff0c; 再在文件夹的Manager下新建脚本LoadManager 写代码&#xff1a; using System.Collections; using System…

Pycharm调用Conda虚拟环境

参考这个链接的评论区回答&#xff1a;Pycharm调用Conda虚拟环境 笑死&#xff0c;我之前也是这样的&#xff0c;不过好像也能用&#xff0c;搞不懂~

Ontrack EasyRecovery2024数据恢复软件详细功能介绍

Ontrack EasyRecovery2024是一款功能强大的数据恢复软件&#xff0c;它可以帮助用户从各种存储设备中恢复丢失或删除的数据。它支持多种文件系统和文件类型&#xff0c;可以恢复包括照片、视频、音频、文档、电子邮件和归档文件等不同类型的数据。 EasyRecovery15Mac版本下载如…

文案二次创作软件,文案二次创作的软件

文案创作成为品牌传播和营销不可或缺的一环。对于许多从业者而言&#xff0c;文案创作常常是一项既耗时又耗力的工作。为了解决这一文案创作的难题&#xff0c;市场上涌现出了众多的智能文案生成工具。我们通过对这些工具的介绍和分析&#xff0c;希望能够为你提供一些在文案创…

Micropython for QNX编译过程

Micropython for QNX编译过程 执行步骤 1. https://github.com/micropython/micropython select tag 1.20.0 git clone micropython 2. make -C mpy-cross 3. 修改py/mkenv.mk CROSS_COMPILE ntoaarch64- 注意如果这步必须在make -C mpy-cross 之后执行&#xff0c;如果需要重…

宝塔+docker+jenkins部署vue项目----笔记版

宝塔dockerjenkins部署vue项目&#xff08;保姆级教程&#xff09;https://blog.csdn.net/weixin_47284756/article/details/129339940 基于上述教程&#xff0c;不同的地方。 1.我使用的是gitee&#xff0c;所以需要在jenkins中安装gitee插件 配置gitee&#xff0c;其他默认配…

SmartsoftHelp8,条形码,二维码 生成,解析 专业工具

生成条形码 生成二维码 条形码解析 二维码解析 专业工具 下载地址&#xff1a; https://pan.baidu.com/s/1zBgeYsqWnSlNgiKPR2lUYg?pwd8888

大学程序员的养生之道

呀哈喽&#xff0c;我是结衣。 今天给大家带来的是大学程序员的养生之道&#xff01; 作为一名大学生还没有深刻的感受到未来的恐怖&#xff0c;但每当我看到这些对程序员的评价还是不禁感慨。 不要让自己的学习之路变成这样啊&#xff01;程序员的职业发展&#xff1a;某编程语…

CSS:calc() 函数 / 动态计算长度值 / 不同场景使用

一、理解 css calc() 函数 CSS calc() 函数是一个用于计算 CSS 属性值的函数。它可以在 CSS 属性值中使用数学表达式&#xff0c;从而实现动态计算属性值的效果。calc() 函数可以使用加减乘除四种基本数学运算符来计算属性值&#xff0c;还可以使用括号来改变优先级。 二、ca…

【brew】Mac上安装vue3

先安装node。 这里我从其他博客找的方案&#xff0c;原始脚本下载太慢了。 cnpm的安装&#xff1a; 让npm更快一点。 npm install -g cnpm --registryhttps://registry.npm.taobao.org安装vue脚手架 2.0版本&#xff1a;sudo npm install -g vue-cli 3.0版本&#xff1a; sud…

Java实战案例————ATM

需求分析 首先ATM银行系统包括两个基础大功能&#xff1a;开户和登陆账户&#xff08;当然在系统中没有一个账户时不能登录&#xff0c;需要先开户&#xff09;。 一名用户有6项基本信息描述&#xff1a;姓名、性别、银行卡号、银行卡密码、账户余额、取款限额。 在登录账户…

QNX常用调试方法

QNX常用调试方法 1. top 查询系统状态最常用的工具是top&#xff0c;它可以显示系统资源的使用情况。我们最关心的通常是系统可用内存和CPU使用率。如果CPU使用率过高可能是因为某些应用存在bug&#xff0c;重点关注下面显示的占用CPU资源最多的几个线程。如果可用内存太少&am…

Fisher信息理论与应用

一、概念介绍 Fisher信息量&#xff0c;是一次观测值所能提供的关于未知参数θ的信息量期望值的一种度量。 Fisher信息矩阵&#xff0c;是用利用最大似然函数估计来计算方差矩阵&#xff0c;表示随机变量的一个样本所能提供的关于状态参数在某种意义下的平均信息量。 Fisher…

node.js express路由和中间件

目录 路由 解释 使用方式 中间件 解释 使用方式 中间件类型 路由注册和中间件注册 代码 app全局路由接口请求以及代码解析 示例1 示例2 示例3 示例4 中间件req继承 嵌套子路由 解释 代码 示例1 路由 解释 在 Express 中&#xff0c;路由&#xff08;Route&…