方法一:
imfinfo('testpng')%查看文件信息
%可以看出是真彩色图像,ColorType: 'truecolor'
%转换为灰度图像进行处理
X=imread('testpng');
X=rgb2gray(X);
X=im2double(X);%uint8转换为double类型
%保留运算后的负值
%防止运算时精度丢失
g=medfilt2(X,[3 3],'symmetric');%中值滤波33,采用对称的填充方式
g1=im2uint8(g);%double[0,1]----->uint8[0,255]
%二值化处理
g1(find(g1<128))=0;
g1(find(g1>=128))=1;
subplot(3,1,1);
imshow(X,[]);title('原图');
subplot(3,1,2);
imshow(g,[]);title('33中值滤波');
subplot(3,1,3);
imshow(g1,[]);title('33中值滤波+二值化处理');
结果见1png
方法二:
imfinfo('testpng')%查看文件信息
%可以看出是真彩色图像,ColorType: 'truecolor'
%转换为灰度图像进行处理
X=imread('testpng');
X=rgb2gray(X);
X=im2double(X);%uint8转换为double类型
%保留运算后的负值
%防止运算时精度丢失
g=medfilt2(X,[3 3],'symmetric');%中值滤波33,采用对称的填充方式
g1=mat2gray(g);
g1=im2bw(g1,05);%二值化处理,im2bw:image to black-white的意思
subplot(3,1,1);
imshow(X);title('原图');
subplot(3,1,2);
imshow(g);title('33中值滤波');
subplot(3,1,3);
imshow(g1);title('33中值滤波+二值化处理');
结果与前面的相同。
1、取连续采样值N(N大于等于3)点,N为奇数,去掉最小值和最大值,去中间的值作为中间点的采样值。2、实际应用中,也可以取9点,去掉最小两点和最大两点,取中间5点的平均值作为采样值。N取多少点,去掉最大最小几个数值,没有硬性的规定,自己可以在程序中根据实际情况自行决定。%原图像
I = [1 2 1 4 3 ;
1 10 2 3 4 ;
5 2 6 8 8;
5 5 7 0 8;
5 6 7 8 9];
x=double(I);
x1=x;
for i=2:4
for j=2:4
c=x(i-1:i+1,j-1:j+1); %取出3x3邻域
c=[ c(1,:) c(2,:) c(3,:)]; %整理成一行
m=median(c); %mm是中值
x1(i,j)=m; %中值赋给中心元素
end
end
x1
%为了计算边缘像素,将原图像扩展为6x6填充0
I = [0 0 0 0 0 0 0;
0 1 2 1 4 3 0;
0 1 10 2 3 4 0;
0 5 2 6 8 8 0;
0 5 5 7 0 8 0;
0 5 6 7 8 9 0;
0 0 0 0 0 0 0 ];
x=double(I);
%加权均值滤波3x3模板
a = [ 1 1 1;1 2 1; 1 1 1]/10;
for i=2:5
for j=2:5
c=x(i-1:i+1,j-1:j+1)a; %与模板相乘
x2(i,j)=sum(sum(c))/9; %计算均值并赋值给像素(i,j)
end
end
x2 = x2(2:5,2:5)先简单介绍一下基本的图像处理算法,比如均值滤波,中值滤波是典型的线性滤波算法,它是指在图像上对目标像素给一个模板,该模板包括了其周围的临近像素(以目标像素为中心的周围8哥像素,构成一个滤波模板,即去掉目标像素本身),再利用模板中的全体像素的平均值来代替原来像素值。

中值滤波算法可以形象的用上述表格来描述,即对于每个33的阵列而言,中间像素的值,等于边缘8个像素的平均值,算法的理论很简单,对于C语言或者matlab而言,一副640480图像的均值滤波,可以很方便的通过数组获得33的阵列,但对于Verilog而言,确实不是一件容易的事儿,想不明白呀,硬件和软件确实不是一个思路。
知名FPGAer Crazybingo 老湿,在他的VIP_mini_board配套教程里面提到了三种方法,但是最被认可接受且最方便的就是shift_ram,用他的话来说就是shift_ram就是为实现33矩阵而生的。
首先介绍一下Shift_ram,宏定义模块如下图所示:

Shift_ram可以定义输入输出数据宽度,每行的宽度, 移位的行数,这里我们需要8bit的数据位宽,每行的宽度640,移位2行即可,(原因稍后分析,其实很简单,画个图很容易理解)。下面的示意图有助于更好的理解Shift_ram。


每个时钟周期输入一个移位数据shift_in_data,同时输出一个数据shift_out_data,而存储器内部是每个clk周期移位一次,每个tap的输出直接移位到下一个tap的输入,每个tap的最后一个w位宽的数据都能出现在对外接口中供用户逻辑使用(通过taps0x( ),taps1x( )输出)。

Shift_ram中存2行数据,同时与当前输入行的数据组成3行的阵列,实现8bit宽度的33像素阵列功能,具体的实现步骤如下:
在我看来首先应当明确33矩阵生成器的输入:
对于来自sensor的图像数据,图像重构需要以下数据:
1 per_frame_vsync //帧同步信号
2 per_frame_href //行有效信号
3 per_frame_clken // 这是移位寄存器存储数据的使能 时钟信号(数据在clk的监督下进来了,但是能不能存下来还要看
per_frame_clken )
4 clk //像素时钟
5 rst_n //全局复位信号
6 img_Y //图像数据
步骤:
1: 首先,将输入的信号用像素使能时钟(per_frame_clken)同步一拍,以保证数据与Shift_ram输出的数据保持同步,如下: 
2:接着,例化并输入row3_data 
3:row_data读取信号的分析及生成
这里有一个问题,就是数据进入shift_ram存储耗费了一个时钟,一次33阵列的读使能与时钟,需要进行一个clock的偏移,如下所示:

4:根据行同步信号read_frame_href 与read_frame_clken信号,直接读取33像素阵列,读取的verilog代码如下


matrix中的p11—p33即为得到的33像素阵列。
5bingo老师把这一步放在了最后,看来基本理解到位了,哈哈哈。 
shift_register的时钟使能输入怎么产生的,在bingo的代码中一直没有仔细的去看,现在有必要在这里整理一下了。


代码还是要多看多写才能达到快速理解别人代码的功力,不用说自己的代码能力也会快速提升,说白了时钟使能信号就是在图像传感器已经输出了10帧图像以后,再开始采样,时钟使能保持与行有效信号同步。最终在打一拍之后时钟使能信号有效。用matlab
A=你的图像矩阵
imshow(medfilt2(A,[3 3]))
其实口算也可以,把每一个像素和其八邻域的像素排序,取中间那个值作为这个点的像素值。%我觉得是你计算 PSNR的方法错了,应该是用最大像素值,
%灰度图像的最大像素值是255, 而不是512。
%另外计算MSE也不用那么麻烦
%下面是计算 MSE和PSNR的程序,我拿一张试了一下,结果肯定是不一样的。
%还有统计像素值出现的次数,用直方图imhist会更简单点,这个程序我没写。
I=imread('boatbmp');
J=imnoise(I,'gaussian',0,001);
Jg=double(J);
%均值滤波
k1=filter2(fspecial('average',3),Jg);
k2=filter2(fspecial('average',5),Jg);
figure,subplot(221),imshow(I);title('原图');
subplot(222),imshow(J);title('加入高斯白噪声以后的图像');
subplot(223),imshow(uint8(k1));title('33模板均值滤波');
subplot(224),imshow(uint8(k2));title('55模板均值滤波');
%中值滤波
k3=medfilt2(Jg,[3 3]);
k4=medfilt2(Jg,[5 5]);
figure,subplot(221),imshow(I);title('原图');
subplot(222),imshow(J);title('加入高斯白噪声以后的图像');
subplot(223),imshow(uint8(k3));title('33模板中值滤波');
subplot(224),imshow(uint8(k4));title('55模板中值滤波');
%计算均值滤波后图像的PMSE与PSNR
diff=(double(I)-k1)^2;
mse=mean(diff(:));
pmse_avg=mse;
max_value=max(k1(:));
psnr=double(10log(max_valuemax_value/mse)/log(10));
%计算中值滤波后的各项指标
diff=(double(I)-k3)^2;
mse=mean(diff(:));
max_value=max(k3(:));
pmse_mid=mse;
psnr_mid=double(10log(max_valuemax_value/mse)/log(10));
根据题目要求就是计算这四个像元;
以30为例,①均值平滑:就是取原栅格数据中30周围的3×3栅格数据,求这9个数的均值,代替中间30的值,类似的 ,可以得到结果;②中值:也是类似的,不过是将这9个数据进行排序,然后去中值,代替中间30的值
x= 1 1 12 2 2
3 3 3
扩展
0 0 0 0 0
0 1 1 1 0
0 2 2 2 0
0 3 3 3 0
0 0 0 0 0
e的第一行、第一列,以原来矩阵的第一个数为中心,3x3矩阵作为统计,也就是
0 0 0
0 1 1
0 2 2
然后对这9个数排序,得到 0 0 0 0 0 1 1 2 2,取牌子中间的数,也就是第5个数0
所以e(1,1)=0
对于e(1,2)第一行,第二列
以原来矩阵(1,2)为中心,取9个数
0 0 0
1 1 1
2 2 2
排序 0 0 0 1 1 1 2 2 2,中间的数,第5个数是1
所以e(1,2)=1
依次类推
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)