stm32f407使用OV7725使用迭代阈值法进行图像二值化,图像分割

  • Post author:
  • Post category:其他


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

希望能够帮助到一起学习的朋友
大笑
大笑



版权声明:本文为zhouxiaoxiaodou原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。