基于FPGA的Bayer转RGB算法实现

1 概述

       Bayer转RGB在图像处理中被称为去马赛克(Demosaic),是机器视觉ISP流程中的一个基础且重要的算法,主要完成彩色图像传感器原始的Bayer格式图像到RGB格式图像的转换。

       关于Bayer图像的相关概念和知识,本文不作介绍。常见知识点以及各种Bayer转RGB算法的介绍网上有很多博文可以参考学习:

https://www.cnblogs.com/qiqibaby/p/5267566.html

三种Bayer数据的插值算法(CCD插值算法)_bayer插值_simple_96的博客-CSDN博客

https://www.cnblogs.com/qiqibaby/p/8719252.html

https://www.cnblogs.com/sunny-li/p/8641767.html

http://www.voidcn.com/article/p-zeuhnrel-ww.html

       Bayer转RGB的核心思想就是色彩插值。各种不同算法主要目的都是真实还原图像的色彩,并解决物体边缘、色彩变化处出现的拉链效应和色彩混叠现象。

2 基于梯度校正的线性插值法

       Bayer转RGB的算法有很多种,很多算法在插值过程中都会考虑领域色彩的梯度,根据梯度对插值结果进行补偿或校正。考虑到在FPGA中实现的效果和资源使用问题,选取了一种经典的算法:gradient-corrected linear interpolation,出自微软研究院,该算法被matlab中的demosaic函数所使用。

       算法论文链接:High-quality linear interpolation for demosaicing of Bayer-patterned color images – Microsoft Researchhttps://www.microsoft.com/en-us/research/publication/high-quality-linear-interpolation-for-demosaicing-of-bayer-patterned-color-images/
       该算法的主要原理为:在5*5大小的窗口中,利用中心点像素所属颜色的梯度值对其它颜色的插值结果进行补偿。其中,R和B都考虑了上下左右4个方向的梯度;G除了上下左右4个方向,还考虑了4个对角线方向的梯度,这应该是由于G的像素点个数是R和B的2倍,而且人眼对于绿色的敏感度更强。

       一共有8种情况,4种计算公式。如下图所示:

       4种顺序的bayer阵列对应的R、G、B插值方式如下图所示:

        算法对应的matlab程序为:

function out=bayer_to_rgb(in) 
m=size(in,1);n=size(in,2); 
 
outR=in; 
outG=in; 
outB=in; 
 
%rg 
%gb 
for i=3:2:m-3 
    for j=3:2:n-3 
        outR(i,j)=in(i,j)*8; 
        outG(i,j)=(in(i-1,j)+in(i,j-1)+in(i,j+1)+in(i+1,j))*2-(in(i-2,j)+in(i+2,j)+in(i,j-2)+in(i,j+2))+in(i,j)*4; 
        outB(i,j)=(in(i-1,j-1)+in(i-1,j+1)+in(i+1,j-1)+in(i+1,j+1))*2-(in(i-2,j)+in(i,j-2)+in(i,j+2)+in(i+2,j))*3/2+in(i,j)*6; 
    end 
end 
 
%gr 
%bg 
for i=3:2:m-3 
    for j=4:2:n-2 
        outR(i,j)=in(i,j-1)*4+in(i,j+1)*4+(in(i-2,j)+in(i+2,j))/2-(in(i-1,j-1)+in(i-1,j+1)+in(i+1,j-1)+in(i+1,j+1)+in(i,j-2)+in(i,j+2))+in(i,j)*5; 
        outG(i,j)=in(i,j)*8; 
        outB(i,j)=(in(i-1,j)+in(i+1,j))*4-(in(i-2,j)+in(i-1,j-1)+in(i-1,j+1)+in(i+1,j-1)+in(i+1,j+1)+in(i+2,j))+(in(i,j-2)+in(i,j+2))/2+in(i,j)*5; 
    end 
end
 
%gb 
%rg 
for i=4:2:m-2 
    for j=3:2:n-3 
        outR(i,j)=(in(i-1,j)+in(i+1,j))*4-(in(i-2,j)+in(i-1,j-1)+in(i-1,j+1)+in(i+1,j-1)+in(i+1,j+1)+in(i+2,j))+(in(i,j-2)+in(i,j+2))/2+in(i,j)*5; 
        outG(i,j)=in(i,j)*8; 
        outB(i,j)=(in(i,j-1)+in(i,j+1))*4-(in(i-1,j-1)+in(i-1,j+1)+in(i,j-2)+in(i,j+2)+in(i+1,j-1)+in(i+1,j+1))+(in(i-2,j)+in(i+2,j))/2+in(i,j)*5; 
    end 
end 
 
%bg 
%gr 
for i=4:2:m-2 
    for j=4:2:n-2 
        outR(i,j)=(in(i-1,j-1)+in(i-1,j+1)+in(i+1,j-1)+in(i+1,j+1))*2-(in(i-2,j)+in(i,j-2)+in(i,j+2)+in(i+2,j))*3/2+in(i,j)*6; 
        outG(i,j)=(in(i-1,j)+in(i,j-1)+in(i,j+1)+in(i+1,j))*2-(in(i-2,j)+in(i,j-2)+in(i,j+2)+in(i+2,j))+in(i,j)*4; 
        outB(i,j)=in(i,j)*8; 
    end 
 
end 

out(:,:,1)=outR/8; 
out(:,:,2)=outG/8; 
out(:,:,3)=outB/8;

       原始bayer图:

       插值后的RGB图:

 3 FPGA实现

       上述算法的计算过程非常适合FPGA实现,首先在FPGA中实现1个5*5的滑动窗口模块。滑动窗口模块设计见作者这篇博客:

https://blog.csdn.net/MmikerR/article/details/107933017?spm=1001.2014.3001.5502

       然后按照4个公式分别对R、G、B像素点的值进行计算即可。需要注意的是,8种插值情况可以通过将4个公式复用2次来实现,这样可以减少50%的加减运算及对应的FPGA资源。

       需要源码请私信。

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
心中带点小风骚的头像心中带点小风骚普通用户
上一篇 2023年12月6日
下一篇 2023年12月6日

相关推荐