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);
}
}
}
文章评论(0条评论)
登录后参与讨论