matlab将二值图像与原图重叠_MATLAB--数字图像处理 图像直方图规定化
发布日期:2021-06-24 15:56:33 浏览次数:2 分类:技术文章

本文共 2635 字,大约阅读时间需要 8 分钟。

ce274168507ecc686b14be80cae7cddc.png

直方图规定化

原理

所谓直方图规定化,就是通过一个灰度映像函数,将原灰度直方图改造成所希望的直方图。说的通俗一点就是,原图像的灰度是从0~255的,其分布是随机的,在一些情况下,我们可能需要一些特定的灰度值,比如我们只需要灰度值为0 3 40 240 255 这些值,除此之外的灰度值我们不需要,那么从原图像到我们需要的图像就可以理解成图像的规定化。

具体事例

左图是原图像的灰度直方图,右图是我们需要的图(这里的需要是指需要灰度由原来的0~7变成规定的1 3 6,规定化后图像的纵坐标是会变的,这里只需要横坐标吻合就行!)

7105533b6ed8788a2615f0ffceb52027.png

规定化后的图像(横坐标和规定一样,纵坐标是会变化的):

2bc01c77fc148d201d91ca9599ecfbb1.png

实现步骤:

  1. 分别计算出原图像和规定图像的累加直方图
  2. 利用SML或者GML映射灰度值
  3. 利用更新后的映射表转换原图像的灰度值

看完之后,应该还是不懂?那么直接实战一题!题目见下图:

f0bdfcbc25b6970cf98ec9d7d7ebf368.png

解题步骤:

  1. 这里是直接给出的原图像各灰度的像素个数,为了得到我们需要的直方累加图(其实是概率累加值,当然也可以不用概率,直接用像素点数也行,就是看起来数字比较大),需要先算出原图像各灰度的概率(占总像素个数的比例),然后在计算累加值

a7a3fede93eca77ab6c4fc026a47ffc4.png
  1. 根据给出的规定直方图,同样的方法计算累加直方图,见下图

cdd95acc7020fc5d5423ad371459dfd0.png
  1. 利用SML映射规则得出结果

a3debfdb97c2582c35cf3d0d72751601.png
  1. 利用映射变化表,更新原图像

提示

这里可能不懂SML映射规则,我说说自己简单的理解(自己也可以自行百度):

SML就是单映射,这里我们关注原图累加直方图和规定累加直方图,所谓SML,就是从原图累加直方图开始,在规定累加直方图寻找和自己最接近的值,然后把它的灰度值变成自己的。具体来说,原图第一个累加概率是0.19,在规定累加直方图中,最接近它的就是0.15,那么原图的灰度0变成规定的3,第二个累加概率是0.44,最接近规定累加直方图的0.35,所以由1变成4,同理,依次遍历完原图累加直方图的概率就行,在规定累加直方图找到最靠近自己的值,最后进行灰度变化。

SML规则懂了,GML规则也就好理解了(GML规则其实编程更难):

SML中,我们是依次遍历原图累加直方图,在规定累加直方图寻找最靠近自己的。在GML(组映射)中,就变成了依次从规定累加直方图中,对比原图累加直方图,也是找到最靠近的值,进行灰度变换,只是这里的变换规则变了。

38f023da49639daff9647c3cd0b963b8.png

具体举例来说,从上图看,这里我们这里从规定累加直方图的0.15看,前面的0其实不用看,再从原始累加直方图找到最接近0.15的值,是0.19,那么0.19对应和它对应灰度值前面的灰度变成规定累加直方图中0.15所对应的灰度值:3;第二个看规定累加直方图的0.35,靠近原图的0.44,那么原图的1变成4(假设这里0.44对应的原图灰度值为4,那么在前一个不为0和4之间变成4)
这里有的不好理解,举个例子:
原数组:1 0 0 2 0 3 0 0 0 4 0 0 6
GML映射变化规则的目标数组就是:1 2 2 2 3 3 4 4 4 4 6 6 6
解释:1前面的数变为1,1和2之间变成2,2和3之间变成3,3和4之间变成4,4和6之间变成6,简单的说就是变0变成后面最靠近的一个不为0的数。(这里算法自己需要掌握,即如何从原数组变成目标数组,这里先给个C++的验证算法)

#include
using namespace std;int main(){ int t[8]={2,0,1,0,3,0,0,6}; int i,j; int tem; int flag=0; for (i=0;i<8;i++) { if(t[i]==0) { for(j=i;j<8;j++) { if(t[j]!=0) { tem=t[j]; break;} } t[i]=tem; } }for(i=0;i<8;i++)cout<
<<" ";return 0;}

如果还是不懂SML和GML规则的话?那自己根据下面两种图片再理解理解吧。

abfae956fcb23dc196a74d1996fad18d.png

d7fe1686f3e0201fb54f9b67a4d38878.png

MATLAB实战

原理懂了,肯定就是要开始实战了啊!
这里我先上全部代码:

t=imread('a1.jpg')%获取图片的长和宽,用于计算总像素,即m*n[m,n]=size(t);%n_1 这里是先统计各灰度的像素数,后面会变换为概率n_1=zeros(1,256);%统计各灰度的像素数for i=1:mfor j=1:nn_1(t(i,j)+1)=n_1(t(i,j)+1)+1;endend%转换为概率n_1=n_1/m/n; %计算各个灰度级的概率%p_1  记录原图的累积直方图概率p_1=zeros(1,256);%p_1 计算原始累积直方图的概率for i=1:256for j=1:ip_1(i)=p_1(i)+n_1(j);endend%n_2  规定直方图的灰度概率分布n_2=[zeros(1,50),0.1,zeros(1,50),0.2,zeros(1,50),0.3,zeros(1,50),0.2,zeros(1,20),0.1,zeros(1,30),0.1];%p_2 记录规定直方图的累积概率p_2=zeros(1,256);% 计算规定直方图累积概率for i=1:256for j=1:ip_2(i)=p_2(i)+n_2(j);endend%SML映射算法data_1=zeros(1,256);%data_1 SML映射表for i=1:256min=abs(p_1(i)-p_2(1));for j=2:256if  abs(p_1(i)-p_2(j))

效果图:

aecb8a9d49836ca7fe7946a5c29c24da.png

总结

SML、GML两个算法用来一天才搞清楚原理,书上的公式开始看真的是好难啊,看不进去,网上的方法,真的是,没有自己想要的。算法其实一天就搞定了,当时由于MATLAB语法还不是很熟,走了很多弯路。下面总结下自己的踩坑吧:

  • MATLAB里面的循环写法 for i=1:256 c++:for(i=1;i<=256;i++)
  • for、if等用end结束,end个数必须和if、for配对,比如,3个for,2个if,就必须有5个end结束,不然程序会一直执行下去
  • 程序语句最后有无 ; 的区别:写了 ; 本地代码区不会显示具体数据,反之不写,则会显示,建议还是写吧,和c++语法类似。
  • 多打印数据,一步一步调试,便于寻找bug

e9f96db9c65fe3d71da44782875cb38b.png

转载地址:https://blog.csdn.net/weixin_33682804/article/details/112339073 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:ptp输出内容包含什么_免费小程序开发包含哪些内容,相对APP有什么优势
下一篇:缺失magisk正常工作所需的文件_总结了十个工作表看上去很凌乱的原因

发表评论

最新留言

路过按个爪印,很不错,赞一个!
[***.219.124.196]2024年04月17日 05时36分40秒