OpenCVForUnity(六)图像的对比度和亮度

文章目录

  • 前言
  • 公式讲解
  • Unity嵌套循环实现
  • 使用convertTo实现
  • 亮度和对比度调整:
  • 伽马矫正


前言

图片处理中这也是非常常用的功能,下面我们一起来学习一下如何在OpenCVForUnity中修改图像的对比度亮度
图像处理中的常见算子可以将一个或多个输入图像转换为输出图像。这些变换包括点运算符(也称像素变换)和邻域运算符。
像素变换仅取决于相应的输入像素值,例如亮度、对比度和颜色的调整。其中两个常见的点处理运算符是加法和乘法。


公式讲解

一点处理是乘法和加法:
在这里插入图片描述

二参数和\bate通常称为增益和篇章参数;有时候这些参数被分别控制对比度和亮度. α>β
可以视作为源像素, g(x)作为输出图像像素.表达式为 f(x)g(x)
在这里插入图片描述

j表示第i行和第j列.


Unity嵌套循环实现

下面我们用C#在Unity中实现一下,我们使用Imgcodecs加载完图片后,套用上面的公式使用循环嵌套实现一下,代码如下:

//参数α 和 β
float alpha = 2f;
float beta = 0;
//读取图片
string readPath1 = Application.dataPath + "/OpenCVForUnity/Examples/Resources/timg.jpg";
Mat image = Imgcodecs.imread(Utils.getFilePath(readPath1), Imgcodecs.IMREAD_COLOR);
Mat new_image = new Mat(image.size(), CvType.CV_8UC3);//三层嵌套结构
for (int rows = 0; rows < image.rows(); rows++)
{for (int cols = 0; cols < image.cols(); cols++){double[] cur = image.get(rows, cols);for (int c = 0; c < cur.Length; c++){cur[c] = (alpha * cur[c]) + beta;}new_image.put(rows, cols, cur);}
}
//下面是把两个Mat图片内容展示出来的代码,此处略...

下面看下效果:
在这里插入图片描述
我们能看到,在读取图片后有个三层嵌套循环。一、循环 每一行里的每一列中的每个通道进行计算。
如果只用上面的方式,那就太低效了.于是OpenCV为我们内置了 convertTo 方法.
将有效地执行 new_image = a * image + beta 。但是,我们想告诉你如何访问每个像素。
在任何情况下,两种方法都给出相同的结果,但是convertTo是更优化的,并且工作得更快。


使用convertTo实现

//参数α 和 β
float alpha = 2f;
float beta = 0;
//读取图片
string readPath1 = Application.dataPath + "/OpenCVForUnity/Examples/Resources/timg.jpg";
Mat image = Imgcodecs.imread(Utils.getFilePath(readPath1), Imgcodecs.IMREAD_COLOR);
Mat new_image = new Mat(image.size(), CvType.CV_8UC3);
image.convertTo(new_image,-1,alpha,beta);

这个与上面的是等效的,这样代码看起来简洁多了,而且更高效。


亮度和对比度调整:

在图像处理中, 通过增加或减少每个像素的常量值来进行亮度和对比度的调整。如果像素值超过0到255的范围,则会被剪裁到该范围内。
在这里插入图片描述
直方图是显示每个颜色级别的像素数量的图表。当添加恒定偏差时,直方图将会向右移动,因为每个像素都添加了固定的偏差。水平参数(alpha)会影响颜色级别的分布。如果alpha小于1,则颜色级别将被压缩,导致对比度减小的图像。
在这里插入图片描述
这些直方图是使用Gimp软件中的“亮度 - 对比度”工具获得的。亮度调整工具与偏置参数类似,但似乎对比度调整工具中的alpha增益不同,输出范围似乎以Gimp为中心(即先前直方图的图形显示)。使用偏置调整可以提高图像的亮度,但是会导致轻微的模糊,对比度下降。增加alpha增益可以降低此效果,但是饱和会导致一些明亮区域的细节丢失。因而我们需要使用伽马矫正技术。


伽马矫正

伽马校正可以用于校正图像的亮度。这是通过对输入值和映射的输出值之间进行非线性变换来实现的。
在这里插入图片描述
当,原始的暗区域会更亮,直方图将向右移动,而\ gamma> 1则会相反。γ<1γ>1

更正曝光不足的图像
在这里插入图片描述
整体亮度得到了改善,但是由于数码饱和的原因,可以看到云层已经非常亮了(即在拍摄时被剪辑掉了)。
以下图像已更正:。γ=0.4
在这里插入图片描述
伽马校正比以前的方法更倾向于减少饱和效应,因为映射是非线性的,并且没有像以前的方法那样的数字饱和。
在这里插入图片描述
左:直方图alpha,β校正; 中心:原始图像的直方图; 右:伽马校正后的直方图


上图比较了三个图像的直方图,可以看到大多数像素值位于原始图像的直方图的较低部分。
在通过其他方法进行调整后,我们可以看到在255的位置有一个高峰,这是由于数码饱和和右侧的偏移所致。
在使用伽马校正后,直方图向右移动,但是暗区域中的像素比明亮区域中的像素更大偏移(参见伽马曲线图)。
这些都是基本技术,不能完全替代光栅图形编辑器。

以下是实现代码:

// 读取图像
Texture2D inputTexture = (Texture2D)Resources.Load("88");
// 将纹理转换为OpenCV Mat对象
Mat inputMat = new Mat(inputTexture.height, inputTexture.width, CvType.CV_8UC4);
Utils.texture2DToMat(inputTexture, inputMat, true);
// 应用gamma矫正
double gamma = 1.5;
Core.pow(inputMat, gamma, inputMat);
// 调整图像亮度
double alpha = 100.0;
double beta = 50.0;
Core.convertScaleAbs(inputMat, inputMat, alpha, beta);
// 将Mat对象转换回Unity Texture2D对象
Texture2D outputTexture = new Texture2D(inputMat.cols(), inputMat.rows(), TextureFormat.RGBA32, false);
Utils.matToTexture2D(inputMat, outputTexture);
// 在Unity中显示
objA.GetComponent<Renderer>().material.mainTexture = inputTexture;
objB.GetComponent<Renderer>().material.mainTexture = outputTexture;

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

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

相关文章

RISCV - 1 RV32/64G指令集清单

RISCV - 1 RV32/64G指令集清单 1 RV32/64G指令类型2 RV32I 基本指令集3 RV64I基础指令集&#xff08;除了RV32I)4 RV32/RV64 Zifencei标准扩展5 RV32/RV64 Zicsr标准扩展6 RV32M标准扩展7 RV64M标准扩展&#xff08;除了RV32M)8 RV32A标准扩展9 RV64A标准扩展&#xff08;除了R…

(栈队列堆) 剑指 Offer 09. 用两个栈实现队列 ——【Leetcode每日一题】

❓ 剑指 Offer 09. 用两个栈实现队列 难度&#xff1a;简单 用两个栈实现一个队列。队列的声明如下&#xff0c;请实现它的两个函数 appendTail 和 deleteHead &#xff0c;分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素&#xff0c;deleteHead …

机器学习32:《推荐系统-V》再谈召回、打分和重排

在《机器学习28&#xff1a;推荐系统-概述》一文中&#xff0c;笔者概述了推荐系统的基本术语和一般架构&#xff0c;通过【推荐系统 I&#xff5e;IV】系列课程的学习&#xff0c;相信读者对推荐系统已经有了一定的理解。本节&#xff0c;我们再来回顾一下推荐系统的核心环节—…

泛在电力物联网、能源互联网与虚拟电厂

导读&#xff1a;从能源互联网推进受阻&#xff0c;到泛在电力物联网名噪一时&#xff0c;到虚拟电厂再次走向火爆&#xff0c;能源领域亟需更进一步的数智化发展。如今&#xff0c;随着新型电力系统建设推进&#xff0c;虚拟电厂有望迎来快速发展。除了国网和南网公司下属的电…

浅谈自动化测试工具 Appium

目录 前言&#xff1a; 一、简单介绍 &#xff08;一&#xff09;测试对象 &#xff08;二&#xff09;支持平台及语言 &#xff08;三&#xff09;工作原理 &#xff08;四&#xff09;安装工具 二、环境搭建 &#xff08;一&#xff09;安装 Android SDK &#xff0…

欧姆龙以太网模块如何设置ip连接 Kepware opc步骤

在数字化和自动化的今天&#xff0c;PLC在工业控制领域的作用日益重要。然而&#xff0c;PLC通讯口的有限资源成为了困扰工程师们的问题。为了解决这一问题&#xff0c;捷米特推出了JM-ETH-CP转以太网模块&#xff0c;让即插即用的以太网通讯成为可能&#xff0c;不仅有效利用了…

Unity自定义后处理——Vignette暗角

大家好&#xff0c;我是阿赵。   继续说一下屏幕后处理的做法&#xff0c;这一期讲的是Vignette暗角效果。 一、Vignette效果介绍 Vignette暗角的效果可以给画面提供一个氛围&#xff0c;或者模拟一些特殊的效果。 还是拿这个角色作为底图 添加了Vignette效果后&#xff0…

【完整版】zabbix企业级监控(概念、简单操作、页面优化、监控主机自己、监控linux、监控Win10)

第三阶段基础 时 间&#xff1a;2023年7月19日 参加人&#xff1a;全班人员 内 容&#xff1a; zabbix企业级监控 目录 一、Zabbix概述 &#xff08;一&#xff09;Zabbix简介 &#xff08;二&#xff09;Zabbix运行条件&#xff1a; &#xff08;三&#xff09;Zab…

Linux gdb汇编调试

文章目录 一、示例代码二、gdb汇编指令2.1 step/stepi2.2 next/nexti2.3 info registers2.4 set2.5 x2.6 rsp寄存器2.7 rip 寄存器 参考资料 一、示例代码 &#xff08;1&#xff09; #include <stdio.h>int add(int a, int b) {return a b; }int main() {int a 3;in…

Airbnb 引入 HTTP Streaming,网页性能得到大幅度提升

Airbnb 通过引入HTTP Streaming来提升网站的页面加载性能。他们将测试的每个页面&#xff08;包括主页&#xff09;的首次内容绘制&#xff08;First Contentful Paint&#xff0c;FCP&#xff09;时间降低了大约 100 毫秒。他们还最小化了后端慢查询对加载时间的影响。 Airbn…

​大华智慧园区综合管理平台存在任意文件上传漏洞

免责声明 请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失,均由使用者本人负责,所产生的一切不良后果与文章作者无关。该文章仅供学习用途使用。 大华智慧园区综合管理平台简介 大华智慧园区综合管理…

JavaScript数组所有方法集合

##方法 1、concat 用于合并两个或多个数组。此方法不会更改现有数组&#xff0c;而是返回一个新数组 2、copyWithin 浅复制数组的一部分到同一数组中的另一个位置&#xff0c;并返回它&#xff0c;不会改变原数组的长度 3、entries 返回一个新的 Array Iterator 对象&#xf…