用stm32采集ov7725stm32 图像采集,通过串口将数据发送到上位机上显示stm32 图像采集。求助大佬

stm32f407使用OV7725使用迭代阈值法进行图像二值化,图像分割
stm32f407使用OV7725进行采集数据,显示到LCD屏幕上面,再进行灰度处理,然后再寻找图像分割的灰度阈值,进行图像二值化。
关于图像分科可以自己百度。。。。
首先进行摄像头的图像采集,使用的是野火带FIFO的OV7725摄像头,帧速率有点慢,但是勉强还能采集数据显示。
但是在采集数据的时候,注意读时序要时间问题,否则会因为时序问题导致图像漂移,如下图:
所以在代码里面的void ImagDisp(void)函数里面处理数据要少。
函数里面void OV7725_GRAY_Serial(void)函数是数据发送给上位机查看灰度图等级直方图和曲线,附件里面带labview的直方图上位机子VI。
接下来是重点,迭代阈值法。
首先来迭代阈值法的思想,主要是下面4条:
迭代法是基于逼近的思想,其步骤如下:
求出图象的最大灰度值和最小灰度值,分别记为Pmax和Pmin,令初始阈值T0=(Pmax+Pmin)/2;
根据阈值T(k)(k=0,1,2...,k)将图象分割为前景和背景,分别求出两者的平均灰度值H1和H2;
求出新阈值T(k+1)=(H1+H2)/2;
若 T(k)-T(k+1)=X
(一个预定义的参数范围内,自己设定),则所得即为阈值;否则转2,迭代计算。
这样就可以逐渐逼近图像二值化阈值,不必使用上位机查看大概的阈值,然后手动分割。
具体函数如下:
#define PIXEL_W
//设定的采集图像的长
#define PIXEL_H
//设定的采集图像的宽
/****************************************************
* 函数名: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];}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
//阈值允许参数
可以微调阈值的大小
实验效果:
按键按下前,摄像头移植在采集数据并且在LCD上面显示,如下图:
图像分割按键按下后,出现的图片如下图:
由于这里不能上传代码文件,所以在资源里面上传了,代码和上位机的下载地址如下:
http://u.download.csdn.net/upload/success
希望能够帮助到一起学习的朋友
没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!【STM32F7】摄像机之上位机显示jpeg图片
1、前言经过了前期的若干铺垫,再没有干货有点说不过去。最初定下的 网络摄像机 也要提上日程了。2、计划回顾拿到开发板之后的规划如下(标绿部分已经按计划完成):&---------------------------------------分割线---------------------------------------------方案设计:大致看了一下板子的原理图,除了很常用的USB接口,大多数引脚都是通过插针或焊点的形式扩展出来。本来想做一个STM32+OV7725数码照相机的,发现DCMI、SDMMC、LCD-TFT控制器都只是扩展出来,具体能不能把三个接口同时用起来,还要花时间确认相关引脚是否被占用。鉴于上述原因,保险起见,就改为设计一个网络摄像机,整体框图如图1所示。DCMI管脚不多,且确认过并未被占用,可以自己引出来,板子提供的网络接口完全够用了,有了输入和输出,剩下的就是软件工作了。虽然不是非常高大上的方案,但是目标很明确:体验低端开发板所没有的功能。该方案用到了低端芯片里所没有的DCMI接口和Ethernet接口,条件允许的话还可以增加本地显示,图像编解码功能,进一步测评其他高大上功能模块。&图1 网络摄像机整体框图&学习过程及发文规划:1、开发板展示及硬件原理简析(前期准备)2、开发平台搭建,用最简单的流水灯程序熟悉开发环境(前期准备)3、为了后续调试的方便,需要搞定虚拟串口(前期准备)4、利用DCMI控制器驱动0V7725摄像头(基本功能)5、通过网口将数据上传至Internet(基本功能)6、编写网页程序显示视频图像(基本功能)7、添加简单的图像处理算法,将视频处理后上传(扩展功能)&后续:如果能拿到板子,我会继续发一些测评文章,想办法把感兴趣的内容都试用一下。1、体验DAC模块:设计一个简易波形发生器(正弦波、三角波、方波)2、体验LCD-TFT控制器:驱动液晶屏3、评估STM32F767ZI运算能力:做一个简单的图形发生器,利用MCU绘制复杂图形,例如:电子飞行仪表系统(EFIS)显示画面绘制等。----------------------------------------分割线---------------------------------------------&其中,流水灯、串口、DAC(波形发生器)都已经完成,今天也开始网络摄像机的调试,这块有所变化,网页设计还是大学的时候玩了一段时间,N年没碰了,有些难度,而网上恰好有一款显示图片、视频的上位机,所以打算拿这个上位机来做显示。还有一点是,摄像头先选用0V5640,因为OV7725不具备压缩功能。后期可以尝试使用芯片自带的JPEG编解码功能处理OV7725的图像数据,然后再上传至上位机。3、网络摄像机调试规划第一步就是要调试上位机显示功能。一方面是调试整个项目的功能之一;另一方面是为摄像头的调试打下基础,如果加入摄像头之后,显示有问题,就可以知道问题出在摄像头控制部分,有助于问题的快速定位。第二步是利用DCMI实现对摄像头的控制。这块不必多说,主要是对摄像头的配置。第三步综合调试,问题改进。做到第二步,其实就差不多了,因为为了验证程序能够成功控制摄像头,必须显示成功才行。4、上位机显示JPEG图片首次调试并没有直接选择网口,而是选择常用的串口作为传输设备,降低了调试难度。网络传输也可以参考该方法进行。首先,设计了一个小程序,把JPEG图片转化为16进制的数组,并保存在 .C文件内。关键代码如下:fprintf(fp_w,&const&unsigned&char&gImage_test_pic[]={&);
while(!feof(fp_r))
&&&&if(i%10==0)
&&&&&&&&fprintf(fp_w,&\n&);
&&&&ch=fread(buf,sizeof(char),1,fp_r);
&&&&printf(&0x%X,&,(unsigned&char)buf[0]);
&&&&fprintf(fp_w,&0x%x,&,(unsigned&char)buf[0]);&
fprintf(fp_w,&};\n&);&这部分代码并不是很完善,还需要手动修改一下.C文件,后续打算做一个JPEG图片转.C文件的GUI的程序,到时候再完善。然后,利用库函数里的发送函数,将图片数据通过串口发送至上位机。5、测试结果串口发送图片显示成功,如下图所示:接下来,再调通摄像头,整个摄像机计算完成一大半了。最后把通信方式由串口变更为网口就OK了。当然也可以先调网络通信,然后再调摄像头,看串口传输的显示效果吧,如果太卡,就换成网口通信。&&版权声明:本文由博主“cuter”发布。欢迎转载,但不得擅自更改博文内容,也不得用于任何盈利目的。转载时不得删除作者简介和版权声明。如有盗用而不说明出处引起的版权纠纷,由盗用者自负。博客官方地址:ChinaAET:
关注微信公众号stm32图像处理问题
[问题点数:100分]
本版专家分:0
结帖率 66.67%
CSDN今日推荐
本版专家分:0
本版专家分:3138
本版专家分:60
本版专家分:0
本版专家分:810
匿名用户不能发表回复!|
CSDN今日推荐新的起点,不忘初心
STM32驱动OV7725摄像头颜色识别
转载请注明出处: 或
文章链接: 或
实验目的:
使用stm32驱动OV7725摄像头进行图像实时采集,在tft屏幕上实时显示并识别图像中的特定颜色,在颜色的周围画上框。
实验现象:
我的工程代码链接:
程序移植自阿莫论坛某位大神的程序。
实现原理:
将摄像头的数据读出写入tft屏,读取tft屏幕上的像素点的颜色进行识别。由于RGB格式的颜色数据的效果不好,所以将其转换为HSL格式数据。首先遍历寻找腐蚀中心,然后在之前腐蚀中心点处进行迭代向外寻找新的腐蚀中心。腐蚀算法从该点开始分别向上下左右四个方向进行读点,若点的颜色符合条件则往外读,等四个方向都结束后得到四个边缘点的坐标,记左边缘点的x轴坐标为left,右边缘点的x轴坐标为right,上边缘点的y轴坐标为up,下边缘点的y轴坐标为bottom,那么坐标( (right-left)/2 , (up-bottom)/2 ) 即为新的腐蚀中心。
关于程序中使用到的参数值,我是参照下面这些该大神在论坛说的调试经验得到的参数:
设置好H、S、L的阈值,用起来没有问题。分享一下我的调节参数时总结的技巧:
1.识别绿色和蓝色的效果最好,因为他们在色调谱中占据的范围最大
2.先将S、L的范围设的广一些(如 5 -250 ),先调节H的值的范围
3.H值调节好后,再调节S、L值
这里介绍下一些相关概念:
HSL:(摘自百度百科)
HSL的H(hue)分量,代表的是人眼所能感知的颜色范围,这些颜色分布在一个平面的色相环上,取值范围是0°到360°的圆心角,每个角度可以代表一种颜色。基本参照:360°/0°红、60°黄、120°绿、180°青、240°蓝、300°洋红,它们在色相环上按照60°圆心角的间隔排列。
HSL的S(saturation)分量,指的是色彩的饱和度,它用0%至100%的值描述了相同色相、明度下色彩纯度的变化。数值越大,颜色中的灰色越少,颜色越鲜艳,呈现一种从理性(灰度)到感性(纯色)的变化。
HSL的L(lightness)分量,指的是色彩的明度,作用是控制色彩的明暗变化。它同样使用了0%至100%的取值范围。数值越小,色彩越暗,越接近于黑色;数值越大,色彩越亮,越接近于白色。
HSL与RGB之间的计算:
从RGB推算HSL:
R、G、B的数值定在【0,255】
亮度L只依赖于R、G、B的最大值和最小值。若令M、N分别是R、G、B的最大值和最小值,则有:若M=0(N=0),即R、G、B均为0时,L=0;否则,亮度L为
其中。由公式可知,L的取值范围在0到240之间。
对于饱和度S:当M或N改变时S随之改变;否则,S不变。即S与L的情况类似,只与最大和最小值有关,换句话说与L有关。所以可以得到S与L之间的数学关系:
当M=N=0或者M=N=255时,没有意义;l=0时,s=0;
当(M+N)&256时,S为:S=240(M-N)/(512-M-N);当l&120时,s = (M-N)* 240 / ( 480 - ( M+ N) );
当(M+N)&256时,S为:S=240(M-N)/(M+N);当l&=120时,s = (M-N)* 240 / ( M+ N);
同理,色相H也是只与最大值和最小值有关。
当M=N时,H无定义;
当最大值为红色,最小值为蓝色,即M=R、N=B,H介于0到40之间,有:
H=40(G-N)/(M-N);
当最大值为红色,最小值为绿色,即M=R、N=G,H介于200到240之间,有:
H=240+40(G-B)/(M-N);
当最大值为绿色,最小值为红色,即M=G、N=R,H介于80到120之间;
当最大值为绿色,最小值为蓝色,即M=G、N=B,H介于40到80之间;
h = 40 * ( B - R ) / (M-N)+ 80;
当最大值为蓝色,最小值为红色,即M=B、N=R,H介于120到160之间;
当最大值为蓝色,最小值为绿色,即M=B、N=G,H介于160到200之间;
h = 40 * ( R - G ) / (M-N)+ 160;
从HSL反算RGB:
当H无定义时,表示R、G、B三者相等,因策,他们的值可以直接由下面公式求得:
当L=0时,R=G=B=0;
当L!=0时,R=G=B=(17L-8)/16;
当H有定义时,令SUM为M与N之和,由上面的公式可知,若L=0,则SUM=0,否则SUM=(17L-8)*2/16。
若SUM&256,则最大值M为:M=SUM/2+SUM*S/480;
若SUM&=256,则最大值M为:M=SUM/2+(512-SUM)*S/480;
求出最大值后,可以求出最小值N=SUM-M。
下面分六种情况求出R、G、B的值:
令L为H/40的整数部分:
若L=0,则:
G=B+H *(R-B)/40
若L=1,则:
R=G+(G-B)(H-40)/40
若L=2,则:
B=R+(G-R)(H-80)/40
若L=3,则:
G=B+(B-R)(H-120)/40
若L=4,则:
R=G+(B-G)(H-160)/40
若L=5,则:
B=R +(R-G)(H-200)/40
至此RGB的反算就完成了。
如果想要更快捷地将HSL转换成RGB格式,可以使用下面的工具:
网络工具链接:
RGB、HEX、HSL等颜色形式相互转换工具
推荐使用windos自带的绘图工具软件中,点“颜色”-&”编辑颜色”-&”规定自定义颜色” 进入调色板进行调色。
具体代码请参考我上传的工程代码。
参考链接:
杨朝霞,逯峰,图像处理中RGB与HLS之间的转换,
没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!stm32 bmp图像数据
[问题点数:20分]
本版专家分:0
结帖率 33.33%
CSDN今日推荐
本版专家分:0
本版专家分:20
本版专家分:0
结帖率 33.33%
本版专家分:0
本版专家分:0
本版专家分:0
结帖率 33.33%
本版专家分:0
结帖率 33.33%
本版专家分:0
匿名用户不能发表回复!|
CSDN今日推荐

我要回帖

更多关于 stm32串口通信 的文章

 

随机推荐