原创 数字图像与C语言之图像中的物体提取

2011-1-20 02:40 5412 3 3 分类: 处理器与DSP

1.何谓“提取”

图像处理技术中,常用的“提取”技术是指把不想要的东西除去,只把想要的对象部分的图像取出,分离出来。图像中有火车模型,我们想从中提取出火车模型。首先应着眼于火车模型的亮度、颜色和形状特点等差异,可以有很多种处理方法,最简单的方法,称为阈值处理。

2.利用阈值提取

图像中为“会”字,想从中把文字部分提取出来。阈值处理的主要思路是,对于输入图像的各个像素,先确定某个亮度值(即阈值)。当像素的亮度超过该阈值时,则将对应输出图像的像素值设为1,否则设为0.阈值处理后的值,并非1或者0,采用的是high或者low。随着不同给定的阈值,所提取出来的对象的情况很不一样,所以阈值的确定非常重要。

3.阈值的确定

采用直方图法能有效的确定阈值。所谓的直方图是指表示具有浓度值为i的像素有多少个的频度分布直方图。他可以利用程序2求出来。程序3用来打印直方图。要显示直方图的图像用程序4。

图像直方图中,参差不齐之处太多,何为二值分界的谷地值很难分出。因此需要采用另一种课清楚容易的分清分界谷地值的方法,即可使邻近直方图平均化,见程序5,就是采用5点平滑化的改进直方图程序清单。这样就能看到阈值在148附近。

4.决定阈值的其他方法

ptile法:当提取的物体占用全部图像的比例比较清楚时,所应选用的方法,以暗方(或由亮方)的p%处作为阈值最佳。

判别分析法:先按物体与背景把直方图分为两个集团,在根据两个集团统计量的差别决定阈值的方法。

可变阈值法:则当背景亮度不一样是比较有效,可对每种场所选用不同的变化的阈值。

附录程序如下:

1.阈值处理

#include"params.h"

/*****threshold:阈值处理

image_out:输出图像数据

image_in:输入图像数据

thresh:阈值

mode:阈值处理方法(1.2)

*****/

void threshold(unsigned char image_in[ysize][xsize],unsigned char image_out[ysize][xsize],int mode)

{

  int i,j;

  for(i=0;i<ysize;i++)

  {

    for(j=0;j<xsize;j++)

     {

       switch(mode)

       {  case 2:

          if((int) image_in[j]<=threash)

          image_out[j]<=high;

          else

          image_out[j]<=low;

        break;

       default:

          if((int) image_in[j]>=threash)

          image_out[j]<=high;

          else

          image_out[j]<=low;

        break;

       }

      }

     } 

  }

2.求直方图

#include"params.h"

/******histgram--

  image_in:

  hist:

******/

void histgram(unsigned char image_in[xzise][ysize],long hist[256])

{

int i,j,n;

for(n=0;n<256;n++) hist[n]=0;

for(i=0;i<ysize;i++)

  {

    for(j=0;j<xsize;j++)

   {

     n=image_in[j];

     hist[n]++;

  }

}

}

3.以数字与字母把直方图打印出来

#include<stdio.h>

#include"params.h"

/******--histprint---以数值与字母把直方图打印出来

hist:直方图

buf:信息用缓冲区

*******/

void histprint(long hist[256],char *buf)

{

int i,j,k;

float p,q,max;

int posi,m;

posi=0;

p=xsize*ysize;

max=0;

for(i=0;i<256;i++)

if(hist>max) max=(float) hist;

for(i=0;i<256;i++){

 q=(float)((float)hist/p*100.0);

m=sprintf(&buf[posi],"%3d:%5.1f%%",i,q);

posi+=m;

k=(int)((float)hist/max*60.0);

for(j=0;j<k;j++)

{

m=sprintf(&buf[posi],"*");

posi+=m;

}

m=sprintf(&buf[posi],"\n");

post+=m;

}

}

4.把直方图图像化

#include"params.h"

/*---histimage---把直方图图像化(其中xsize>64)

hist:直方图

image hist:输出图像数组

---------*/

void histimage(long hist[256],unsinged char image_hist[ysize][xsize])

{
 int i,j,k,max,range;
 long n;
 float d;
 range=ysize-5;
 for(i=0;i<ysize;i++)
 {
  for(j=0;j<ysize;j++)
  {
   image_hist[j]=low;
  }
 }
if(xsize>=256)
{
 max=0;
 for(i=0;i<256;i++)
 {
  n=hist;
  if(n>max) max=n;
 }
 for(i=0;i<256;i++)
 {
  d=(float)hist;
  n=(long)(d/(float)max*(float)range);
  for(j=0;j<=n;j++) image_hist[range-j]=high;
 }
 for(i=0;i<=4;i++)
 {
  k=64*i;
  if(k>xsize) k=xszie-1;
  for(j=range;j<ysize;j++) image_hist[j]=high;
 }
}
else if(x_size>=128)
{
 max=0;
 for(i=0;i<128;i++)
 {
  n=hist[i*2]+hist[2*i+1];
  if(n>max) max=n;
 }
 for(i=0;i<128;i++)
 {
  d=(float)(hist[i*2]+hist[i*2+1]);
  n=(long)(d/(float)max*(float)range);
  for(j=0;j<=n;j++) image_hist[range-j]=high;
 }
 for(i=0;i<=4;i++)
 {
  k=32*i;
  if(k>xsize) k=xszie-1;
  for(j=range;j<ysize;j++) image_hist[j]=high;
 }
}
else if(xsize>=64)
{
 max=0;
  for(i=0;i<64;i++)
 {
  n=(hist[i*4]+hist[4*i+1]+hist[i*4+2]+hist[4*i+3]);
  if(n>max) max=n;
 }
 for(i=0;i<128;i++)
 {
  d=(float)(hist[i*4]+hist[4*i+1]+hist[i*4+2]+hist[4*i+3]);
  n=(long)(d/(float)max*(float)range);
  for(j=0;j<=n;j++) image_hist[range-j]=high;
 }
 for(i=0;i<=4;i++)
 {
  k=16*i;
  if(k>xsize) k=xszie-1;
  for(j=range;j<ysize;j++) image_hist[j]=high;
 }
}
}


 

5.把直方图平滑化

#include "params.h"
/***----histsmooth--把直方图平滑化
hist_in:直方图平滑化前
hist_out:直方图平滑化后
*****/
void histsmooth(long hist_in[256],long hist_out[256])
{
 int m,n,i;
 long sum;
 for(n=0;n<256;n++)
 {
   sum=0;
   for(m=-2;m<=2;m++)
   {
    i=n+m;
    if(i<0) i=0;
    if(i>255)i=255;
    sum=sum+hist_in;
   }
   hist_out[n]=(long)((float)sum/5.0+0.5);
 }
}

 

}

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
3
关闭 站长推荐上一条 /3 下一条