直方图匹配,又称直方图规定化,即变换原图的直方图为规定的某种形式的直方图,从而使两幅图像具有类似的色调和反差。直方图匹配属于非线性点运算。

直方图规定化的原理:对两个直方图都做均衡化,变成相同的归一化的均匀直方图,以此均匀直方图为媒介,再对参考图像做均衡化的逆运算

     /// <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#数字图像处理(七)直方图匹配的更多相关文章

  1. OpenCV-跟我一起学数字图像处理之直方图均衡化

    从这篇博文开始,小生正式从一个毫不相干专业转投数字图像处理.废话不多说了,talk is cheap. show me the code. 直方图均衡化目的 由于一些图像灰度的分布过于集中,这样会导致 ...

  2. Win8 Metro(C#)数字图像处理--3.3图像直方图计算

    原文:Win8 Metro(C#)数字图像处理--3.3图像直方图计算 /// <summary> /// Get the array of histrgram. /// </sum ...

  3. Win8Metro(C#)数字图像处理--2.34直方图规定化

    原文:Win8Metro(C#)数字图像处理--2.34直方图规定化  [函数名称] WriteableBitmap HistogramSpecificateProcess(WriteableBi ...

  4. Win8Metro(C#)数字图像处理--2.30直方图均衡化

    原文:Win8Metro(C#)数字图像处理--2.30直方图均衡化 [函数名称] 直方图均衡化函数HistogramEqualProcess(WriteableBitmap src) [算法说明] ...

  5. FPGA与数字图像处理技术

    数字图像处理方法的重要性源于两个主要应用领域: 改善图像信息以便解释. 为存储.传输和表示而对图像数据进行处理,以便于机器自动理解. 图像处理(image processing): 用计算机对图像进行 ...

  6. 数字图像处理:基于MATLAB的车牌识别项目 标签: 图像处理matlab算法 2017-06-24 09:17 98人阅读 评论(0)

    学过了数字图像处理,就进行一个综合性强的小项目来巩固一下知识吧.前阵子编写调试了一套基于MATLAB的车牌识别的项目的代码.今天又重新改进了一下代码,识别的效果好一点了,也精简了一些代码.这里没有使用 ...

  7. FPGA经典:Verilog传奇与基于FPGA的数字图像处理原理及应用

    一 简述 最近恶补基础知识,借了<<Verilog传奇>>,<基于FPGA的嵌入式图像处理系统设计>和<<基千FPGA的数字图像处理原理及应用>& ...

  8. 数字图像处理的Matlab实现(4)—灰度变换与空间滤波

    第3章 灰度变换与空间滤波(2) 3.3 直方图处理与函数绘图 基于从图像亮度直方图中提取的信息的亮度变换函数,在诸如增强.压缩.分割.描述等方面的图像处理中扮演着基础性的角色.本节的重点在于获取.绘 ...

  9. 数字图像处理实验(总计23个)汇总 标签: 图像处理MATLAB 2017-05-31 10:30 175人阅读 评论(0)

    以下这些实验中的代码全部是我自己编写调试通过的,到此,最后进行一下汇总. 数字图像处理实验(1):PROJECT 02-01, Image Printing Program Based on Half ...

随机推荐

  1. onload事件属性,JQ中的load,ready方法

    onload事件属性,JQ中的load,ready方法 前言 页面中的很多操作,需要我们在所需资源下载完成后,才可以进行操作,而资源没有及时下载,我们进行操作的话,是会报错.因此我们需要熟练掌握哪些事 ...

  2. <Standard Template Library>标准模板库专项复习总结(一)

    看了看博客园的申请时间也一年多了...想想自己一年多以来一直处于各种划水状态,现在又要面临ACM的冲击... 还是要抓紧时间赶紧复习一下了- -毕竟校园新生赛还是有奖金的.. 1.栈 先进后出(LIF ...

  3. Windows 服务安装与卸载 (通过 Sc.exe)

    1. 安装 新建文本文件,重命名为 ServiceInstall.bat,将 ServiceInstall.bat 的内容替换为: sc create "Verity Platform De ...

  4. AS优化

    第一步:打开AS安装所在的位置,用记事本打开“红色框”选中的文件. 如图: 第二步:打开“studio64.exe.vmoptions”文件后修改里面的值,修改后如下: 1 2 3 4 5 6 7 8 ...

  5. 35.python之事件驱动模型

    转载:https://www.cnblogs.com/yuanchenqi/articles/5722574.html 事件驱动模型 上节的问题: 协程:遇到IO操作就切换. 但什么时候切回去呢?怎么 ...

  6. iptables详细参数讲解

    table 表 --> chain 链 --->rule 规则Commands:Either long or short options are allowed. --append -A ...

  7. 洛谷$P2153\ [SDOI2009]$ 晨跑 网络流

    正解:网络流 解题报告: 传送门$QwQ$ 题目好长昂,,,大概概括下$QwQ$.就说有$n$个节点$m$条边,然后要求每次走的路径都不一样,问最多能走多少次,然后在次数最多的前提下问路径最短是多少$ ...

  8. python接口自动化测试-unittest-生成测试报告

    用例的管理问题解决了后,接下来要考虑的就是报告我问题了,这里生成测试报告主要用到 HTMLTestRunner.py 这个模块,下面简单介绍一下如何使用: 一.下载HTMLTestRunner下载: ...

  9. JDK1.8中的HashMap实现

    1.HashMap概述 在JDK1.8之前,HashMap采用数组+链表实现,即使用链表处理冲突,同一hash值的节点都存储在一个链表里.但是当位于一个桶中的元素较多,即hash值相等的元素较多时,通 ...

  10. 「CodeForces 546B」Soldier and Badges 解题报告

    CF546B Soldier and Badges 题意翻译 给 n 个数,每次操作可以将一个数 +1,要使这 n 个数都不相同, 求最少要加多少? \(1 \le n \le 3000\) 感谢@凉 ...