stm32f407使用OV7725进行采集数据,显示到LCD屏幕上面,再进行灰度处理,然后再寻找图像分割的灰度阈值,进行图像二值化。
关于图像分科可以自己百度。。。。
首先进行摄像头的图像采集,使用的是野火带FIFO的OV7725摄像头,帧速率有点慢,但是勉强还能采集数据显示。
但是在采集数据的时候,注意读时序要时间问题,否则会因为时序问题导致图像漂移,如下图:
所以在代码里面的void ImagDisp(void)函数里面处理数据要少。
函数里面void OV7725_GRAY_Serial(void)函数是数据发送给上位机查看灰度图等级直方图和曲线,附件里面带labview的直方图上位机子VI。
接下来是重点,迭代阈值法。
首先来迭代阈值法的思想,主要是下面4条:
迭代法是基于逼近的思想,其步骤如下:
1. 求出图象的最大灰度值和最小灰度值,分别记为Pmax和Pmin,令初始阈值T0=(Pmax+Pmin)/2;
2. 根据阈值T(k)(k=0,1,2…,k)将图象分割为前景和背景,分别求出两者的平均灰度值H1和H2;
3. 求出新阈值T(k+1)=(H1+H2)/2;
4. 若 T(k)-T(k+1)=X (一个预定义的参数范围内,自己设定),则所得即为阈值;否则转2,迭代计算。
这样就可以逐渐逼近图像二值化阈值,不必使用上位机查看大概的阈值,然后手动分割。
具体函数如下:
#define PIXEL_W 320 //设定的采集图像的长
#define PIXEL_H 180 //设定的采集图像的宽
/****************************************************
* 函数名:Itera_Threshold
* 功 能:迭代阈值法,能够找到灰度图的最佳二值化点
****************************************************/
void Itera_Threshold(void)
{
u16 i=0,j=0,k=0,cnt=0,mux=0,Camera_Data=0;
u8 newthreshold=0;
u16 Pmax=0,Pmin=0;
u32 sum_h1=0,sum_h2=0;
//数据清空
for( i=0; i<256; i++ )
{
gray_test_value[i] = 0;
}
for( i=0; i<PIXEL_H; i++ )
{
for( j=0; j<PIXEL_W; j++ )
{
mux = pixel[i][j]; //获取灰度图的数据
//像素点数自增
gray_itera_threshold[mux]++;
}
}
Pmin = gray_itera_threshold[0];
Pmax = gray_itera_threshold[0];
for( cnt=0; cnt<256; cnt++ )
{
if( Pmin>gray_itera_threshold[cnt] ){
Pmin = gray_itera_threshold[cnt];
}
if( Pmax<gray_itera_threshold[cnt] ){
Pmax = gray_itera_threshold[cnt];
}
}
printf(“the Pmax is %d\n”,Pmax);
printf(“the Pmin is %d\n”,Pmin);
//初始阈值
threshold_h[0] = ( Pmax + Pmin ) / 2;
//寻找最佳阈值
for( k=0; k<256; k++ )
{
//分割前景和背景
for( cnt=0; cnt<threshold_h[k]; cnt++ )
{
sum_h1 += gray_itera_threshold[cnt];
}
for( cnt=threshold_h[k]; cnt<256; cnt++ )
{
sum_h2 += gray_itera_threshold[cnt];
}
sum_h1 /= threshold_h[k];
sum_h2 /= (256-threshold_h[k]);
//计算出新的阈值
threshold_h[k+1] = ( sum_h1 + sum_h2 ) / 2;
if( fabs(threshold_h[k]-threshold_h[k+1]) <= GRAY_BREAK_RANGE ){
newthreshold = threshold_h[k+1];
break;
}
sum_h1 = 0;
sum_h2 = 0;
}
printf(“the newthreshold is %d\n”,newthreshold);
//在液晶屏上面写入图像分割后的图像
LCD_SetCursor(0,0);
LCD_WriteIndex(0x22);
//准备写入数据
//根据最佳阈值将图像二值化
for( i=0; i<PIXEL_H; i++ )
{
for( j=0; j<PIXEL_W; j++ )
{
mux = pixel[i][j]; //获取灰度图的数据
//图像二值化
if( mux > newthreshold ){
mux = 255;
}
else{
mux = 0;
}
Camera_Data = GRAY_TO_RGB(mux);
LCD_WriteData(Camera_Data);
}
}
}
这样就能够找到阈值点,然后再进行图像二值化。
这里我使用的芯片是stm32f407ZET6,内部的RAM比较大,192K,所以能够存储 static u8 pixel[PIXEL_H][PIXEL_W];
程序里面的#define GRAY_BREAK_RANGE 1 //阈值允许参数
可以微调阈值的大小
实验效果:
按键按下前,摄像头移植在采集数据并且在LCD上面显示,如下图:
图像分割按键按下后,出现的图片如下图:
由于这里不能上传代码文件,所以在资源里面上传了,代码和上位机的下载地址如下:
http://u.download.csdn.net/upload/success
希望能够帮助到一起学习的朋友