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

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

  1.     /// <summary>
  2. /// 直方图匹配
  3. /// </summary>
  4. /// <param name="srcBmp">原始图像</param>
  5. /// <param name="matchingBmp">匹配图像</param>
  6. /// <param name="dstBmp">处理后图像</param>
  7. /// <returns>处理成功 true 失败 false</returns>
  8. public static bool HistogramMatching(Bitmap srcBmp, Bitmap matchingBmp, out Bitmap dstBmp)
  9. {
  10. if (srcBmp == null || matchingBmp == null)
  11. {
  12. dstBmp = null;
  13. return false;
  14. }
  15. dstBmp = new Bitmap(srcBmp);
  16. Bitmap tempSrcBmp = new Bitmap(srcBmp);
  17. Bitmap tempMatchingBmp = new Bitmap(matchingBmp);
  18. double[] srcCpR = null;
  19. double[] srcCpG = null;
  20. double[] srcCpB = null;
  21. double[] matchCpB = null;
  22. double[] matchCpG = null;
  23. double[] matchCpR = null;
  24. //分别计算两幅图像的累计概率分布
  25. getCumulativeProbabilityRGB(tempSrcBmp, out srcCpR, out srcCpG, out srcCpB);
  26. getCumulativeProbabilityRGB(tempMatchingBmp, out matchCpR, out matchCpG, out matchCpB);
  27.  
  28. double diffAR = , diffBR = , diffAG = , diffBG = , diffAB = , diffBB = ;
  29. byte kR = , kG = , kB = ;
  30. //逆映射函数
  31. byte[] mapPixelR = new byte[];
  32. byte[] mapPixelG = new byte[];
  33. byte[] mapPixelB = new byte[];
  34. //分别计算RGB三个分量的逆映射函数
  35. //R
  36. for (int i = ; i < ; i++)
  37. {
  38. diffBR = ;
  39. for (int j = kR; j < ; j++)
  40. {
  41. //找到两个累计分布函数中最相似的位置
  42. diffAR = Math.Abs(srcCpR[i] - matchCpR[j]);
  43. if (diffAR - diffBR < 1.0E-08)
  44. {//当两概率之差小于0.000000001时可近似认为相等
  45. diffBR = diffAR;
  46. //记录下此时的灰度级
  47. kR = (byte)j;
  48. }
  49. else
  50. {
  51. kR = (byte)Math.Abs(j - );
  52. break;
  53. }
  54. }
  55. if (kR == )
  56. {
  57. for (int l = i; l < ; l++)
  58. {
  59. mapPixelR[l] = kR;
  60. }
  61. break;
  62. }
  63. mapPixelR[i] = kR;
  64. }
  65. //G
  66. for (int i = ; i < ; i++)
  67. {
  68. diffBG = ;
  69. for (int j = kG; j < ; j++)
  70. {
  71. diffAG = Math.Abs(srcCpG[i] - matchCpG[j]);
  72. if (diffAG - diffBG < 1.0E-08)
  73. {
  74. diffBG = diffAG;
  75. kG = (byte)j;
  76. }
  77. else
  78. {
  79. kG = (byte)Math.Abs(j - );
  80. break;
  81. }
  82. }
  83. if (kG == )
  84. {
  85. for (int l = i; l < ; l++)
  86. {
  87. mapPixelG[l] = kG;
  88. }
  89. break;
  90. }
  91. mapPixelG[i] = kG;
  92. }
  93. //B
  94. for (int i = ; i < ; i++)
  95. {
  96. diffBB = ;
  97. for (int j = kB; j < ; j++)
  98. {
  99. diffAB = Math.Abs(srcCpB[i] - matchCpB[j]);
  100. if (diffAB - diffBB < 1.0E-08)
  101. {
  102. diffBB = diffAB;
  103. kB = (byte)j;
  104. }
  105. else
  106. {
  107. kB = (byte)Math.Abs(j - );
  108. break;
  109. }
  110. }
  111. if (kB == )
  112. {
  113. for (int l = i; l < ; l++)
  114. {
  115. mapPixelB[l] = kB;
  116. }
  117. break;
  118. }
  119. mapPixelB[i] = kB;
  120. }
  121. //映射变换
  122. BitmapData bmpData = dstBmp.LockBits(new Rectangle(, , dstBmp.Width, dstBmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
  123. unsafe
  124. {
  125. byte* ptr = null;
  126. for (int i = ; i < dstBmp.Height; i++)
  127. {
  128. ptr = (byte*)bmpData.Scan0 + i * bmpData.Stride;
  129. for (int j = ; j < dstBmp.Width; j++)
  130. {
  131. ptr[j * + ] = mapPixelR[ptr[j * + ]];
  132. ptr[j * + ] = mapPixelG[ptr[j * + ]];
  133. ptr[j * ] = mapPixelB[ptr[j * ]];
  134. }
  135. }
  136. }
  137. dstBmp.UnlockBits(bmpData);
  138. return true;
  139. }
  140.  
  141. /// <summary>
  142. /// 计算各个图像分量的累计概率分布
  143. /// </summary>
  144. /// <param name="srcBmp">原始图像</param>
  145. /// <param name="cpR">R分量累计概率分布</param>
  146. /// <param name="cpG">G分量累计概率分布</param>
  147. /// <param name="cpB">B分量累计概率分布</param>
  148. private static void getCumulativeProbabilityRGB(Bitmap srcBmp, out double[] cpR, out double[] cpG, out double[] cpB)
  149. {
  150. if (srcBmp == null)
  151. {
  152. cpB = cpG = cpR = null;
  153. return;
  154. }
  155. cpR = new double[];
  156. cpG = new double[];
  157. cpB = new double[];
  158. int[] hR = null;
  159. int[] hG = null;
  160. int[] hB = null;
  161. double[] tempR = new double[];
  162. double[] tempG = new double[];
  163. double[] tempB = new double[];
  164. getHistogramRGB(srcBmp, out hR, out hG, out hB);
  165. int totalPxl = srcBmp.Width * srcBmp.Height;
  166. for (int i = ; i < ; i++)
  167. {
  168. if (i != )
  169. {
  170. tempR[i] = tempR[i - ] + hR[i];
  171. tempG[i] = tempG[i - ] + hG[i];
  172. tempB[i] = tempB[i - ] + hB[i];
  173. }
  174. else
  175. {
  176. tempR[] = hR[];
  177. tempG[] = hG[];
  178. tempB[] = hB[];
  179. }
  180. cpR[i] = (tempR[i] / totalPxl);
  181. cpG[i] = (tempG[i] / totalPxl);
  182. cpB[i] = (tempB[i] / totalPxl);
  183. }
  184. }
  185.  
  186. /// <summary>
  187. /// 获取图像三个分量的直方图数据
  188. /// </summary>
  189. /// <param name="srcBmp">图像</param>
  190. /// <param name="hR">R分量直方图数据</param>
  191. /// <param name="hG">G分量直方图数据</param>
  192. /// <param name="hB">B分量直方图数据</param>
  193. public static void getHistogramRGB(Bitmap srcBmp, out int[] hR, out int[] hG, out int[] hB)
  194. {
  195. if (srcBmp == null)
  196. {
  197. hR = hB = hG = null;
  198. return;
  199. }
  200. hR = new int[];
  201. hB = new int[];
  202. hG = new int[];
  203. BitmapData bmpData = srcBmp.LockBits(new Rectangle(, , srcBmp.Width, srcBmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
  204. unsafe
  205. {
  206. byte* ptr = null;
  207. for (int i = ; i < srcBmp.Height; i++)
  208. {
  209. ptr = (byte*)bmpData.Scan0 + i * bmpData.Stride;
  210. for (int j = ; j < srcBmp.Width; j++)
  211. {
  212. hB[ptr[j * ]]++;
  213. hG[ptr[j * + ]]++;
  214. hR[ptr[j * + ]]++;
  215. }
  216. }
  217. }
  218. srcBmp.UnlockBits(bmpData);
  219. return;
  220. }

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. dotnet 通过 WMI 获取系统安装的驱动

    本文告诉大家如何通过 WMI 获取用户已经安装的驱动程序 通过 Win32_SystemDriver 可以获取用户已经安装的驱动程序 var mc = "Win32_SystemDriver ...

  2. 在网上找到的一些Java封装的utils类

    这是网址:https://github.com/hanyunpeng0521/utils

  3. 聊聊多线程哪一些事儿(task)之 一

    多线程,一个多么熟悉的词汇,作为一名程序员,我相信无论是从事什么开发语言,都能够轻轻松松说出几种实现多线程的方式,并且在实际工作种也一定用到过多线程,比如:定时器.异步作业等等,如果你说你没有用过多线 ...

  4. spring-redis-session 自定义 key 和过期时间

    对于分布式应用来说,最开始遇到的问题就是 session 的存储了,解决方案大致有如下几种 使用 spring-session 它可以把 session 存储到你想存储的位置,如 redis,mysq ...

  5. CentOS 下 git 401 Unauthorized while accessing 问题解决

    The requested URL returned error: 401 Unauthorized while accessing 这个一般是旧版git的问题,需要安装新版的.CentOS 想下载最 ...

  6. k8s集群———etcd-三节点部署

    etcd集群部署 ,创建etcd可执行文件,配置文件,证书文件存放目录 mkdir /opt/etcd/{bin,cfg,ssl} -p ,创建包文件存放目录 mkdir /soft -p ,解压et ...

  7. Q: 字符串的修改

    题目描述 怎么样,前面的题还可以吧~ 依旧是字符串处理,设A和B是两个字符串.我们要用最少的字符操作次数,将字符串A转换为字符串B.这里所说的字符操作共有三种: 1. 删除一个字符: 2. 插入一个字 ...

  8. [gitHub实践] git基础:远程仓库的使用

    [gitHub实践] git基础:远程仓库的使用 版权2019.6.2更新 git 基础 远程仓库的使用 git remote # 查看远程仓库 $ git remote # 克隆的仓库服务器默认名字 ...

  9. Excel如何快速选定指定区域

    在日常办公中我们经常遇见需要选中指定的区域,这样选种比较快捷节省时间,要比用鼠标下拉要方便很多. 1.框选的是起始的位置(A1) 2.终止位置 3.这就是我们所要选中的区域例如(A1:H21) 总结: ...

  10. Android系统启动过程分析

    Android系统启动过程分析 一.Android平台架构 首先贴一张Android系统架构图方便理解整个Android架构,这可以让我们从整体上对整个启动流程有个大概认知. 可以看出整个架构由5部分 ...