c#数字图像处理(七)直方图匹配
直方图匹配,又称直方图规定化,即变换原图的直方图为规定的某种形式的直方图,从而使两幅图像具有类似的色调和反差。直方图匹配属于非线性点运算。
直方图规定化的原理:对两个直方图都做均衡化,变成相同的归一化的均匀直方图,以此均匀直方图为媒介,再对参考图像做均衡化的逆运算
- /// <summary>
- /// 直方图匹配
- /// </summary>
- /// <param name="srcBmp">原始图像</param>
- /// <param name="matchingBmp">匹配图像</param>
- /// <param name="dstBmp">处理后图像</param>
- /// <returns>处理成功 true 失败 false</returns>
- public static bool HistogramMatching(Bitmap srcBmp, Bitmap matchingBmp, out Bitmap dstBmp)
- {
- if (srcBmp == null || matchingBmp == null)
- {
- dstBmp = null;
- return false;
- }
- dstBmp = new Bitmap(srcBmp);
- Bitmap tempSrcBmp = new Bitmap(srcBmp);
- Bitmap tempMatchingBmp = new Bitmap(matchingBmp);
- double[] srcCpR = null;
- double[] srcCpG = null;
- double[] srcCpB = null;
- double[] matchCpB = null;
- double[] matchCpG = null;
- double[] matchCpR = null;
- //分别计算两幅图像的累计概率分布
- getCumulativeProbabilityRGB(tempSrcBmp, out srcCpR, out srcCpG, out srcCpB);
- getCumulativeProbabilityRGB(tempMatchingBmp, out matchCpR, out matchCpG, out matchCpB);
- double diffAR = , diffBR = , diffAG = , diffBG = , diffAB = , diffBB = ;
- byte kR = , kG = , kB = ;
- //逆映射函数
- byte[] mapPixelR = new byte[];
- byte[] mapPixelG = new byte[];
- byte[] mapPixelB = new byte[];
- //分别计算RGB三个分量的逆映射函数
- //R
- for (int i = ; i < ; i++)
- {
- diffBR = ;
- for (int j = kR; j < ; j++)
- {
- //找到两个累计分布函数中最相似的位置
- diffAR = Math.Abs(srcCpR[i] - matchCpR[j]);
- if (diffAR - diffBR < 1.0E-08)
- {//当两概率之差小于0.000000001时可近似认为相等
- diffBR = diffAR;
- //记录下此时的灰度级
- kR = (byte)j;
- }
- else
- {
- kR = (byte)Math.Abs(j - );
- break;
- }
- }
- if (kR == )
- {
- for (int l = i; l < ; l++)
- {
- mapPixelR[l] = kR;
- }
- break;
- }
- mapPixelR[i] = kR;
- }
- //G
- for (int i = ; i < ; i++)
- {
- diffBG = ;
- for (int j = kG; j < ; j++)
- {
- diffAG = Math.Abs(srcCpG[i] - matchCpG[j]);
- if (diffAG - diffBG < 1.0E-08)
- {
- diffBG = diffAG;
- kG = (byte)j;
- }
- else
- {
- kG = (byte)Math.Abs(j - );
- break;
- }
- }
- if (kG == )
- {
- for (int l = i; l < ; l++)
- {
- mapPixelG[l] = kG;
- }
- break;
- }
- mapPixelG[i] = kG;
- }
- //B
- for (int i = ; i < ; i++)
- {
- diffBB = ;
- for (int j = kB; j < ; j++)
- {
- diffAB = Math.Abs(srcCpB[i] - matchCpB[j]);
- if (diffAB - diffBB < 1.0E-08)
- {
- diffBB = diffAB;
- kB = (byte)j;
- }
- else
- {
- kB = (byte)Math.Abs(j - );
- break;
- }
- }
- if (kB == )
- {
- for (int l = i; l < ; l++)
- {
- mapPixelB[l] = kB;
- }
- break;
- }
- mapPixelB[i] = kB;
- }
- //映射变换
- BitmapData bmpData = dstBmp.LockBits(new Rectangle(, , dstBmp.Width, dstBmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
- unsafe
- {
- byte* ptr = null;
- for (int i = ; i < dstBmp.Height; i++)
- {
- ptr = (byte*)bmpData.Scan0 + i * bmpData.Stride;
- for (int j = ; j < dstBmp.Width; j++)
- {
- ptr[j * + ] = mapPixelR[ptr[j * + ]];
- ptr[j * + ] = mapPixelG[ptr[j * + ]];
- ptr[j * ] = mapPixelB[ptr[j * ]];
- }
- }
- }
- dstBmp.UnlockBits(bmpData);
- return true;
- }
- /// <summary>
- /// 计算各个图像分量的累计概率分布
- /// </summary>
- /// <param name="srcBmp">原始图像</param>
- /// <param name="cpR">R分量累计概率分布</param>
- /// <param name="cpG">G分量累计概率分布</param>
- /// <param name="cpB">B分量累计概率分布</param>
- private static void getCumulativeProbabilityRGB(Bitmap srcBmp, out double[] cpR, out double[] cpG, out double[] cpB)
- {
- if (srcBmp == null)
- {
- cpB = cpG = cpR = null;
- return;
- }
- cpR = new double[];
- cpG = new double[];
- cpB = new double[];
- int[] hR = null;
- int[] hG = null;
- int[] hB = null;
- double[] tempR = new double[];
- double[] tempG = new double[];
- double[] tempB = new double[];
- getHistogramRGB(srcBmp, out hR, out hG, out hB);
- int totalPxl = srcBmp.Width * srcBmp.Height;
- for (int i = ; i < ; i++)
- {
- if (i != )
- {
- tempR[i] = tempR[i - ] + hR[i];
- tempG[i] = tempG[i - ] + hG[i];
- tempB[i] = tempB[i - ] + hB[i];
- }
- else
- {
- tempR[] = hR[];
- tempG[] = hG[];
- tempB[] = hB[];
- }
- cpR[i] = (tempR[i] / totalPxl);
- cpG[i] = (tempG[i] / totalPxl);
- cpB[i] = (tempB[i] / totalPxl);
- }
- }
- /// <summary>
- /// 获取图像三个分量的直方图数据
- /// </summary>
- /// <param name="srcBmp">图像</param>
- /// <param name="hR">R分量直方图数据</param>
- /// <param name="hG">G分量直方图数据</param>
- /// <param name="hB">B分量直方图数据</param>
- public static void getHistogramRGB(Bitmap srcBmp, out int[] hR, out int[] hG, out int[] hB)
- {
- if (srcBmp == null)
- {
- hR = hB = hG = null;
- return;
- }
- hR = new int[];
- hB = new int[];
- hG = new int[];
- BitmapData bmpData = srcBmp.LockBits(new Rectangle(, , srcBmp.Width, srcBmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
- unsafe
- {
- byte* ptr = null;
- for (int i = ; i < srcBmp.Height; i++)
- {
- ptr = (byte*)bmpData.Scan0 + i * bmpData.Stride;
- for (int j = ; j < srcBmp.Width; j++)
- {
- hB[ptr[j * ]]++;
- hG[ptr[j * + ]]++;
- hR[ptr[j * + ]]++;
- }
- }
- }
- srcBmp.UnlockBits(bmpData);
- return;
- }
c#数字图像处理(七)直方图匹配的更多相关文章
- OpenCV-跟我一起学数字图像处理之直方图均衡化
从这篇博文开始,小生正式从一个毫不相干专业转投数字图像处理.废话不多说了,talk is cheap. show me the code. 直方图均衡化目的 由于一些图像灰度的分布过于集中,这样会导致 ...
- Win8 Metro(C#)数字图像处理--3.3图像直方图计算
原文:Win8 Metro(C#)数字图像处理--3.3图像直方图计算 /// <summary> /// Get the array of histrgram. /// </sum ...
- Win8Metro(C#)数字图像处理--2.34直方图规定化
原文:Win8Metro(C#)数字图像处理--2.34直方图规定化 [函数名称] WriteableBitmap HistogramSpecificateProcess(WriteableBi ...
- Win8Metro(C#)数字图像处理--2.30直方图均衡化
原文:Win8Metro(C#)数字图像处理--2.30直方图均衡化 [函数名称] 直方图均衡化函数HistogramEqualProcess(WriteableBitmap src) [算法说明] ...
- FPGA与数字图像处理技术
数字图像处理方法的重要性源于两个主要应用领域: 改善图像信息以便解释. 为存储.传输和表示而对图像数据进行处理,以便于机器自动理解. 图像处理(image processing): 用计算机对图像进行 ...
- 数字图像处理:基于MATLAB的车牌识别项目 标签: 图像处理matlab算法 2017-06-24 09:17 98人阅读 评论(0)
学过了数字图像处理,就进行一个综合性强的小项目来巩固一下知识吧.前阵子编写调试了一套基于MATLAB的车牌识别的项目的代码.今天又重新改进了一下代码,识别的效果好一点了,也精简了一些代码.这里没有使用 ...
- FPGA经典:Verilog传奇与基于FPGA的数字图像处理原理及应用
一 简述 最近恶补基础知识,借了<<Verilog传奇>>,<基于FPGA的嵌入式图像处理系统设计>和<<基千FPGA的数字图像处理原理及应用>& ...
- 数字图像处理的Matlab实现(4)—灰度变换与空间滤波
第3章 灰度变换与空间滤波(2) 3.3 直方图处理与函数绘图 基于从图像亮度直方图中提取的信息的亮度变换函数,在诸如增强.压缩.分割.描述等方面的图像处理中扮演着基础性的角色.本节的重点在于获取.绘 ...
- 数字图像处理实验(总计23个)汇总 标签: 图像处理MATLAB 2017-05-31 10:30 175人阅读 评论(0)
以下这些实验中的代码全部是我自己编写调试通过的,到此,最后进行一下汇总. 数字图像处理实验(1):PROJECT 02-01, Image Printing Program Based on Half ...
随机推荐
- dotnet 通过 WMI 获取系统安装的驱动
本文告诉大家如何通过 WMI 获取用户已经安装的驱动程序 通过 Win32_SystemDriver 可以获取用户已经安装的驱动程序 var mc = "Win32_SystemDriver ...
- 在网上找到的一些Java封装的utils类
这是网址:https://github.com/hanyunpeng0521/utils
- 聊聊多线程哪一些事儿(task)之 一
多线程,一个多么熟悉的词汇,作为一名程序员,我相信无论是从事什么开发语言,都能够轻轻松松说出几种实现多线程的方式,并且在实际工作种也一定用到过多线程,比如:定时器.异步作业等等,如果你说你没有用过多线 ...
- spring-redis-session 自定义 key 和过期时间
对于分布式应用来说,最开始遇到的问题就是 session 的存储了,解决方案大致有如下几种 使用 spring-session 它可以把 session 存储到你想存储的位置,如 redis,mysq ...
- CentOS 下 git 401 Unauthorized while accessing 问题解决
The requested URL returned error: 401 Unauthorized while accessing 这个一般是旧版git的问题,需要安装新版的.CentOS 想下载最 ...
- k8s集群———etcd-三节点部署
etcd集群部署 ,创建etcd可执行文件,配置文件,证书文件存放目录 mkdir /opt/etcd/{bin,cfg,ssl} -p ,创建包文件存放目录 mkdir /soft -p ,解压et ...
- Q: 字符串的修改
题目描述 怎么样,前面的题还可以吧~ 依旧是字符串处理,设A和B是两个字符串.我们要用最少的字符操作次数,将字符串A转换为字符串B.这里所说的字符操作共有三种: 1. 删除一个字符: 2. 插入一个字 ...
- [gitHub实践] git基础:远程仓库的使用
[gitHub实践] git基础:远程仓库的使用 版权2019.6.2更新 git 基础 远程仓库的使用 git remote # 查看远程仓库 $ git remote # 克隆的仓库服务器默认名字 ...
- Excel如何快速选定指定区域
在日常办公中我们经常遇见需要选中指定的区域,这样选种比较快捷节省时间,要比用鼠标下拉要方便很多. 1.框选的是起始的位置(A1) 2.终止位置 3.这就是我们所要选中的区域例如(A1:H21) 总结: ...
- Android系统启动过程分析
Android系统启动过程分析 一.Android平台架构 首先贴一张Android系统架构图方便理解整个Android架构,这可以让我们从整体上对整个启动流程有个大概认知. 可以看出整个架构由5部分 ...