Sobel边缘提取算法(DSP)

1.  把数据从视频通道通过一维方式传送到片内RAM中并作Sobel边缘提取算法。

我们只对摄像头采集的一块数据进行Sobel边缘提取。采用一维EDMA传送方式,每一次传送采集的一行中的部分数据(DAT_copy()函数)。在PAL制式下,先把一行数据放到nMemTemp数组中,比如我们要把从144行到432行,从180列到435列的图像进行Sobel边缘提取,最后把变换后的数据输出到显示缓冲区。     

unsigned char nMemTemp[720];

for ( i = 0; i < numLines; i ++ )   {  m_nID=DAT_copy(capFrameBuf->frame.iFrm.y1+i*capLinePitch,nMemTemp,numPixels);

     DAT_wait(m_nID);

     if ( i>144 && i<432 )

     Sobel();     DAT_copy(nMemTemp,disFrameBuf->frame.iFrm.y1+i*disLinePitch,numPixels);

}

因为Sobel算法需要三行数据,我们可以开辟一个可以存放三行数据的缓冲区,通过指针的交换把从视频通道过来的数据分别放到缓冲区中。保存的三行图像使用翻卷的缓冲区管理,三个变量分别指示当前使用的y行、y-1行和y-2行在缓冲区中的起始偏移量。我们可以这样来做:轮流往三块缓存区拷贝数据。只要拷贝的指针变化就可以。在我们拷贝当前这一块的时候,已经拷贝的另外两块数据依然没有变化,所以我们就可以实现三块数据保存采集图像中的相邻的三行数据。如下:

 

缓冲区1

cLines[0-255]

缓冲区2

cLines[256-512]

缓冲区3

cLines[513-768]

                缓存区分配

三个指针*pImg1,*pImg2,*pImg3分别轮流指向三个缓冲区。

    m_nOffset1=0;

    m_nOffset2=256;

    m_nOffset3=512;

unsigned char cLines[256*3];

void Sobel()

{

    unsigned int m_nID;

    m_nID=DAT_copy(nMemTemp+180,cLines+m_nOffset3,256);

    pImg1=cLines; pImg1+=m_nOffset1;

    pImg2=cLines; pImg2+=m_nOffset2;

    pImg3=cLines; pImg3+=m_nOffset3;

    x1=(*pImg1); pImg1++; x2=(*pImg1); pImg1++;

    x4=(*pImg2); pImg2++; x5=(*pImg2); pImg2++;

    x7=(*pImg3); pImg3++; x8=(*pImg3); pImg3++;

    for ( mi=0;mi<256;mi++,pImg1++,pImg2++,pImg3++ )

    {

        x3=(*pImg1); x6=(*pImg2); x9=(*pImg3);

        m_nWork1=x7+x8+x8-x2-x2-x3;

        m_nWork2=x3+x6+x6-x4-x4-x7;

        if ( m_nWork1<m_nWork2 )

            m_nWork1=m_nWork2;

        m_nWork2=m_nWork1+x9-x1;

        if ( m_nWork2>255 ) m_nWork2=1;

        else if ( m_nWork2<0 )  m_nWork2=0;

        nMemTemp[mi+180]=m_nWork2;

        x1=x2; x2=x3;

        x4=x5; x5=x6;

        x7=x8; x8=x9;

    }

nMemTemp[mi]=0;

    m_nWork=m_nOffset1; m_nOffset1=m_nOffset2;

    m_nOffset2=m_nOffset3; m_nOffset3=m_nWork;

}

2.  把数据从视频通道通过二维方式传送到SDRAM并作Sobel边缘提取算法。

我们可以通过DAT_copy2d()函数直接把采集的一幅图像亮度分量存放到SDRAM中,如下:

DAT_copy2d(DAT_2D2D,

                capFrameBuf->frame.iFrm.y1,

                    m_dbFrameBufferTemp,

                        numPixels,

                          numLines,

                            numPixels);

其中:m_dbFrameBufferTemp是指向SDRAM中缓冲区的指针,numPixels是一行的象素数,numLines是行数。当把数据存放到SDRAM的一个数组中后,Sobel算法的实现就非常简单了。当然也可以参照一维的方法来实现。

你可能感兴趣的:(算法)