改善OV5640的锯齿现象(应用梯度导向算法)

来源:互联网 发布:图片怎么上传淘宝店铺 编辑:程序博客网 时间:2024/06/01 09:09

关于梯度导向算法的内容来自于http://blog.chinaaet.com/crazybingo/p/32548

来看bayer pattern,其中的一部分示意图如下:

  

因为人眼对绿色分量最为敏感,因此G分量占的比重大,为像素总数的一半;像素总数的四分之一为R,四分之一为B。将Bayer Raw图像转换为RGB图像,本系统尝试过两种算法:1.双线性插值法。2.边缘导向算法。双线性插值法就是使用周围邻域像素来恢复自身像素值的办法,

 

R在中间,四边G,四角B的排列为例,其中,像素的下标为坐标。

 

对于(2,2)点像素,RR22G为(G12+G21+G23+G32/4B为(B11+B13+B31+B33/4

双线性插值算法实现简单,并且适合用FPGA流水线方式进行操作,在平滑的区域有比较好的实现效果,但是在图像的轮廓区域,由于像素的取值并没有考虑到方向性,采用双线性插值算法,将产生锯齿状的效应,大大影响图像质量。

为了克服双线性插值算法带来的图像轮廓的锯齿效应,本系统考虑到第二种算法:边缘导向插值算法。这种插值算法通过比较水平方向、垂直方向和对角线方向的梯度大小,选择梯度较小方向上的像素点,来计算当前像素值。仍然以R在中间,四边G,四角B的排列为例:

 

 

 

 

因为边缘导向插值算法考虑到了图像边缘区域的变化,因此可以避免边缘区域的锯齿现象。本系统通过对比两种算法,在资源足够的情况下,采用了效果更好的边缘导向插值算法。

将RAW2RGB的源码粘贴如下:

moduleRAW2RGB(iCLK,iRST_N,//Read Port 1iDATA,iDVAL,oRed,oGreen,oBlue,oDVAL,iZoom,iX_Cont,iY_Cont);//--------------------------------------------------//parameterDATA_SIZE=10;inputiCLK,iRST_N;input[DATA_SIZE-1:0]iDATA;inputiDVAL;output[DATA_SIZE-1:0]oRed;output[DATA_SIZE-1:0]oGreen;output[DATA_SIZE-1:0]oBlue;outputoDVAL;input[1:0]iZoom;input[15:0]iX_Cont;input[15:0]iY_Cont;wire[DATA_SIZE-1:0]wData0;wire[DATA_SIZE-1:0]wData1;wire[DATA_SIZE-1:0]wData2;reg[DATA_SIZE-1:0]rRed;reg[DATA_SIZE-1:0]rGreen;reg[DATA_SIZE-1:0]rBlue;regrDval;reg[DATA_SIZE-1:0]wData0_d1,wData0_d2;reg[DATA_SIZE-1:0]wData1_d1,wData1_d2;reg[DATA_SIZE-1:0]wData2_d1,wData2_d2;regoDVAL;regdval_ctrl;regdval_ctrl_en;//outassignoRed=rRed;assignoGreen=rGreen;assignoBlue=rBlue;LineBuffer_vhdlL1(.clken(iDVAL),.aclr(~iRST_N),.clock(iCLK),.shiftin(iDATA),.shiftout(),.taps({wData2,wData1,wData0}));always@(posedge iCLK or negedge iRST_N)beginif (!iRST_N)begindval_ctrl<=0;endelsebeginif(iY_Cont>1)begindval_ctrl<=1;endelsebegindval_ctrl<=0;endendendalways@(posedge dval_ctrl or negedge iRST_N)beginif (!iRST_N)begindval_ctrl_en<=0;endelsebegindval_ctrl_en<=1;endendalways@(posedge iCLK or negedge iRST_N)beginif (!iRST_N)beginrDval<=0;oDVAL <= 0;endelseif(dval_ctrl_en)beginrDval<=iDVAL;oDVAL<=rDval;endelsebeginrDval<=iDVAL;oDVAL<=0;endendalways@(posedge iCLK or negedge iRST_N)beginif (!iRST_N)beginwData0_d1<=0;wData0_d2<=0;wData1_d1<=0;wData1_d2<=0;wData2_d1<=0;wData2_d2<=0;endelsebegin{wData0_d2,wData0_d1}<={wData0_d1,wData0};{wData1_d2,wData1_d1}<={wData1_d1,wData1};{wData2_d2,wData2_d1}<={wData2_d1,wData2};endendalways@(posedge iCLK or negedge iRST_N)beginif (!iRST_N)beginrRed<=0;rGreen<=0;rBlue<=0;endelse if ({iY_Cont[0],iX_Cont[0]} == 2'b00)//2'b11begin    rRed<=wData1_d1;            //Hg > Vg            if( (wData1_d2 >= wData1 && wData2_d1 >= wData0_d1 && (wData1_d2- wData1)>(wData2_d1-wData0_d1) )||             ( wData1_d2 >=  wData1 && wData2_d1 < wData0_d1 && (wData1_d2 - wData1)>(wData0_d1 - wData2_d1) ) ||            ( wData1_d2 < wData1 && wData2_d1 >= wData0_d1 && (wData1 - wData1_d2)>(wData2_d1 - wData0_d1) ) ||            ( wData1_d2 < wData1 && wData2_d1 < wData0_d1 && (wData1 - wData1_d2)>(wData0_d1 - wData2_d1) )                     )            rGreen<=(wData2_d1+ wData0_d1)/2;            //Hg < Vg            if( (wData1_d2 >= wData1 && wData2_d1 >= wData0_d1 && (wData1_d2- wData1)<(wData2_d1-wData0_d1) )||             ( wData1_d2 >=  wData1 && wData2_d1 < wData0_d1 && (wData1_d2 - wData1)<(wData0_d1 - wData2_d1) ) ||            ( wData1_d2 < wData1 && wData2_d1 >= wData0_d1 && (wData1 - wData1_d2)<(wData2_d1 - wData0_d1) ) ||            ( wData1_d2 < wData1 && wData2_d1 < wData0_d1 && (wData1 - wData1_d2)<(wData0_d1 - wData2_d1) )                     )            rGreen<=(wData1_d2+ wData1)/2;            //Hg = Vg            if( (wData1_d2 >= wData1 && wData2_d1 >= wData0_d1 && (wData1_d2- wData1)==(wData2_d1-wData0_d1) )||             ( wData1_d2 >=  wData1 && wData2_d1 < wData0_d1 && (wData1_d2 - wData1)==(wData0_d1 - wData2_d1) ) ||            ( wData1_d2 < wData1 && wData2_d1 >= wData0_d1 && (wData1 - wData1_d2)==(wData2_d1 - wData0_d1) ) ||            ( wData1_d2 < wData1 && wData2_d1 < wData0_d1 && (wData1 - wData1_d2)==(wData0_d1 - wData2_d1) )                     )                    rGreen<=(wData1+wData2_d1+wData1_d2 + wData0_d1)/4;                                //Db1 > Db2            if( (wData2_d2 >= wData0 && wData2 >= wData0_d2 && (wData2_d2- wData0)>(wData2-wData0_d2) )||             (wData2_d2 >= wData0 && wData2 < wData0_d2 && (wData2_d2- wData0)>(wData0_d2 - wData2) )||             (wData2_d2 < wData0 && wData2 >= wData0_d2 && (wData0 - wData2_d2)>(wData2-wData0_d2) )||             (wData2_d2 < wData0 && wData2 < wData0_d2 && (wData0 - wData2_d2)>(wData0_d2 - wData2) ) )            rBlue<=(wData2+wData0_d2)/2;            //Db1 < Db2                    if( (wData2_d2 >= wData0 && wData2 >= wData0_d2 && (wData2_d2- wData0)<(wData2-wData0_d2) )||             (wData2_d2 >= wData0 && wData2 < wData0_d2 && (wData2_d2- wData0)<(wData0_d2 - wData2) )||             (wData2_d2 < wData0 && wData2 >= wData0_d2 && (wData0 - wData2_d2)<(wData2-wData0_d2) )||             (wData2_d2 < wData0 && wData2 < wData0_d2 && (wData0 - wData2_d2)<(wData0_d2 - wData2) ) )            rBlue<=(wData2_d2+wData0)/2;            //Db1 = Db2                        if( (wData2_d2 >= wData0 && wData2 >= wData0_d2 && (wData2_d2- wData0)==(wData2-wData0_d2) )||             (wData2_d2 >= wData0 && wData2 < wData0_d2 && (wData2_d2- wData0)==(wData0_d2 - wData2) )||             (wData2_d2 < wData0 && wData2 >= wData0_d2 && (wData0 - wData2_d2)==(wData2-wData0_d2) )||             (wData2_d2 < wData0 && wData2 < wData0_d2 && (wData0 - wData2_d2)==(wData0_d2 - wData2) ) )            rBlue<=(wData0+wData2+wData0_d2 + wData2_d2)/4;        endelse if ({iY_Cont[0],iX_Cont[0]} == 2'b01)//2'b10begin    rRed<=(wData1+wData1_d2)/2;            rGreen<=(wData0+wData2+wData0_d2 + wData2_d2)/4;            rBlue<=(wData0_d1+wData2_d1)/2;    endelse if ({iY_Cont[0],iX_Cont[0]} == 2'b10)//2'b01begin    rRed<=(wData2_d1+wData0_d1)/2;            rGreen<=(wData0+wData2+wData0_d2 + wData2_d2)/4;            rBlue<=(wData1+wData1_d2)/2;endelse if ({iY_Cont[0],iX_Cont[0]} == 2'b11)//2'b00beginrBlue<=wData1_d1;            //Hg > Vg            if( (wData1_d2 >= wData1 && wData2_d1 >= wData0_d1 && (wData1_d2- wData1)>(wData2_d1-wData0_d1) )||             ( wData1_d2 >=  wData1 && wData2_d1 < wData0_d1 && (wData1_d2 - wData1)>(wData0_d1 - wData2_d1) ) ||            ( wData1_d2 < wData1 && wData2_d1 >= wData0_d1 && (wData1 - wData1_d2)>(wData2_d1 - wData0_d1) ) ||            ( wData1_d2 < wData1 && wData2_d1 < wData0_d1 && (wData1 - wData1_d2)>(wData0_d1 - wData2_d1) )                     )            rGreen<=(wData2_d1+ wData0_d1)/2;            //Hg < Vg            if( (wData1_d2 >= wData1 && wData2_d1 >= wData0_d1 && (wData1_d2- wData1)<(wData2_d1-wData0_d1) )||             ( wData1_d2 >=  wData1 && wData2_d1 < wData0_d1 && (wData1_d2 - wData1)<(wData0_d1 - wData2_d1) ) ||            ( wData1_d2 < wData1 && wData2_d1 >= wData0_d1 && (wData1 - wData1_d2)<(wData2_d1 - wData0_d1) ) ||            ( wData1_d2 < wData1 && wData2_d1 < wData0_d1 && (wData1 - wData1_d2)<(wData0_d1 - wData2_d1) )                     )            rGreen<=(wData1_d2+ wData1)/2;            //Hg = Vg            if( (wData1_d2 >= wData1 && wData2_d1 >= wData0_d1 && (wData1_d2- wData1)==(wData2_d1-wData0_d1) )||             ( wData1_d2 >=  wData1 && wData2_d1 < wData0_d1 && (wData1_d2 - wData1)==(wData0_d1 - wData2_d1) ) ||            ( wData1_d2 < wData1 && wData2_d1 >= wData0_d1 && (wData1 - wData1_d2)==(wData2_d1 - wData0_d1) ) ||            ( wData1_d2 < wData1 && wData2_d1 < wData0_d1 && (wData1 - wData1_d2)==(wData0_d1 - wData2_d1) )                     )                    rGreen<=(wData1+wData2_d1+wData1_d2 + wData0_d1)/4;                                    //Db1 > Db2            if( (wData2_d2 >= wData0 && wData2 >= wData0_d2 && (wData2_d2- wData0)>(wData2-wData0_d2) )||             (wData2_d2 >= wData0 && wData2 < wData0_d2 && (wData2_d2- wData0)>(wData0_d2 - wData2) )||             (wData2_d2 < wData0 && wData2 >= wData0_d2 && (wData0 - wData2_d2)>(wData2-wData0_d2) )||             (wData2_d2 < wData0 && wData2 < wData0_d2 && (wData0 - wData2_d2)>(wData0_d2 - wData2) ) )            rRed<=(wData2+wData0_d2)/2;            //Db1 < Db2                    if( (wData2_d2 >= wData0 && wData2 >= wData0_d2 && (wData2_d2- wData0)<(wData2-wData0_d2) )||             (wData2_d2 >= wData0 && wData2 < wData0_d2 && (wData2_d2- wData0)<(wData0_d2 - wData2) )||             (wData2_d2 < wData0 && wData2 >= wData0_d2 && (wData0 - wData2_d2)<(wData2-wData0_d2) )||             (wData2_d2 < wData0 && wData2 < wData0_d2 && (wData0 - wData2_d2)<(wData0_d2 - wData2) ) )            rRed<=(wData2_d2+wData0)/2;            //Db1 = Db2                        if( (wData2_d2 >= wData0 && wData2 >= wData0_d2 && (wData2_d2- wData0)==(wData2-wData0_d2) )||             (wData2_d2 >= wData0 && wData2 < wData0_d2 && (wData2_d2- wData0)==(wData0_d2 - wData2) )||             (wData2_d2 < wData0 && wData2 >= wData0_d2 && (wData0 - wData2_d2)==(wData2-wData0_d2) )||             (wData2_d2 < wData0 && wData2 < wData0_d2 && (wData0 - wData2_d2)==(wData0_d2 - wData2) ) )            rRed<=(wData0+wData2+wData0_d2 + wData2_d2)/4;    endendendmodule

1 0