Chinaunix首页 | 论坛 | 博客
  • 博客访问: 279461
  • 博文数量: 109
  • 博客积分: 2116
  • 博客等级: 大尉
  • 技术积分: 1062
  • 用 户 组: 普通用户
  • 注册时间: 2009-10-22 15:38
文章分类

全部博文(109)

文章存档

2013年(2)

2011年(16)

2010年(90)

2009年(1)

我的朋友

分类:

2011-01-07 20:37:44

原理
利用计算机进行图像处理有两个目的:一是产生更适合人观察和识别的图像;二是希望能由计算机自动识别和理解图像。无论为了哪种目的,图像处理中关键的一步就是对包含有大量各式各样景物信息的图像进行分解。分解的最终结果是图像被分解成一些具有某种特征的最小成分,成为图像的基元。相对于整幅图像来说,这种基元更容易被快速处理。
图像的特征指图像场中可用作标志的属性。它可以分为图像的统计特征和图像的视觉特征两类。图像的统计特征是指一些人为定义的特征,通过变换才能得到,如图像的直方图、频谱等等;图像的视觉特征是指人的视觉可直接感受到的自然特征,如区域的亮度、纹理或轮廓等。利用这两类特征把图像分解成一系列有意义的目标或区域的过程称为图像的分割
图像的边缘是图像的最基本特征。所谓边缘 ( 或边沿 ) 是指其周围像素灰度有阶跃变化或屋顶变化的那些像素的集合。边缘广泛存在于物体与背景之间、物体与物体之间、基元与基元之间 。因此,它是图像分割所依赖的重要特征。
物体的边缘是由灰度不连续性所反映的。经典的边缘提取方法是考察图像的每个像素在某个邻域内灰度的变化,利用边缘临近一阶或二阶方向导数变化规律,用简单的方法检测边缘。这种方法称为边缘检测局部算子法
边缘的种类可以分为两种:一种称为阶跃性边缘,它两边的像素的灰度值有着显著的不同;另一种称为屋顶状边缘,它位于灰度值从增加到减少的变化转折点。对于阶跃性边缘,二阶方向导数在边缘处呈零交叉;而对于屋顶状边缘,二阶方向导数在边缘处取极值。边缘检测算子检查每个像素的邻域并对灰度变化率进行量化,也包括方向的确定。大多数使用基于方向导数掩模求卷积的方法。
Sobel 边缘算子:下图所示的两个卷积核形成了 sobel 算子,图像中的每个点都用这两个核做卷积,一个核对通常的垂直边缘相应最大,而另一个对水平边缘相应最大。两个卷积的最大值作为该点的输出位。运算结果是一幅边缘幅度图像。
-1 -2 -1
0   0  0
1   2  1

-1 0 1
-2 0 2
-1 0 1
Prewitt 边缘算子:下图所示的两个卷积核形成了 Prewitt 算子。和使用 Sobel 算子的方法一样,图像中的每个点都用这两个核进行卷积,取最大值作为输出。 Prewitt 算子也产生一幅边缘幅度图像。
-1 -1 -1
 0  0  0
 1  1  1

-1 0 1
-1 0 1
-1 0 1


边缘提取代码:
-----------------------------------------------------------------------------------------------
void ICETEKDM6437B2BoardInit()
{
    m_nOffset1=0;
    m_nOffset2=MWIDTH;
    m_nOffset3=MWIDTH*2;
    for ( mi=0;mi        cLines[mi]=0;
}
------------------------------------------------------------------------------------------------
 pWork = src = dst = (Uint8 *)frameBuffPtr->frame.frameBufferPtr;

        for ( i = 0 ; i < inputHeight ; i ++ )
        {
            for(j = 0 ; j < inputWidth ; j++)
            {
                /* remove the color information */
                *pWork++ = 0x80;pWork++;
            }
            /* draw the edge_counter_sobel on screen */
            if ( i>144 && i<432 )
                ICETEKDM6437B2EdgeCounterSobel(src + i * inputWidth * 2, inputWidth);
        }
------------------------------------------------------------------------------------------------
void ICETEKDM6437B2EdgeCounterSobel(unsigned char * src, short pixelCount)
{
    src += 180;
    for ( mi=0;mi    {
        *(cLines+m_nOffset3+mi) = src[mi * 2 + 1];
    }

    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    {
        x3=(*pImg1); x6=(*pImg2); x9=(*pImg3);
        m_nWork1=x7+x8+x8-x2-x2-x3;//核1
        m_nWork2=x3+x6+x6-x4-x4-x7;//核2
/*
如果使用Prewitt 边缘算子
,这两式应为
m_nWork1=x7+x8-x2-x3;
m_nWork2=x3+x6-x4-x7;
*/
        if ( m_nWork1            m_nWork1=m_nWork2;//max
        m_nWork2=m_nWork1+x9-x1;
        if ( m_nWork2>255 )    m_nWork2=255;
        else if ( m_nWork2<0 )    m_nWork2=0;
        src[mi * 2 + 1]=m_nWork2;
        x1=x2; x2=x3;
        x4=x5; x5=x6;
        x7=x8; x8=x9;
    }
    src[mi * 2 + 1]=0;
    m_nWork=m_nOffset1; m_nOffset1=m_nOffset2;
    m_nOffset2=m_nOffset3; m_nOffset3=m_nWork;
}

阅读(10321) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~