2018-04-24 11:40:18 u010936286 阅读数 398
  • Matplotlib 数据分析可视化

    数据分析三剑客,NumPy、Pandas、Matplotlib,本课程是对Matplotlib的讲解,Matplotlib可以是分析的数据可视化,可以更直观的查看数据分析的结果,本课程独辟蹊径,不光教大家如何绘图,例如:饼图、柱状图、条形图、直方图等,而且深入剖析的Matplotlib的绘图原理,例如:如何操作图片,如何加载本地数据等。

    15364 人正在学习 去看看 郭宏志

图像的直方图

图像的直方图处理是从概率统计的角度出发,对图像灰度级的概率分布进行变换,从而达到使图像细节丰富、动态范围较大、便于观测和理解的目的。

直方图处理是多种空间域处理技术的基础,可以直接用于图像的增强以及图像的压缩和分割。在灰度级范围为[0,L-1]的数字图像的直方图可以表示为:


其中rk是第k级灰度值,nk是图像中灰度为rk的像素的个数,MN分别是图像的行和列数。

我们首先对下列图像进行观测。我们可以看到,在亮图像中,直方图的分量集中在灰度级的高端,而在暗图像中,中直方图的分量倾向于灰度级的低端。低对比度的图像具有较窄的直方图,且集中于灰度级的中部。对于单色图像,这就意味着暗淡,好像灰度被冲淡了一样。而高对比度的图像的直方图的分量覆盖了很宽的灰度级范围,而且像素的分布比较均匀。因此,若一幅图像的像素倾向于占据整个可能的灰度级并且分布均匀,那么该图像会有高对比度的外观并展示灰色调的较大变化。最终效果将是一幅灰度细节丰富且动态范围较大的图像。


下面是图像直方图绘制的Matlab程序,其中numel(image)是求取图像的M×N的值,imhist是求取图像的直方图,这里进行了归一化处理,使每个值处于[0,1]范围内。bar()用于显示直方图。

clear
clc
%%读取图像数据
Cells_bright=imread('细胞亮.jpg');
Cells_dark=imread('细胞暗.jpg');
Cells_low_contrast=imread('细胞低对比度.jpg');
Cells_hight_contrast=imread('细胞高对比度.jpg');

%%灰度化
Cells_bright_gray=rgb2gray(Cells_bright);
Cells_dark_gray=rgb2gray(Cells_dark);
Cells_low_contrast_gray=rgb2gray(Cells_low_contrast);
Cells_hight_contrast_gray=rgb2gray(Cells_hight_contrast);

%%求直方图
h_bright         =imhist(Cells_bright_gray)/numel(Cells_bright_gray);
h_dark           =imhist(Cells_dark_gray)/numel(Cells_dark_gray);
h_low_contrast   =imhist(Cells_low_contrast_gray)/numel(Cells_low_contrast_gray);
h_hight_contrast =imhist(Cells_hight_contrast_gray)/numel(Cells_hight_contrast_gray);

%%绘制直方图
h=0:255;
figure(1)
subplot(1,2,1)
imshow(Cells_bright)
title('细胞亮')
subplot(1,2,2)
bar(h,h_bright);
title('直方图')
axis([0,255,0,0.1])

figure(2)
subplot(1,2,1)
imshow(Cells_dark_gray)
title('细胞暗')
subplot(1,2,2)
bar(h,h_dark);
title('直方图')
axis([0,255,0,0.1])

figure(3)
subplot(1,2,1)
imshow(Cells_low_contrast_gray)
title('细胞低对比度')
subplot(1,2,2)
bar(h,h_low_contrast);
title('直方图')
axis([0,255,0,0.1])

figure(4)
subplot(1,2,1)
imshow(Cells_hight_contrast_gray)
title('细胞高对比度')
subplot(1,2,2)
bar(h,h_hight_contrast);
title('直方图')
axis([0,255,0,0.1])

图像的直方图均衡




注意,我们的目的是为了使图像的直方图分量覆盖整个灰度级且分布均匀,因此其等价于使得Ps(s)的直方图分布律为:


因此利用上述两个公式可以得到:



可以看到,变换后的图像的直方图概率分布为均匀分布。

对于离散的数字图像可以通过下式进行变换。


下面是原书中给的一个例子:


下面我们以图像“细胞亮”为实例,通过Matlab实现图像的均衡。这里的histeq可以实现对原图像的直方图均衡。我们可以看到,直方图均衡后的图像显示了更多细节,且直方图分量分布更加均匀。

%%直方图均衡
hist_equilibrium=histeq(Cells_bright_gray);

%%直方图
Image_equilibrium_hist=imhist(hist_equilibrium)/numel(hist_equilibrium);
%%绘制直方图均衡后图像
figure(5)
subplot(1,2,1)
imshow(g)
title('细胞亮直方图均衡后的图片')
subplot(1,2,2)
bar(h,Image_equilibrium_hist);
title('直方图')
axis([0,255,0,0.1])

直方图规定化

上述我们实现了对某张图像进行直方图均衡,使图像的直方图分量分布均匀。但是有时对图像进行直方图均衡效果不佳。例如:

clear
clc
%%读取图像数据
Mars=imread('火星.jpg');

%%灰度化
Mars_gray=rgb2gray(Mars);

%%直方图
h=0:255;
h_Mars=imhist(Mars_gray)/numel(Mars_gray);
figure(1)
subplot(1,2,1)
imshow(Mars_gray)
title('火星灰度图')
subplot(1,2,2)
bar(h,h_Mars);
title('直方图')
axis([0,255,0,1])

%%直方图均衡
hist_equilibrium=histeq(Mars_gray);
Mars_equilibrium_hist=imhist(hist_equilibrium)/numel(hist_equilibrium);
figure(2)
subplot(1,2,1)
imshow(hist_equilibrium)
title('火星直方图均衡')
subplot(1,2,2)
bar(h,Mars_equilibrium_hist);
title('直方图')
axis([0,255,0,1])
如图显示了火星卫星(Phobos)的图像,图像中的大部分是暗色区域,如果我们采用直方图均衡的方式进行图像增强,会使得把非常窄的暗像素区域映射到输出图像灰度级的高端。直方图的规定化就是解决这类问题。

直方图的规定化可以理解为指定一种直方图分布律(自己可以根据实际需要设计),将原图像的直方图分布变换为我们规定的分布律。其实现方式也是显而易见的,由于直方图均衡是一一对应的结果,因此原图像可以通过直方图均衡由P(r)→P(s)(再次强调是一一对应的),同理,我们设计的直方图分布律也可以进行直方图均衡P(z)→P(s),而由于直方图均衡的一一对应的特性,我们可以找到这样的映射:P(s)→P(z)。因此我们可以通过这样的路线实现直方图规定化。

(1)P(r)→P(s)

(2)P(z)→P(s),P(s)→P(z)

(3)P(r)→P(s)→P(z)

下面是原书中的示例:


下面我们对上述火星卫星图像进行直方图规定化操作:

%%指定直方图分布律
p(1:100)=-16/50/50*(h(1:100)-50).^2+18;
p(101:256)=2;
p=p/sum(p);
figure(3)
plot(h,p);
title('指定的直方图')

%%直方图匹配
hist_matching=histeq(Mars_gray,p);
Mars_matching_hist=imhist(hist_matching)/numel(hist_matching);
figure(4)
subplot(1,2,1)
imshow(hist_matching)
title('火星直方图匹配')
subplot(1,2,2)
bar(h,Mars_matching_hist);
title('直方图')
axis([0,255,0,1])

我们可以看到直方图规定化具有较好的效果。

局部直方图均衡

局部直方图均衡是为了解决在全局处理情况下使得图像大面积引入噪声的问题。例如下图所示。这里可以通过在某个局部邻域内进行均衡操作。具体代码可以参考后面讲解的直方图统计进行局部修改。


直方图统计

直方图统计的方式增强图像是借助图像中的数据的统计量进行分析计算。例如图像的平均值和二阶矩(方差)等统计量。

图像的取样均值可以表示为:


方差可以表示为:


其中均值表示了图像整体的明暗程度,方差可以理解为图像中的对比度。

例如下面是一幅放大了约130倍钨丝的SME图像,可以看到图像中央的钨丝及其支架可以很清楚并容易的分析,然而图像的右侧存在的另一根钨丝的结构由于过暗而不宜观测。倘若我们希望图像中央钨丝结构不变,仅仅对暗区纹理部分进行增强,而图像的全局均衡化虽然对暗区进行了增强,却影响了中央钨丝的区域。这时我们可以通过图像的直方图统计的方式实现。

clear
clc
%%读取图像数据
Tungsten=imread('放大约130倍钨丝的SME图像.jpg');

%%灰度化
Tungsten_gray=rgb2gray(Tungsten);

%%直方图
h=0:255;
h_Tungsten=imhist(Tungsten_gray)/numel(Tungsten_gray);
%%绘制直方图
figure(1)
subplot(1,2,1)
imshow(Tungsten_gray)
title('放大约130倍钨丝的SME图像')
subplot(1,2,2)
bar(h,h_Tungsten);
title('直方图')
axis([0,255,0,0.1])

%%全局直方图均衡
hist_equilibrium=histeq(Tungsten_gray);
Tungsten_equilibrium_hist=imhist(hist_equilibrium)/numel(hist_equilibrium);
figure(2)
subplot(1,2,1)
imshow(hist_equilibrium)
title('全局直方图均衡')
subplot(1,2,2)
bar(h,Tungsten_equilibrium_hist);
title('直方图')
axis([0,255,0,1])


具体做法如下,首先取某个大小为n×n的邻域,求取其均值和标准差,若其均值小于平均值的k0倍,则说明该区域过暗,可以表示为:

若考虑该区域的对比度,则通过以下公式:

K2>1则表示增强亮区域,若k2<1则表示增强暗区域。
当然,我们需要限制能够接受的最低的对比度值,否则该过程会试图增强标准差为0的恒定区域。

对于满足上述所有条件的区域,可以通过将该像素值乘以指定常数E来处理,以便增强或减小该区域灰度值。

因此,综上所述,我们可以表示为:


下面对上述钨丝图进行操作:

首先求取全局均值和标准差,其次设置k0、k1、k2和E,设置邻域范围为n=3。这里的wextend()用于扩展图像,否则图像的边缘点,如点(1,1)无法得到计算。然后根据上述公式进行计算。可以看到通过直方图统计的方式增强了图像右侧的暗区域。

%%直方图统计
Tungsten_gray=double(Tungsten_gray);    %格式转化,便于后期计算
Tungsten_mean_G =mean(Tungsten_gray(:));  %全局平均值
k0=0.25;
Tungsten_std_G=std(Tungsten_gray(:));   %全局标准差
k2=0.4;
k1=0.02;
E=4.0;
if k1>=k2
    disp(['输入错误,k1>k2'])
end

n=3;    %局部均衡邻域范围
st=floor(n/2);           %以像素所在位置为(2,2)为例,其邻域为[1:3,1:3]。
image_extend=wextend('2D','sym',Tungsten_gray,n);%%扩展
Tungsten_result=Tungsten_gray;              %用于得到结果
[row,col]=size(image_extend);              %扩展后的图像大小
for i=1+n:row-n
    for j=1+n:col-n
        img_temp=image_extend(i-st:i+st,j-st:j+st);   %获取像素(i,j)的邻域
        img_temp_mean=mean(img_temp(:));         %求局部均值
        img_temp_std=std(img_temp(:));           %求局部标准差
        if img_temp_mean<=k0*Tungsten_mean_G && img_temp_std<=k2*Tungsten_std_G &&img_temp_std>=k1*Tungsten_std_G;
            Tungsten_result(i-n,j-n)=img_temp(st+1,st+1)*E;  %将该像素增强E倍
        end
        
    end
end
Tungsten_result=uint8(Tungsten_result);
Tungsten_result_hist=imhist(Tungsten_result)/numel(Tungsten_result);
figure(3)
subplot(1,2,1)
imshow(Tungsten_result)
title('局部直方图统计增强后的图像')
subplot(1,2,2)
bar(h,Tungsten_result_hist);
title('直方图')
axis([0,255,0,0.1])

改变参数,可以得到下图。
k0=0.4;
k2=0.4;
k1=0.02;
E=4.0;

我们也可以仅对右侧一半进行局部直方图统计增强。使j加了列数的一半。则可以得到下图。

j=1+n+floor(col/2):col-n

2019-09-19 16:43:13 flying_monkey_1 阅读数 26
  • Matplotlib 数据分析可视化

    数据分析三剑客,NumPy、Pandas、Matplotlib,本课程是对Matplotlib的讲解,Matplotlib可以是分析的数据可视化,可以更直观的查看数据分析的结果,本课程独辟蹊径,不光教大家如何绘图,例如:饼图、柱状图、条形图、直方图等,而且深入剖析的Matplotlib的绘图原理,例如:如何操作图片,如何加载本地数据等。

    15364 人正在学习 去看看 郭宏志

首先什么是直方图?

直方图:某一灰度级像素出现的次数(多数情况下进行了归一化,以概率的形式表示)。记作p(k)= n(r_k)p(rk) = n_k/n的形式。

性质:无像素空间信息(导致多个图像可能对应一个直方图),一个图像的直方图,可以由多个子图像的直方图叠加而成

直方图均衡:

直方图修正:
                通过灰度映射函数,将原灰度直方图改造成所希望的直方图。
                s=T(r)
               单调递增:防止黑白反转。
            
       目标:找到一个变换函数,T使得变换后的直方图是均匀的。
     

数学推导:

1.连续情况下:

s = T(r),目标是找到这样一个变换T,其中s是处理后的像素灰度级,r是处理前的像素灰度级数,p(r)可以理解为灰度级为r的像素的概率或个数。

\int_{0}^{r}p_r\left ( w\right )dw= \int_{0}^{s}p_s\left ( w \right )dw  第一个积分可以理解为灰度级从0到r的像素的总概率,第二个积分为灰度级从0到s的像素的总概率。因为r到s 的映射是单射的关系,所以灰度级做归一化处理的情况下,要想实现均匀分布就有

\int_{0}^{s}p_s\left ( w \right )dw = \int_{0}^{s}1dw= s就得出这样的变换s= \int_{0}^{r}p_r\left ( w\right )dw可以把r映射到满足情况s上。

2.推广到离散情况时:

积分就变成了累加的形式:\sum_{k=0}^{r} \frac{n_k}{n}=s,s为归一化后处理后的灰度级,n为像素总个数,nk为灰度级为k的像素的个数。(如果不是从连续情况推广过来的规律,我个人理解是,把原来小范围大量存在的灰度级,以概率累加或者理解为累积分布的形式把直方图分散到整体

上栗子!!!!


        

直方图均衡造成的后果:
               多个灰度等级可能均衡为一个灰度等级,导致会出现连续的灰度等级变得不连续, 出现伪轮廓。

直方图匹配(人为规定)    

按照直方图均衡的话,我们想要的结果是均衡后,所有像素灰度级均匀分布,我们最常用的8bit图片的话,也就是理想的结果是0-255的灰度级个数都一样,表现为直方图等高,这仅仅是计算机想要的结果。显然很多情况下就是需要明暗对比很强的图片效果,所以我们还是希望的到适合人们眼睛的效果。

 

也就是说直方图均衡可以理解为直方图匹配的特例。

以上仅仅为个人学习笔记记录,如有错误承蒙指正!
        

2019-07-15 11:09:44 Thousand_jade 阅读数 25
  • Matplotlib 数据分析可视化

    数据分析三剑客,NumPy、Pandas、Matplotlib,本课程是对Matplotlib的讲解,Matplotlib可以是分析的数据可视化,可以更直观的查看数据分析的结果,本课程独辟蹊径,不光教大家如何绘图,例如:饼图、柱状图、条形图、直方图等,而且深入剖析的Matplotlib的绘图原理,例如:如何操作图片,如何加载本地数据等。

    15364 人正在学习 去看看 郭宏志

一、直方图均衡化的概念

   图像的直方图:由一幅图像(一般是灰度图像)上的各个灰度值(灰度值在0-255之间)出现的次数(概率)绘图而成。

图1. 原图像

图2. 原图像对应的直方图:横轴表示灰度值,纵轴表示该灰度值在图像上出现的概率(次数)

直方图均衡化:是图像处理领域中利用图像直方图对对比度进行调整的方法。理想的图像其直方图分布是比较均衡的,如图3比图1对比度增强,表现在直方图分布上图4比图2要均衡。直方图均衡化实际上就是通过处理,使得一副效果欠佳的图像的直方图能够尽量分布均衡,从而使得处理后的图像对比度增强的技术。

图3. 直方图均衡处理后的图像

图4. 处理后图像对应的直方图

这种方法对于背景和前景都太亮或者太暗的图像非常有用,这种方法尤其是可以带来X光图像中更好的骨骼结构显示以及曝光过度或者曝光不足照片中更好的细节。这种方法通常用来增加许多图像的局部对比度,尤其是当图像的有用数据的对比度相当接近的时候。通过这种方法,亮度可以更好地在直方图上分布。

二、实现算法

    1)直方图计算:计算图像各个灰度值的概率

    看一幅灰度图像,i(i>=0且i<=255)表示灰度值,统计该灰度在图像上出现的次数ni(也就是计算图像上灰度值=i的像素的个数),进而计算灰度为i 的像素的出现概率是:

L 是图像中所有的灰度数,n 是图像中所有的像素数, p 实际上是图像的直方图,归一化到 [0,1]。

   2)累计概率计算

    把 c 作为对应于 p 的累计概率函数, 定义为:

c 是图像的累计归一化直方图,简言之,c(i)的物理意义是灰度值<=i的像素出现的概率

   3)直方图均衡化处理

    我们创建一个形式为 j= T(i) 的变换,其中,i、j分别是直方图均衡化处理前、后的对应的像素点的灰度值。则转换公式为:

j= T(i) = c(i).

    4)线性化处理:i的取值范围是0-255,c(i)、j的取值范围是0-1,将j的取值范围线性扩展至0-255: j=j*255.

三、程序的大体流程
	读图im;
	获取im的行、列数:row,col;
	for i=0:255	%计算直方图
		计算im上i出现的次数ni;
	    p(i+1)=ni/(row*col);
	end
	%计算累计直方图c
	for s1=1:row	%进行变换处理
		for s2=1:col
			读取原图像对应位置的灰度值i;
			imnew(s1,s2)=c(i+1);进行变换
		end
	end
	%计算imnew的直方图
	%绘图显示im、imnew;
	%绘图显示im、imnew的直方图。
四、matlab程序
[FileName,PathName] = uigetfile('*.jpg','Select the JPG-file');
File=strcat(PathName,FileName);
img=imread(File); %读取文件

if length(size(img))>2 
    img=rgb2gray(img);%如果不是灰度图先转化为灰度图
end
[m,n]=size(img);%m,n分别为行列像素个数
p=zeros(1,256);%统计各灰度数目,共256个灰度级  
for i=0:255
    p(i+1)=length(find(img==i))/(m*n); %计算直方图img中i出现的概率
end
subplot(2,2,1);
imshow(img);title('原图');
subplot(2,2,2);
bar(0:255,p,'b');title('未均衡化的直方图');
%对直方图进行统计
s=zeros(1,256);
for i=1:256
    for j=1:i
        s(i)=p(j)+s(i);
    end
end
a=round(s*255);%对s进行四舍五入
b=img;
for i=0:255
    b(find(img==i))=a(i+1);%将取值范围线性扩展至0-255
end
subplot(2,2,3);
imshow(b);title('均衡化后图像');
for i=0:255
    Gpeq(i+1)=sum(p(find(a==i)));%统计均衡化后的直方图
end
subplot(2,2,4);
bar(0:255,Gpeq,'b');title('均衡化后的直方图');

 

2015-10-14 23:44:37 jaych 阅读数 3216
  • Matplotlib 数据分析可视化

    数据分析三剑客,NumPy、Pandas、Matplotlib,本课程是对Matplotlib的讲解,Matplotlib可以是分析的数据可视化,可以更直观的查看数据分析的结果,本课程独辟蹊径,不光教大家如何绘图,例如:饼图、柱状图、条形图、直方图等,而且深入剖析的Matplotlib的绘图原理,例如:如何操作图片,如何加载本地数据等。

    15364 人正在学习 去看看 郭宏志

直方图均衡化原理

直方图均衡化的主要思想是直方图统计,在统计之后,根据具体的灰度值及其对应的出现概率,对图片的灰度进行拉伸,使得图像的对比度得到扩展,如下图这张经典的图像所示。


可以看到左上角的图像灰度比较集中,经过直方图均衡化之后,右下角的图像的灰度就被拉伸。

其原理是将图像中的灰度值根据其概率分布在0-255的区间。


转换后的灰度值为:


其中,sk是转变后的灰度值

rk是输入的灰度值

nj是灰度值为 j 的像素个数;

k是当前的灰度值,取值范围0到L-1(L通常为256)。

L表示灰度值可取的个数,如8bit的图像可以表示的灰度值有256,L=256.

举个例子

下图为具体图像的像素值,已知该图像的灰度值为0~7,现要求对其进行直方图均衡化。

这里我们可以得到下图所示的表,其中,L-1=7;Pr=像素个数/25;


根据转换后的灰度值,替换原先的像素值,图像变成:


PC端代码实现

根据以上原理,将其在PC端用程序实现如下:

<span style="font-size:14px;">bool getHist(unsigned char *pImgData, unsigned char *pHistData,int height,int width)
{     // 此处需要对输入的指针进行非空判断,此处略。
	int grayLvl[256]={0};
	float fP[256];
	int i;
	int sum = height*width; //计算总像素个数
	for(i=0 ; i < sum ;i++)  //统计各个灰度值的像素点个数
	{
		grayLvl[pImgData[i]]++;
	}
	for(i=0; i < 256;i++) //计算每个灰度值的比重
	{
		fP[i]=(float)grayLvl[i]/(float)sum;
	}
	for(i=1; i < 256;i++) 
	{
		fP[i]=fP[i-1]+fP[i];
	}
	for(i=0; i <m_ByteOfData;i++) //均衡化
	{
<span style="white-space: pre;">		</span>pHistData[i]=(unsigned char)(fP[pImgData[i]]*255.0+0.5);// 加上0.5是为了能够四舍五入取值。
	}
	return true;
}</span><span style="font-size: 18px;">
</span>

安卓平台移植

在安卓平台,图像处理的操作由JNI实现,基本与上面的程序一致。具体可参考《【安卓开发】JNI程序开发》

<span style="font-size:14px;">void Java_com_example_imageprocess_MainActivity_getHist(JNIEnv* env,jobject thiz,jbyteArray imgData, jbyteArray histData, jlong size)
{
	jint* graylvl=(jint*)malloc(256*sizeof(jint));
	jfloat* pb=(jfloat*)malloc(256*sizeof(jfloat));
	unsigned char* grayHist=(unsigned char*)malloc(256*sizeof(unsigned char));
	unsigned char *imgData_buf=(*env)->GetByteArrayElements(env,imgData,0); //获取jni数组
	unsigned char *histData_buf = (*env)->GetByteArrayElements(env,histData, NULL);
	int i;
	unsigned char index=0;
	memset(graylvl,0,256*sizeof(jint));
	for(i=0;i<size;i++)
	{
		graylvl[imgData_buf[i]]++;
	}

	for(i=0;i<256;i++)
	{
		pb[i]=(jfloat)graylvl[i]/(jfloat)size;
	}
	grayHist[0]=(unsigned char)(pb[0]*255.0+0.5);
	for(i=1;i<256;i++)
	{
		pb[i]=pb[i-1]+pb[i];
		grayHist[i]=(unsigned char)(pb[i]*255.0+0.5);
	}
	for(i=0;i<size;i++)
	{
		histData_buf[i]=grayHist[imgData_buf[i]];
	}
	//save the data from histData_buf to histData
	(*env)->SetByteArrayRegion(env,histData, 0, size,histData_buf);
	free(graylvl);
	free(pb);
	free(grayHist);
}</span>

安卓代码优化

这里的优化是将浮点数优化成定点数,有一定的效果。
<span style="font-size:14px;"><span style="font-size:18px;">void Java_com_example_imageprocess_MainActivity_getHist(JNIEnv* env,jobject thiz,jbyteArray imgData, jbyteArray histData, jlong size)
{
	jint* graylvl=(jint*)malloc(256*sizeof(jint));
	jint* graylvlPtr=graylvl;
	unsigned int* pb=(unsigned int*)malloc(256*sizeof(unsigned int));
	unsigned int *pbPtr=pb;
	unsigned char* grayHist=(unsigned char*)malloc(256*sizeof(unsigned char));
	unsigned char *grayHistPtr=grayHist+1;
	unsigned char *imgData_buf=(*env)->GetByteArrayElements(env,imgData,0);
	unsigned char *imgPtr=imgData_buf;
	unsigned char *histData_buf = (*env)->GetByteArrayElements(env,histData, NULL);
	unsigned char *histPtr=histData_buf;
	int i;
	unsigned char index=0;
	unsigned int temp = (255<<20)/size;
	memset(graylvl,0,256*sizeof(jint));
	for(i=size;i!=0;i--)
	{
		(*(graylvl+*imgPtr))++;
		imgPtr++;
	}
	for(i=256;i!=0;i--)
	{
		*pbPtr=*graylvlPtr*temp;
		pbPtr++;
		graylvlPtr++;
	}
	grayHist[0]=(pb[0]>>20);
	pbPtr=pb+1;
	for(i=255;i!=0;i--)
	{
		*pbPtr=*pbPtr+*(pbPtr-1);
		*grayHistPtr=(*pbPtr)>>20;
		pbPtr++;
		grayHistPtr++;
	}
	imgPtr=imgData_buf;
	for(i=size;i!=0;i--)
	{
		*histPtr=*(grayHist+*imgPtr);
		imgPtr++;
		histPtr++;
	}
	//save the data from histData_buf to histData
	(*env)->SetByteArrayRegion(env,histData, 0, size,histData_buf);
	free(graylvl);
	free(pb);
	free(grayHist);
}
</span></span>


未优化的代码运行的时间为11ms,优化后代码运行时间为9ms。

处理的效果如下图所示,C1为未优化代码,C2为优化代码,发现C2运行后的结果存在一定误差,虽然误差较小(误差为1)。



2019-11-26 17:26:58 qq_41940950 阅读数 131
  • Matplotlib 数据分析可视化

    数据分析三剑客,NumPy、Pandas、Matplotlib,本课程是对Matplotlib的讲解,Matplotlib可以是分析的数据可视化,可以更直观的查看数据分析的结果,本课程独辟蹊径,不光教大家如何绘图,例如:饼图、柱状图、条形图、直方图等,而且深入剖析的Matplotlib的绘图原理,例如:如何操作图片,如何加载本地数据等。

    15364 人正在学习 去看看 郭宏志
  1. 图像处理中绘制图像直方图往往是观察和处理图像的利器之一。

  2. 直方图的观察方面的基本知识:

    • 横坐标代表着灰度级、纵坐标是该灰度值在图像中出现的概率或者次数。
    • 直方图的型态为斜态和峰态,斜态指的是直方图的不对称的程度,峰态表示的是直方图的分布在均值周围的集中程度。
    • 直方图可以基本上反映出图像对比度的基本情况。
  3. 直方图的基本性质

    • 直方图没有位置信息。
    • 直方图反映了总体灰度分布。
    • 直方图具有可叠加性。
    • 直方图具有统计性。

不多BB,上代码:

实现一:

from PIL import Image
from pylab import *
import cv2
from tqdm import tqdm
def Rgb2gray(image):
    h = image.shape[0]
    w = image.shape[1]
    grayimage  = np.zeros((h,w),np.uint8)
    for i in tqdm(range(h)):
        for j in range(w):
            grayimage [i,j] = 0.144*image[i,j,0]+0.587*image[i,j,1]+0.299*image[i,j,1]
    return grayimage
# 读取图像到数组中,并灰度化
image = cv2.imread("peng.png")

im = array(Image.open('peng.png').convert('L'))
# 直方图图像
# flatten可将二维数组转化为一维
hist(image.flatten(), 128)
# 显示
show()

显示效果图如下:

在这里插入图片描述
实现方法二:

import cv2
import matplotlib.pyplot as plt
import numpy as np
import math
import os
import pandas as pd
from tqdm import tqdm

# 绘制直方图函数
def grayHist(img):
    h, w = img.shape[:2]
    pixelSequence = img.reshape([h * w, ])
    numberBins = 256
    histogram, bins, patch = plt.hist(pixelSequence, numberBins,
                                      facecolor='black', histtype='bar')
    plt.xlabel("gray label")
    plt.ylabel("number of pixels")
    plt.axis([0, 255, 0, np.max(histogram)])
    plt.show()

image = cv2.imread("peng.png",0)
grayHist(image)

显示效果如下:
在这里插入图片描述

没有更多推荐了,返回首页