数据算法基于FPGA的图像处理(七)--Verilog实现均值滤波Strut2教程-java教程

最近研究数据算法,略微总结一下,以后继续补充:

    C语言或者Matlab停止图像理处,图片的文件读取取获或者摄像头读取都能

    一个函数搞定,但是FPGA停止图像理处,如果从摄像头取获须要虑考很多时序题问,如果从存储区取获图片又不能太大,因为FPGA部内的RAM个数很无限,想存一张图片都比拟难困。

    //C IplImage *src = cvLoandImage("lena.png",0); //Matlab src = imread('lena.png');

    //中值滤波和值均滤波 #include<cv.h> #include<highgui.h> int main(){ IplImage * image,*image2,*image3; image = cvLoadImage("E:\\image\\Dart.bmp",0);//以度灰图像的式形读入图片 cvNamedWindow("image",CV_WINDOW_AUTOSIZE); cvNamedWindow("image2",CV_WINDOW_AUTOSIZE); cvNamedWindow("image3",CV_WINDOW_AUTOSIZE); //cvSaveImage("E:\\image\\moon.jpg",image,0); cvShowImage("image",image); //cvWaitKey(0); unsigned char * ptr,*dst; int i,j,m,n,sum,temp,r,s; image2 = cvCreateImage(cvGetSize(image),image->depth,1); image3 = cvCreateImage(cvGetSize(image),image->depth,1); //模板1 值均 int tem[9] = {1,1,1,1,1,1,1,1,1}; //也可以应用进改的高斯模板,但是果效邻近 int tem2[9] = {0};//取获中值时用于序排 //值均滤波3*3模板的值均 for( i = 0 ; i < image->height;i++){ for( j = 0; j< image->width;j++){ //界边理处 if(i == 0 || i == image->height || j == 0 || j == image->width){ ptr = (unsigned char *)image->imageData + i*image->widthStep + j; dst = (unsigned char *)image2->imageData+ i*image2->widthStep+ j; *dst = *ptr; //界边值予赋源图像的值 } else { sum = 0; for( m = -1 ; m <= 1; m++ ){ for( n = -1 ; n <= 1 ; n++){ ptr = (unsigned char *)image->imageData + (i + m)*image->widthStep + j + n; sum += (*ptr) * tem[3*(m+1) + n+1]; } } dst = (unsigned char *)image2->imageData+ i *image2->widthStep+ j; *dst = (unsigned char)((sum +4)/9);//赋新值,四舍五入 } } } //中值滤波 在去除噪声的同时,图像的模糊度程比拟小,比值均滤波更加合适 //打击噪声或者称为椒盐噪声 for( i = 0 ; i < image->height;i++){ for( j = 0; j< image->width;j++){ //界边理处 if(i == 0 || i == image->height || j == 0 || j == image->width){ ptr = (unsigned char *)image->imageData + i*image->widthStep + j; dst = (unsigned char *)image3->imageData+ i*image3->widthStep+ j; *dst = *ptr; //界边值予赋源图像的值 } else { temp = 0; //将3*3模板覆盖的值贝拷进组数,一边查找中值 for( m = -1 ; m <= 1; m++ ){ for( n = -1 ; n <= 1 ; n++){ ptr = (unsigned char *)image->imageData + (i + m)*image->widthStep + j + n; tem2[3*(m+1) +n +1] = *ptr; //printf("%d",*ptr); } } //对组数停止冒泡序排 for(r = 0 ; r <8; r ++){ for(s = 0 ; s< r -1; s++ ){ if(tem2[s] > tem2[s+1]){ temp = tem2[s]; tem2[s] = tem2[s+1]; tem2[s+1] = temp; } } } //printf("%d",tem2[4]); //对新图予赋新值 dst = (unsigned char *)image3->imageData+ i *image3->widthStep+ j; *dst = (unsigned char)(tem2[4]);//赋新值 } } } cvShowImage("image2",image2); cvShowImage("image3",image3); cvWaitKey(0); cvSaveImage("E:\\image\\Dart2.bmp",image2,0); cvSaveImage("E:\\image\\Dart3.bmp",image3,0); return 0; }

    %mcode to create a mif file src = imread('lena.jpg'); gray = rgb2gray(src); [m,n] = size( gray ); % m行 n列 N = m*n; %%数据的度长,即存储器深度。 word_len = 8; %%个每单元的据占的位数,需自己设定 data = reshape(gray', 1, N);% 1行N列 fid=fopen('gray_image.mif', 'w'); %打开文件 fprintf(fid, 'DEPTH=%d;\n', N); fprintf(fid, 'WIDTH=%d;\n', word_len); fprintf(fid, 'ADDRESS_RADIX = UNS;\n'); %% 指定址地为十进制 fprintf(fid, 'DATA_RADIX = HEX;\n'); %% 指定数据为十六进制 fprintf(fid, 'CONTENT\t'); fprintf(fid, 'BEGIN\n'); for i = 0 : N-1 fprintf(fid, '\t%d\t:\t%x;\n',i, data(i+1)); end fprintf(fid, 'END;\n'); %%出输尾结 fclose(fid); %%关闭文件

    每日一道理
喜马拉雅直冲霄汉,可上面有攀爬者的旗帜;撒哈拉沙漠一望无垠,可里面有跋涉者的脚印;阿尔卑斯山壁立千仞,可其中有探险者的身影;雅鲁藏布江湍急浩荡,可其中有勇敢者的故事。

    DEPTH=1024; WIDTH=8; ADDRESS_RADIX = UNS; DATA_RADIX = HEX; CONTENT BEGIN 0 : 9e; 1 : 97; ................................... 1020 : 50; 1021 : 65; 1022 : 58; 1023 : 3b; END;

    gray_image_ROM gray_image_ROM_inst ( .address ( address_sig ), .clock ( clock_sig ), .q ( q_sig ) );

    可以通过如下的方法逐一取获像素值:

    //rom reg [9:0] rd_addr = 10'b0_000_000_000; wire [7:0] raw_data; //address increase always @(posedge rCLK_1Hz or negedge iRST_n) if(!iRST_n) rd_addr <= 10'b0_000_000_000; else if(rd_addr == 10'b1_111_111_111) rd_addr <= 10'b0_000_000_000; else rd_addr <= rd_addr + 1'b1; //read from rom gray_image_ROM gray_image_ROM_inst ( .address ( rd_addr ), .clock ( rCLK_1Hz ), .q ( raw_data ) );

    raw_data就会个每期周更新一次,逐次将有所的数据流出。面下就是怎么理处了。

    

    shift_line_buffer shift_line_buffer_inst ( .clock ( clock_sig ), .shiftin ( shiftin_sig ), .shiftout ( shiftout_sig ), .taps0x ( taps0x_sig ), .taps1x ( taps1x_sig ), .taps2x ( taps2x_sig ) );

    可以通过如的方法取获邻域内的9个数据:

    wire [7:0] wData0; wire [7:0] wData1; wire [7:0] wData2; reg [7:0] wData0_d1,wData0_d2; reg [7:0] wData1_d1,wData1_d2; reg [7:0] wData2_d1,wData2_d2; //TODO shift_line_buffer S1 ( .clock(wMeanFilter_clk), .shiftin(iData), .shiftout(), .taps2x(wData0), .taps1x(wData1), .taps0x(wData2) ); //get data in the window always@(posedge wMeanFilter_clk or negedge iRST_n) begin if (!iRST_n) begin wData0_d1<=0; wData0_d2<=0; wData1_d1<=0; wData1_d2<=0; wData2_d1<=0; wData2_d2<=0; end else begin {wData0_d2,wData0_d1}<={wData0_d1,wData0}; {wData1_d2,wData1_d1}<={wData1_d1,wData1}; {wData2_d2,wData2_d1}<={wData2_d1,wData2}; end end

    module meanFilter ( input [7:0] p00, input [7:0] p01, input [7:0] p02, input [7:0] p10, input [7:0] p11, input [7:0] p12, input [7:0] p20, input [7:0] p21, input [7:0] p22, output [7:0] oMeanVal ); //weights //1 2 1 //2 4 2 //1 2 1 wire [8:0] p01_w, p10_w, p12_w,p21_w; wire [9:0] p11_w; wire [11:0] sum; wire [10:0] sum2; wire [10:0] sum1; assign p01_w = { p01, 1'b0}; assign p10_w = { p10, 1'b0}; assign p12_w = { p12, 1'b0}; assign p21_w = { p21, 1'b0}; assign p11_w = { p11, 2'b0}; assign sum1 = p00 + p02 + p20 + p22 + p11_w; assign sum2 = p01_w + p10_w + p12_w + p21_w; // assign sum4 = p11_w; assign sum = sum1 + sum2; assign oMeanVal = sum[11:4]; endmodule

    数据算法基于FPGA的图像处理(七)--Verilog实现均值滤波Strut2教程-java教程_第1张图片

    

    %mcode to create a mif file src = imread('lena.jpg'); gray = rgb2gray(src); imwrite(gray, 'gray.png'); [m,n] = size( gray ); % m行 n列 dst = gray; sum = 0; gray = double(gray); for i = 2 : m -1 % i 行 for j = 2 : n -1 %j 列 sum = gray(i,j)*4 + gray(i, j -1)*2 + gray(i-1, j)*2 + gray(i, j + 1)*2 + gray(i +1, j) *2 + gray(i-1, j-1)+ gray(i-1,j+1) + gray(i+1, j-1) + gray(i +1, j+1); dst(i,j) = uint8(sum/16); end end %将数据写入文件 fid = fopen('meanFilter.txt','w'); for i = 1 : m for j = 1 :n fprintf(fid, '%x ',dst(i,j)); end end fclose(fid); imwrite(dst, 'meanFilter.png');

    


    注意到有些数据并不一致,有两个原因,一是Matlab理处时会有舍入,二是二者对界边的理处方法不同。

文章结束给大家分享下程序员的一些笑话语录: 现在社会太数字化了,所以最好是有一个集很多功能于一身的设备!

你可能感兴趣的:(Verilog)