对比度拉伸:对数对比度拉伸
0赞对比度拉伸:对数对比度拉伸
20130916
By CrazyBingo
对比度拉伸有很多种方法,这里介绍对数对比度拉伸的方法,通过Matlab与Verilog的移植思路结合来阐述这一算法。
简单的说对比度拉伸与直方图均衡同一概念,就是为了像素均衡分度,使得亮的更亮,暗的更暗,图像更加的细腻!
首先为了验证先生称一张灰度简便图像,如下所示:
IMG1 = zeros(256,256);
for m = 1:256
IMG1(m,m) = m;
for n = (m+1):256
IMG1(m,n) = n-1;
IMG1(n,m) = IMG1(m,n)-1;
end
end
subplot(1,2,1);
imshow(uint8(IMG1));
对数对比度拉伸算法如下所示(有很多种,这是其中一种):
其中r为原来图像的数据,S为拉伸后的数据,Threshold为阀值,而E为对数。由于目标图像为0-255的灰度图像,因此最后乘了一个255的因子!
应用该算法,取阀值为127,E=5,Matlab算法如下:
IMG1 = double(IMG1);
IMG2 = zeros(256,256);
for i = 1:256
for j = 1:256
IMG2(i,j) = (1./(1 + (THRESHOLD./IMG1(i,j)).^E)) * 255;
end
end
subplot(1,2,2);
imshow(uint8(IMG2));
最终拉伸后的图像如下所示:
可见黑色更黑了,同时白色也更白了,整个图像按照对数拉伸了。
为了更好地理解,画出了该对数的函数,如下所示(红色):
最后,为了验证算法,同对灰度图像处理,得到了如下结果(左边为原图,右边卫处理后的图像):
但是,这还不够,为了便于FPGA的移植,我们不可能采用浮点操作来实现对数函数的算法的!!!为了便于移植,我们用Matlab生成一位数组来移植到FPGA的ROM中!!
由于本人擅长偷懒,因此多谢了几行代码,直接将对数对比度拉伸生成函数,添加了文件系统,直接生成了Mif或者verilog直接可调用的文件,代码如下所示:
% -----------------------------------------------------------------------
clear all; %清除Matlab缓存数据
THRESHOLD = 255*0.5;
E = 5;
fp_gray = fopen('C:\Users\Administrator\Desktop\Grave_Contrast_Array.v','w');
fprintf(fp_gray,'//Gray THRESHOLD = %f, E = %f\n', THRESHOLD, E);
fprintf(fp_gray,'module Grave_Contrast_Array\n');
fprintf(fp_gray,'(\n');
fprintf(fp_gray,' input\t\t[7:0]\tPre_Data,\n');
fprintf(fp_gray,' output\treg\t[9:0]\tPost_Data\n');
fprintf(fp_gray,');\n\n');
fprintf(fp_gray,'always@(*)\n');
fprintf(fp_gray,'begin\n');
fprintf(fp_gray,'\tcase(Pre_Data)\n');
Gray_ARRAY = zeros(1,256);
for i = 1 : 256
Gray_ARRAY(1,i) = (1./(1 + (THRESHOLD./(i-1)).^E)) * 255;
fprintf(fp_gray,'\t%03d: Post_Data = %03d; \n',i-1, uint16(Gray_ARRAY(1,i)));
end
fprintf(fp_gray,'\tdefault:Post_Data = Pre_Data;\n');
fprintf(fp_gray,'endcase\n');
fprintf(fp_gray,'end\n');
fprintf(fp_gray,'\nendmodule\n');
fclose(fp_gray);
然后在桌面生成了Grave_Contrast_Array.v的verilog文件,接口调用极其方便,打开如下:
最后,在Verilog中移植,如下:
//------------------------------------
wire [9:0] CCD_Post_Data;
Grave_Contrast_Array u_Grave_Contrast_Array
(
.Pre_Data (CCD_Din),
.Post_Data (CCD_Post_Data)
);
然后,然后你们都懂了。。。。