国内做网站比较好的公司网站统计ip pv
国内做网站比较好的公司,网站统计ip pv,枣庄做网站建设找哪家,可以做翻译的网站目录
第一部分、关于白平衡的知识
1、MATLAB 自动白平衡算法的实现
1.1、matlab代码
1.2、测试效果
1.3 测试源图
2、为什么摄像头采集的图像要做白平衡
3、自动白平衡算法总结
4、FPGA设计思路
4.1、实时白平衡的实现
4.2、计算流程优化思路
第二部分、硬件实…目录
第一部分、关于白平衡的知识
1、MATLAB 自动白平衡算法的实现
1.1、matlab代码
1.2、测试效果
1.3 测试源图
2、为什么摄像头采集的图像要做白平衡
3、自动白平衡算法总结
4、FPGA设计思路
4.1、实时白平衡的实现
4.2、计算流程优化思路
第二部分、硬件实现
1、除法IP核的调用方法
2、乘法IP核的调用方法
3、verilog代码
第三部分、实现结果
1、白平衡前后对比
2、总结 第一部分、关于白平衡的知识
1、MATLAB 自动白平衡算法的实现 大家先测试下面这段自动白平衡MATLAB代码代码来源于以下这篇博客我只不过加上了注释更多细节请大家参考这篇博客图像白平衡原理及实现-CSDN博客
1.1、matlab代码
%%白平衡与色温紧密相关不同色温光源下图像会呈现不同程度的偏色
%%由于人眼独特的适应性在不同光照条件下观看物体时不会出现偏色而就没这么先进了
%%蓝色光色温高红色光色温低
%CSDNhttps://blog.csdn.net/helimin12345/article/details/78255669clc;
clear all;
close all;tic;%用来记录程序的使用时间tic 程序 toc% imgSrc imread(green1.jpg);
imgSrc imread(test2.png);
%定义一个与图像大小一样的三位变量
imgDst imgSrc;
%将RGB三个通道的数据进行分离
imgR imgSrc(:,:,1);%单个通道的数据默认 uint80~255
imgG imgSrc(:,:,2);
imgB imgSrc(:,:,3);
%对RGB三个通道的像素求均值相当于mean( mean( A ) ) 即对整一个矩阵求像素平均值
RAve mean2(imgR);
GAve mean2(imgG);
BAve mean2(imgB);
aveGray (RAve GAve BAve) / 3;%比较系数
%计算三个通道的增益系数
RCoef aveGray / RAve;
GCoef aveGray / GAve;
BCoef aveGray / BAve;
%使用增益系数来调整原始图
%注意其实这里应该是存在一个比较的过程小于255那就是当前值大于255那就等于255只不过uint8超出了255自动溢出了
%巧妙的运用溢出会减少很多计算量
RCorrection RCoef * imgR;
GCorrection GCoef * imgG;
BCorrection BCoef * imgB;
%白平衡后的图像
imgDst(:,:,1) RCorrection;
imgDst(:,:,2) GCorrection;
imgDst(:,:,3) BCorrection;
%显示两张图片
figure(1),imshow(imgSrc),title(original image);
figure(2),imshow(imgDst),title(white balanced image);
1.2、测试效果 关于这两张测试照片我也会放在文末。先看效果 1.3 测试源图 我也是网上从别人博客保存的找不到原博客了 2、为什么摄像头采集的图像要做白平衡 人眼对白色很敏感 在不同色温下都能准确判断出白色。例如下面那张图色温比较高的时候会偏蓝色温比较低的的时候会偏红。 当摄像头在不同色温的光源下采集的图像会出现不同程度的偏色与人眼看到的颜色不一致因此需要进行白平衡处理。还有一点就是我感觉CMOS摄像头就算在正常光源下采集的图像也是偏绿的不知道是不是因为选用的Bayer转RGB的算法太垃圾了还是什么别的原因。关于Bayer转RGB的算法大家可以看这篇基于FPGA的Bayer转RGB算法实现 但是目前稍微好一点的摄像头模组都包含了自动白平衡算法都不需要做处理。 3、自动白平衡算法总结 把上面的matlab代码仔细读几遍读明白之后总结出白平衡算法的步骤 step1、分别对图像的R、G、B三通道的数据进行求和得到Rsum、Gsum、Bsum step2、获取图像的R、G、B三通道的平均值RvGvBvimag_width当前图像的宽 imag_high当前图像的高度。 Rv Rsum /imag_width*imag_high Gv Gsum /imag_width*imag_high Bv Bsum /imag_width*imag_high step3、将求得的Rv、Gv、Bv 进行加和取平均值得到Kv (Rv Gv Bv) / 3 step4、分别将R、G、B三通道的数据带入公式进行计算得到新的值 R通道 Rnew R * Kv / Rv if(Rnew 255) Rnew 255; G通道Gnew G * Kv / Gvif(Gnew 255) Gnew 255; B通道 Bnew B * Kv / Bv if(Bnew 255) Bnew 255; step5、最后将计算后的图片显示出来便是白平衡后的图像。 4、FPGA设计思路
4.1、实时白平衡的实现 FPGA的摄像头采集的是实时的图像数据每秒采集30帧那么如何将FPGA获取的图像进行白平衡处理呢 解决办法就是计算当前帧图像的RvGvBvKv将计算的结果留给下一帧图像使用下一帧的RvGvBvKv计算结果又给下下一帧使用...一直循环就实现了实时的图像白平衡处理。
4.2、计算流程优化思路 正常情况下进行除法可以调用除法IP核来解决。但是当除数很大且接近于2^N时这时就可以用截位的方式来代替除法核。 例如对于分辨率为1920*1080图片Rv Rsum /1920*1080而1920*1080 2,073,600非常接近于2^21 2,097,152。 如果我用2^21次幂来代替1920*1080那么只需要去除Rsum的低21位即可直接截位都不需要移位。这这太牛逼了
计算误差方法由于误差很小而且对于图像处理也不需要那么高的精度所以该方法可行。 (2^21 - (1920*1080)) / (1920*1080) (2,097,153 - 2,073,600) / 2,073,600 ≈ 0.0113585 ≈ 1.14% 第二部分、硬件实现
1、除法IP核的调用方法 第一步、搜索输入divider generator 第二步、配置第二个界面 第三步、配置第三个界面 注意这里的Latency配置为自动模式 第四步、整数有效位宽和余数有效位宽 注意这里的位宽需要记住方便后面截位数据 2、乘法IP核的调用方法 第一步、搜索multiplier 第二步、配置第二个界面 第三步、配置Output and control界面 注意这里是几级流水那么输出就有几个时钟周期的latency。这里选用系统推荐的流水级数当然也可以自定手动修改流水级数级数越多时序越好延迟越多因此实际开发要是情况而定。 3、verilog代码
// -----------------------------------------------------------------------------
// Copyright (c) 2014-2024 All rights reserved
// -----------------------------------------------------------------------------
// Author : BigFartPeach
// CSDN : 大屁桃
// E-mail : 2624507313qq.com
// File : white_balance_my.v
// Create : 2024-01-06 13:58:39
// -----------------------------------------------------------------------------
module white_balance_my(input wire clk,input wire rst,input wire vsync,input wire hsync,input wire [7:0]red,input wire [7:0]green,input wire [7:0]blue,output wire fra_vsy,output reg fra_hsy,output wire[23:0]rgb_new);//变量定义
/*累计这一帧并计算上一帧的累加结果*/
reg [1:0]vsync_dly;//对vsync延迟两拍
reg vsync_fall;//检测vsync下降沿reg [28:0]Rsum,Gsum,Bsum;//求和
reg [7:0]Ravg,Gavg,Bavg;//求均值直接舍去低21位wire[30:0]Ksum;//RsumGsumBsum的和wire[55:0]Temp_Kavg;//临时用来存储Kavg除法IP输出的结果
wire Kavg_valid;//除法IP核输出的结果有效标志
reg [30:0]Kavg;//除法IP核输出的结果
///
/*计算当前帧*/
wire [18:0]temp_red,temp_green,temp_blue;//用来存储red*Kavg、green*Kavg、blue*Kavg的值
wire [31:0]temp_red_new,temp_green_new,temp_blue_new;//用来存储除法IP输出的值temp_red/Ravg、temp_green/Gavg、temp_blue/Bavg
wire temp_fra_hsy;//用来存储输出的red_new的valid用作输出的fra_hsy//凑成24bit输出
reg [7:0]red_new;
reg [7:0]green_new;
reg [7:0]blue_new;assign rgb_new {red_new,green_new,blue_new};//凑成24bit输出//vsync_dly打拍
always (posedge clk) beginvsync_dly {vsync_dly[0],vsync};
end
//检测vsync下降沿
always (posedge clk or posedge rst) beginif (rst 1b1) beginvsync_fall 1b0;endelse if (vsync_dly 2b10) beginvsync_fall 1b1;endelse beginvsync_fall 1b0;//just one cycle clockend
end//Rsum,Gsum,Bsum求和 以及 清零
always (posedge clk or posedge rst) beginif (rst 1b1) beginRsum d0;Gsum d0;Bsum d0;endelse if (vsync_fall 1b1) beginRsum d0;Gsum d0;Bsum d0; endelse if(hsync 1b1)beginRsum Rsum red;Gsum Gsum green;Bsum Bsum blue;end
end
//Ksum求和
assign Ksum Rsum Gsum Bsum;//如果用alway相较于RsumGsumBsum会晚一个时钟周期//Ravg,Gavg,Bavg求均值直接舍去Rsum,Gsum,Bsum的低21位
always (posedge clk or posedge rst) beginif (rst 1b1) beginRavg d0;Gavg d0;Bavg d0;endelse if (vsync_fall 1b1) beginRavg Rsum[28:21];Gavg Gsum[28:21];Bavg Bsum[28:21];end
end//Kavg的除法IP33个latency
div_gen_Ksum_div_1920x1080x3 div_gen_Kavg (.aclk(clk), // input wire aclk.s_axis_divisor_tvalid(vsync_fall), // input wire s_axis_divisor_tvalid.s_axis_divisor_tdata(23d6220800), // input wire [23 : 0] s_axis_divisor_tdata.s_axis_dividend_tvalid(vsync_fall), // input wire s_axis_dividend_tvalid.s_axis_dividend_tdata(Ksum), // input wire [31 : 0] s_axis_dividend_tdata.m_axis_dout_tvalid(Kavg_valid), // output wire m_axis_dout_tvalid.m_axis_dout_tdata(Temp_Kavg) // output wire [55 : 0] m_axis_dout_tdata
);//锁存Kavg
always (posedge clk or posedge rst) beginif (rst 1b1) beginKavg d0;endelse if (Kavg_valid 1b1) begin//可以用这个信号来锁存KavgKavg Temp_Kavg[54:24];//截取输出的整数位end
end///
//进行结果计算
//red_new的计算先算乘法再算除法 red_new (red*Kavg)/Ravg
//3级流水线3个latency
mult_gen_8xKavg redxKavg (.CLK(clk), // input wire CLK.A(red), // input wire [7 : 0] A.B(Kavg[10:0]), // input wire [10 : 0] B这里取11位主要是根据老师推荐的按道理是要去大一点但是大多少位并没有限制.P(temp_red) // output wire [18 : 0] P
);/*************************************************/
/******************解决白线问题的方法**************/
/*************************************************/
//给hsync进行打拍操作。delay 3个 latency和上面乘法核的输出对齐
reg [2:0]hsync_dly;
always (posedge clk) beginhsync_dly {hsync_dly[1:0],hsync};
end
/*************************************************/
/*************************************************/div_gen_0 temp_red_div_Ravg (.aclk(clk), // input wire aclk.s_axis_divisor_tvalid(hsync_dly[2]), // input wire s_axis_divisor_tvalid.s_axis_divisor_tdata(Ravg), // input wire [7 : 0] s_axis_divisor_tdata.s_axis_dividend_tvalid(hsync_dly[2]), // input wire s_axis_dividend_tvalid.s_axis_dividend_tdata(temp_red), // input wire [23 : 0] s_axis_dividend_tdata.m_axis_dout_tvalid(temp_fra_hsy), // output wire m_axis_dout_tvalid.m_axis_dout_tdata(temp_red_new) // output wire [31 : 0] m_axis_dout_tdata [26:8]
);
//red进行判断
always (posedge clk or posedge rst) beginif (rst 1b1) beginred_new d0;endelse if (temp_red_new[26:8] d255) beginred_new d255;endelse beginred_new temp_red_new[15:8];//有效值肯定在这个八位区间end
end//green_new
mult_gen_8xKavg greenxKavg (.CLK(clk), // input wire CLK.A(green), // input wire [7 : 0] A.B(Kavg[10:0]), // input wire [10 : 0] B.P(temp_green) // output wire [18 : 0] P
);div_gen_0 temp_green_div_Gavg (.aclk(clk), // input wire aclk.s_axis_divisor_tvalid(hsync_dly[2]), // input wire s_axis_divisor_tvalid.s_axis_divisor_tdata(Gavg), // input wire [7 : 0] s_axis_divisor_tdata.s_axis_dividend_tvalid(hsync_dly[2]), // input wire s_axis_dividend_tvalid.s_axis_dividend_tdata(temp_green), // input wire [23 : 0] s_axis_dividend_tdata.m_axis_dout_tvalid(), // output wire m_axis_dout_tvalid.m_axis_dout_tdata(temp_green_new) // output wire [31 : 0] m_axis_dout_tdata
);//进行判断
always (posedge clk or posedge rst) beginif (rst 1b1) begingreen_new d0;endelse if (temp_green_new[26:8] d255) begingreen_new d255;endelse begingreen_new temp_green_new[15:8];end
end//blue_new
mult_gen_8xKavg bluexKavg (.CLK(clk), // input wire CLK.A(blue), // input wire [7 : 0] A.B(Kavg[10:0]), // input wire [10 : 0] B.P(temp_blue) // output wire [18 : 0] P
);div_gen_0 temp_blue_div_Bavg (.aclk(clk), // input wire aclk.s_axis_divisor_tvalid(hsync_dly[2]), // input wire s_axis_divisor_tvalid.s_axis_divisor_tdata(Bavg), // input wire [7 : 0] s_axis_divisor_tdata.s_axis_dividend_tvalid(hsync_dly[2]), // input wire s_axis_dividend_tvalid.s_axis_dividend_tdata(temp_blue), // input wire [23 : 0] s_axis_dividend_tdata.m_axis_dout_tvalid(), // output wire m_axis_dout_tvalid.m_axis_dout_tdata(temp_blue_new) // output wire [31 : 0] m_axis_dout_tdata
);always (posedge clk or posedge rst) beginif (rst 1b1) beginblue_new d0;endelse if (temp_blue_new[26:8] d255) beginblue_new d255;endelse beginblue_new temp_blue_new[15:8];end
end//不是数据没有对齐的问题
always (posedge clk) beginfra_hsy temp_fra_hsy;
end//fra_vsy可以随便一个
assign fra_vsy vsync_dly[1];endmodule
第三部分、实现结果
1、白平衡前后对比 没有白平衡之前CMOS采集到的图像偏绿白平衡之后效果就好多了 CMOS摄像头图像白平衡之前和白平衡之后的效果
2、总结 这篇主要是总结了一下白平衡算法的原理的实现方法我上面的Verilog 代码大家只需要看明白就可以移植了。 QQ交流群聊号码1020775171有疑问的小伙伴可以加入哦 本专栏有很多我个人总结的比较好的文章希望对你开发有帮助FPGA的学习之旅_大屁桃的博客-CSDN博客
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/87799.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!