C#+vs2019windos窗口实现数字图像基础处理(灰度化,二值化,对比度,亮度)

2023-05-16

目录

  • 一、灰度化
  • 二、亮度
  • 三、对比度
  • 四、可变阈值二值化
  • 五、自适应二值化

一、灰度化

在三原色理论中,所有颜色都是以红、绿、蓝三原色按不同比例混合构成的,不同的红、绿、蓝三原色比例构成了不同的颜色。
而灰度数字图像指的是图像中每个像素只有一个采样颜色的图像,通常显示为从最暗黑色到最亮的白色的灰度。本质上灰度数字图像中像素点中三原色的比例相同,0-255个灰度。
RGB图片转化为灰度图片,就是将RGB图像中每一个像素转化为灰度,通常采用 Gray=(R*30+G*59+B*11)/100公式转化。
核心代码如下:

Bitmap bt = new Bitmap(pictureBox1.Image);
Bitmap bt1 =neBitmap(pictureBox1.Image);//定义并初始化两个位图对象
Color color = new Color();//定义一个颜色对象
for (int i = 0; i < bt.Width; i++)
 {
 for (int j = 0; j < bt.Height; j++)
 {
 color = bt.GetPixel(i, j); //遍历整张图像,获取每个像素的色彩信息
 int n = (int)((color.G * 59 + color.R * 30 + color.B * 11) / 100); //根据GRB的不同的权值计算每个像素点的亮度,利用该亮度作为灰度图像中每个像素的灰度值
 bt1.SetPixel(i,j,Color.FromArgb(n,n,n)); //给该像素的每种色彩分量均赋予相同的附录 A 数字图像处理基本算法的 C#程序实现 310灰度值,完成灰度图像的转换
 }

实现效果如下:

Alt

二、亮度

亮度是指图像色彩的明暗程度,是人眼对物体明暗强度的感觉,取值为0%–100%。
所以亮度调节就是修改像素分量的值使得其根据调节值改变图像的亮度。
代码原理:首先提取出图像的每个像素点的RGB分量,根据所要求调整的图像亮度同时同量地改变每个像素点的RGB值。
例如:增加图像亮度10个值,则对图像的每个像素点的RGB分量值进行加10操作,但是要注意RGB值需位于0-255之间。
核心代码:

for (int j = 0; j < bt1.Height; j++)
 {
 //获取位于(i,j)坐标的像素然后提取RGB分量
 Color color = bt.GetPixel(i, j);
 r = color.R;
 g = color.G;
 b = color.B;
 //对RGB分量进行增加或删除,增加量为滑杆滑动的量
 r += value;
 g += value;
 b += value;
 if (r > 255) r = 255; //判断各颜色分量的值是否超出各分量允许的范围,如果大于255则只能等于255
 if (r < 0) r = 0; //如果小于0则只能等于0
 if (g > 255) g = 255;
 if (g < 0) g = 0;
 if (b > 255) b = 255;
 if (b < 0) b = 0;
 Color c1 = Color.FromArgb(r, g, b); //用调整后的值生成新的颜色对象
 bt1.SetPixel(i, j, c1); //把新的颜色c1赋给bt1位图对象在坐标为(i,j)的像素
 }

实现效果如下:
Alt

三、对比度

对比度调节的实质是使图像中各像素的亮度分布发生变化,对比度增强时亮的点更亮,
暗的点更暗,对比度减弱则相反。
代码原理:首先获取图像每个像素点的RGB分量值,获取此次对比度的调整值,然后根据此次对比度调整值得到像素点RGB分量的变化值,然后将RGB分量值分出强弱,较强的RGB分量加上变化值,较弱的RGB分量减去变化值。
核心代码如下:

for (int i = 0; i < bt1.Width; i++)
 {
 for (int j = 0; j < bt1.Height; j++)
 {
 //获取位于(i,j)坐标的像素然后提取RGB分量
 Color c = bt.GetPixel(i, j);
 r = c.R;
 g = c.G;
 b = c.B;
 //对RGB分量进行变换
 int rg = (Math.Abs(127 - r) * degree) / 255;
 int gg = (Math.Abs(127 - g) * degree) / 255;
 int bg = (Math.Abs(127 - b) * degree) / 255;
 //这个判断的作用是使得颜色对比度更加明显也就是亮度更亮暗的更暗
 if (r > 127) r = r + rg;
 else r = r - rg;
 if (g > 127) g = g + gg;
 else g = g - gg;
 if (b > 127) b = b + bg;
 else b = b - bg;
 //判断三分量是否超过了取值范围
 if (r > 255) r = 255;
 if (r < 0) r = 0;
 if (g > 255) g = 255;
 if (g < 0) g = 0;
 if (b > 255) b = 255;
 if (b < 0) b = 0;
 Color c1 = Color.FromArgb(r, g, b);
 //把新的像素赋值bt1位图对象在坐标为(i,j)的像素
 bt1.SetPixel(i, j, c1);
 }

实现效果:
Alt

四、可变阈值二值化

二值图像是指将图像上的每一个像素只有两种可能的取值或灰度等级状态,每个像素不是黑就是白。
代码原理:此处的可变阈值二值化,便是自选一个阈值,若该像素点的亮度大于此阈值,则用白色表示;低于该阈值,用黑色表示。
核心代码:

for (int j = 0; j <= pictureBox1.Image.Height - 1; j++)//循环处理图像中的每一个像素点
 {
 ColorOrigin = Bmp1.GetPixel(i, j); //获取当前像素点的色彩信息
 Red = ColorOrigin.R; //获取当前像素点的红色分量
 Green = ColorOrigin.G; //获取当前像素点的绿色分量
 Blue = ColorOrigin.B; //获取当前像素点的蓝色分量
 Y = 0.59 * Red + 0.3 * Green + 0.11 * Blue; //计算当前像素点的亮度
 if (Y>brightThreshole) //如果当前像素点的亮大于指定阈值
 {
 Color ColorProcessed = Color.FromArgb(255, 255, 255); //那么定义一个纯白
的色彩变量,即各分量均为255
 Bmp1.SetPixel(i, j, ColorProcessed); //将白色变量赋给当前像素点
 }
 if (Y <= brightThreshole) //如果当前像素点的度小于指定阈值
 {
 Color ColorProcessed = Color.FromArgb(0, 0, 0); //那么定义一个纯黑的色彩
变量,即各分量均为0
 Bmp1.SetPixel(i, j, ColorProcessed); //将黑色变量赋给当前像素点
 } 
 }

实际演示如下:
Alt

五、自适应二值化

自适应二值化与可变阈值二值化的区别就在于,自适应二值化能根据算法求得一个合适的阈值,不需要人手动调整最佳阈值。
代码原理:实话说我还没搞清楚求阈值的算法原理
核心代码如下:

for(int i=1;i<pictureBox1.Image.Width-1;i++)
 {
 for(int j=1;j<pictureBox1.Image.Height-1;j++)
 {
 c=box1.GetPixel(i,j);
 r=c.R;
 array[i,j]=r;
 }
 }
 //灰度值在0-256之间变换,再次扫描图像,把相同灰度值的累加起来
 for(int i=1;i<pictureBox1.Image.Width;i++)
 {
 for(int j=1;j<pictureBox1.Image.Height;j++)
 {
 for(int k=0;k<255;k++)
 {
 if(array[i,j]==k)
 {
 tt[k]=tt[k]+1;
 }
 }
 }
 }
 //求出图像里含有的各个灰度值所占的百分比
 for(int m=0;m<255;m++)
 {
 p[m]=tt[m]/(pictureBox1.Image.Width*pictureBox1.Image.Height);
 }
 //求灰度均值
 for(int n = 1;n<256;n++)
 {
 u=u+(n-1)*p[n];
 }
 //求灰度类均值和直方图和
 for(int i=1;i<256;i++)
 {
 uu[i]=uu[i-1]+(i-1)*p[i];
 w[i]=w[i-1]+p[i];
 if(w[i]*(1-w[i-1])!=0)
 {
 b[i]=((u*w[i]-uu[i])*(u*w[i]-uu[i]))/(w[i]*(1-w[i]));
 }
 }
 //初始化函数最大值
 max=b[0];
 //求出使函数达到最大值的变量
 for(int i=0;i<255;i++)
 {
 if(b[i]>=max)
 {
 max=b[i];
 }
 }
 for(int j=0;j<255;j++)
 {
 if(b[j]==max)
 maxb=j;
 }
 //最佳阈值就是maxb-1,然后根据阈值对灰度图像进行二值化处理
 for(int i=1;i<pictureBox1.Image.Width;i++)
 {
 for(int j=1;j<pictureBox1.Image.Height;j++)
 {
 c=box1.GetPixel(i,j);
 r=c.R;
 if(r>(maxb-1))
 box1.SetPixel(i,j,cc2);
 else
 box1.SetPixel(i,j,cc1);
 }


实际演示如下:

Alt

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C#+vs2019windos窗口实现数字图像基础处理(灰度化,二值化,对比度,亮度) 的相关文章

  • 如何在程序中解析获取word文档(docx格式)的文本内容

    原理 docx格式的word文档其实是一个压缩包 xff0c 文本内容 格式 图片等是分别存储在不同的文件中的 xff0c office通过这些文件还原出我们所看到的word文档 下面以一个简单的示例来说明docx格式 示例 首先我们新建一
  • QFormLayout布局该什么时候使用

    概述 QFormLayout是一种支持两列的格子布局方式 xff0c 左列是标签 xff0c 右列是窗口部件 可以方便且快速的实现标签和输入组件的组合 xff0c 如下图 示例 像上面的例子 xff0c 使用QGridLayout 栅格布局
  • Qt判断文件类型 QMimeType

    前言 通常来说我们判断一个文件的类型是根据后缀名称来的 xff0c 例如 xff1a txt是文本文件 exe是二进制文件可执行程序 在程序中需要预设后缀名称 xff0c 有些时候不太容易把属于某类文件的后缀名写全 比如说图片类型的文件 x
  • 在qmake中定义子项目的编译顺序(依赖关系)

    背景 当一个大项目中包含多个子项目时 xff0c 往往子项目之间有依赖关系 xff0c 这时需要在pro文件中指明子项目的编译顺序 xff0c 否则编译整个项目的时候可能会失败 实现 现有项目一名称为Porject1 xff0c 包含三个子
  • lua面向对象-----继承的实现

    前言 在lua里是没有类的概念的 xff0c 但是可以利用表 xff08 table xff09 和元表特性来实现面向对象和继承 lua的表类似于一个对象 xff0c 每个对象都有自己的方法和属性 当访问一个表中不存在的属性时 xff0c
  • 使用Qt实现阿里云API签名

    最近需要使用阿里云API来访问物联网平台 xff0c 但是阿里官方的C 43 43 版API有些复杂而且编译有些问题 xff0c 所以决定自己来实现 xff0c 这里主要就是要解决签名的问题 xff0c 下面把签名实现的部分分享一下 使用示
  • Ubuntu下dpkg安装软件遇到包依赖问题的处理方法

    在Ubuntu环境下通过dpkg命令安装deb包时 xff0c 如果遇到包依赖问题 xff0c 如 sudo dpkg i xxx deb Reading database 227173 files and directories curr
  • proxmox VE备份优化手记--两次优化,大幅度提高性能

    问题描述 某项目由两套proxmox组成 xff0c 一套运行所有的应用程序 xff0c 一台运行mysql数据库 为了保险起见 xff0c proxmox外挂共享存储 xff0c 夜间对所有的虚拟机进行自动备份 备份是用的一台4U服务器
  • 开源超融合私有云神器proxmox VE

    Prxomox VE由位于奥地利维也纳的Proxmox Server Solutions GmbH开发 xff0c 这让人有点意外 其实欧洲在IT技术方面 xff0c 还是很强的 xff0c 比如大名鼎鼎的mysql xff0c 出自瑞典
  • Proxmox VE 桌面虚拟化(windows 10)集群尝试

    一家小型企业 内部有几台服务器 办公电脑40几台 这些服务器都是单点 经历过一次财务服务器损坏 好几周都不能开展业务的惨痛教训 正对这种问题 可采用proxmox超融合集群来解决业务高可用问题 但考虑到它的业务服务器数量不多 用超融合集群专
  • Promox VE日常维护

    Promox VE超融合私有云部署并用于生产系统以后 并不能一劳永逸 这仅仅是万里长征走完了第一步 虽然超融合私有云本身提供了非常高的可用性 但并不保证整个系统在运行中不会整体崩溃 因此 好的系统加上好的维护 才是正途 Promox VE超
  • PBS(proxmox backup server)尝鲜记

    作者 xff1a 田逸 xff08 vx xff1a formyz xff0c mail xff1a sery 64 163 com xff09 终于等到pbs发布正式版本pbs 1 0 迫不及待去官网下载好proxmox backup s
  • 打造炫酷的Proxmox VE 监控界面

    打造炫酷的Proxmox VE 监控界面 今天终于把Proxmox VE xff08 简称PVE xff09 从6 1版本升级到PVE 6 4版本 xff0c 在Web管理后台对比PVE 6 4与 PVE 6 1 xff0c 看新增哪些功能
  • Proxmox VE 多机系统备份

    作者 xff1a 田逸 在我管控的项目里 xff0c 有Proxmox VE集群 xff0c 也有些单独的PVE 我打算把集群上的虚拟机 单机PVE上的虚拟机 xff0c 都备份到同一个大容量存储 这样规划 xff0c 即能有效利用资源 x
  • Proxmox VE 超融合集群实践真传

    第1章 老司机眼中的私有云 3 1 1私有云的定义 3 1 2私有云适用场景 4 1 3私有云行业现状 6 1 4私有云技术要求 xff08 针对Proxmox VE平台 xff09 7 第2章 开源私有云神器Proxmox VE 8 2
  • Proxmox VE 超融合集群创建多个Ceph Pool

    作者 xff1a 田逸 xff08 vx formyz xff09 创建多Ceph Pool的目的 Proxmox VE集群上的虚拟机运行在高速磁盘NVME 而虚拟机附属的数据 xff0c 则指定到低速 廉价 容量大的磁盘空间 为了高可用性
  • Proxmox VE 超融合集群OVS(Open vSwitch)虚拟机网络隔离

    作者 xff1a 田逸 需求的产生 在一个高配置的Proxmox VE 超融合集群中 xff0c 为充分利用资源 xff0c 需要按某种需求将虚拟机之间进行网络隔离 xff0c 以支持更大规模的场景 网络虚拟化基本条件 支持VLAN的网络交
  • 第1章 Rust安装

    Rust是一门安全的语言 xff0c 最近也加入到Linux内核中 xff0c 因此后续这门语言会越来越流行 xff0c 所以准备学习下 xff0c 本篇介绍Rust在Window平台上的安装过程 目录 安装步骤 1 到官网下载安装包 2
  • Proxmox VE 7.0升级到Proxmox VE 7.1虚拟机重启失败

    一单节点pve xff0c 版本为7 0 xff0c 顺手刷了一下更新 xff0c 升级到版本7 1 因为对其中的一个Centos 7虚拟机执行了yum update 重启此虚拟机 xff0c 启动失败 xff0c 尝试多次皆如此 kvm
  • Proxmox VE 修改集群名称

    作者 xff1a 田逸 xff08 formyz Proxmox VE集群一旦创建 xff0c 其集群的名称就固定下来 在Proxmox VE Web管理后台 xff0c 没有相应的菜单或按钮对应与集群名称的修改 xff08 仅仅发现修改虚

随机推荐