在网上看到一个和我做的课题相同的源码 根据实验35ov2640实验基础上改良的边缘提取算法 下面是main函数 我看不懂每一步干什么的 也不知道这个是什么算子实现的 求各位大神指教
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "lcd.h"
#include "key.h"
//#include "usmart.h"
#include "usart2.h"
#include "timer.h"
#include "ov2640.h"
#include "dcmi.h"
u8 ov2640_mode=0; //工作模式:0,RGB565模式;1,JPEG模式
#define CAMERA_H 160 //定义数组CAMERA_H
#define CAMERA_W 160 //定义数组CAMERA_W
u16 Image[CAMERA_H][CAMERA_W]= {0};
u8 address[40][2]={0};
u8 x_address,y_address;
u8 hold_for_gray=12;
u8 hold_for=5;
#define jpeg_buf_size 2 //定义JPEG数据缓存jpeg_buf的大小(*4字节)
__align(4) u32 jpeg_buf[jpeg_buf_size]; //JPEG数据缓存buf
volatile u32 jpeg_data_len=0; //buf中的JPEG有效数据长度
volatile u8 jpeg_data_ok=0; //JPEG数据采集完成标志
#define yuv_buf_size 160*160*2/4
__align(4) u32 yuv_buf[yuv_buf_size]; //yuv数据缓存buf【__align(4)为四字节对齐】
volatile u32 yuv_data_len=12800;
int my_abs(int a)
{
if(a<0)
return -a;
else
return a;
}
//处理JPEG数据
//当采集完一帧JPEG数据后,调用此函数,切换JPEG BUF.开始下一帧采集.
void jpeg_data_process(void)
{
if(ov2640_mode)//只有在JPEG格式下,才需要做处理.
{
if(jpeg_data_ok==0) //jpeg数据还未采集完?
{
DMA2_Stream1->CR&=~(1<<0); //停止当前传输
while(DMA2_Stream1->CR&0X01); //等待DMA2_Stream1可配置
jpeg_data_len=jpeg_buf_size-DMA2_Stream1->NDTR;//得到此次数据传输的长度
jpeg_data_ok=1; //标记JPEG数据采集完按成,等待其他函数处理
}
if(jpeg_data_ok==2) //上一次的jpeg数据已经被处理了
{
DMA2_Stream1->NDTR=jpeg_buf_size; //传输长度为jpeg_buf_size*4字节
DMA2_Stream1->CR|=1<<0; //重新传输
jpeg_data_ok=0; //标记数据未采集
}
}
}
//函数功能:YUV422格式转灰度图像(RGB565格式显示)
//yuv422:yuv格式数据
u16 yuv422_to_Gray(u16 yuv422)
{
u16 Gray; //用于储存灰度值变量(RGB565格式显示)
Gray =(((yuv422>>(8+3))<<11)|((yuv422>>(8+2))<<5)|((yuv422>>(8+3))<<0));//Y量转为灰度值(RGB565格式显示)
return Gray; //返回灰度图像值(RGB565格式显示)
}
//函数功能:YUV422格式Y量二值化(RGB565格式显示)
//yuv422:yuv格式数据
//threshold:阀值
u16 yuv422_y_to_bitmap(u8 threshold,u16 yuv422)
{
u16 bitmap; //二值化数据变量(RGB565格式显示)
u8 temp; //用于储存yuv422格式数据中的亮度值Y量
temp = (u8)(yuv422>>8);//把yuv422格式数据中的亮度值Y量提取出来赋值给temp变量(Y值在高字节,根据OV2640寄存器设置决定)
if(temp >= threshold)//如果,Y值大于等于阀值
{
bitmap =0xffff; //白
}
else
{
bitmap =0x0000; //黑
}
return bitmap; //返回二值化像素值
}
void img_send()
{
u8 j,k;
u8 *p;
u32 i;
// for(j=hold_for+1;j<160-hold_for;j++)
// {
// if((my_abs(address[j][0]-address[j-1][0])<3)&&(my_abs(address[j][0]-address[j-1][0])<3))
// if((my_abs(address[j][0]-address[j+1][0])<3)&&(my_abs(address[j][0]-address[j+1][0])<3))
// if((my_abs(address[j][0]-address[j+2][0])<3)&&(my_abs(address[j][0]-address[j+2][0])<3))
// if((my_abs(address[j][0]-address[j+3][0])<3)&&(my_abs(address[j][0]-address[j+3][0])<3))
// {
// if((address[j+1][0]>0)&&(address[j+1][1]>0))
// {
// x_address=address[j+1][1];
// y_address=address[j+1][0];
//// LCD_Fast_DrawPoint(address[j+1][1],address[j+1][0],RED);
//// LCD_Fast_DrawPoint(address[j+2][1],address[j+2][0],RED);
//// LCD_Fast_DrawPoint(address[j+3][1],address[j+3][0],RED);
// LCD_ShowString(x_address,y_address,50,16,16,"x");
// }
// }
// }
p=(u8*)Image;
while(USART_GetFlagStatus(USART2,USART_FLAG_TC)==RESET); //循环发送,直到发送完毕
USART_SendData(USART2,0x01);
while(USART_GetFlagStatus(USART2,USART_FLAG_TC)==RESET); //循环发送,直到发送完毕
USART_SendData(USART2,0xfe);
for(i=0;i<yuv_data_len*4;i++) //dma传输1次等于4字节,所以乘以4.
{
while(USART_GetFlagStatus(USART2,USART_FLAG_TC)==RESET); //循环发送,直到发送完毕
USART_SendData(USART2,p[i]);
}
while(USART_GetFlagStatus(USART2,USART_FLAG_TC)==RESET); //循环发送,直到发送完毕
USART_SendData(USART2,0xfe);
while(USART_GetFlagStatus(USART2,USART_FLAG_TC)==RESET); //循环发送,直到发送完毕
USART_SendData(USART2,0x01);
//while(USART_GetFlagStatus(USART2,USART_FLAG_TC)==RESET);
// USART_SendData(USART2,253);//行标志
//while(USART_GetFlagStatus(USART2,USART_FLAG_TC)==RESET); //循环发送,直到发送完毕
// USART_SendData(USART2,x_address);
// while(USART_GetFlagStatus(USART2,USART_FLAG_TC)==RESET);
// USART_SendData(USART2,254);//列标志
// while(USART_GetFlagStatus(USART2,USART_FLAG_TC)==RESET); //循环发送,直到发送完毕
// USART_SendData(USART2,y_address);
LCD_ShowNum(59,310,(u32)x_address,3,16);
LCD_ShowNum(59,330,(u32)y_address,3,16);
LCD_Fast_DrawPoint(y_address,x_address,RED);//快速画点
LCD_Fast_DrawPoint(y_address+1,x_address,RED);
LCD_Fast_DrawPoint(y_address,x_address+1,RED);
// for(j=0;j<160;j++)
// {
// address[j][0]=0;
// address[j][1]=0;
// }
}
u16 imag_proc(u16 imag,u16 i)
{
u8 night;
u8 count=0;
u16 imagtemp;
imagtemp=imag;
night=imag>>8;
if((u8)(yuv_buf[i-320]>>8)-night>hold_for_gray) count++;
if((u8)(yuv_buf[i-160]>>8)-night>hold_for_gray) count++;
if((u8)(yuv_buf[i+320]>>8)-night>hold_for_gray) count++;
if((u8)(yuv_buf[i+320]>>8)-night>hold_for_gray) count++;
if((u8)(yuv_buf[i-1]>>24)-night>hold_for_gray) count++;
if((u8)(yuv_buf[i+1]>>24)-night>hold_for_gray) count++;
if(count>3)
{imag=0x0000;return imag;}
else return imagtemp;
}
int main(void)
{
u8 key=0;
u8 threshold=130; //二值化时用到的阀值变量 threshold=128 TEST
// u16 Direction_value1=0,Direction_value2=0,Direction_value3=0; //方向值变量
Stm32_Clock_Init(336,8,2,7);//设置时钟,168Mhz
delay_init(168); //延时初始化
uart_init(84,115200); //初始化串口波特率为115200
usart2_init(42,115200); //初始化串口2波特率为115200
LED_Init(); //初始化LED
LCD_Init(); //LCD初始化
KEY_Init(); //按键初始化
TIM3_Int_Init(10000-1,8400-1);//10Khz计数,1秒钟中断一次
POINT_COLOR=RED;//设置字体为红 {MOD}
LCD_ShowString(30,10,200,16,16,"Explorer STM32F4");
while(OV2640_Init())//初始化OV2640
{
LCD_ShowString(30,30,240,16,16,"OV2640 ERROR");
delay_ms(200);
LCD_Fill(30,130,239,170,WHITE);
delay_ms(200);
}
LCD_ShowString(30,30,200,16,16,"OV2640 OK");
LCD_ShowString(30,50,240,16,16,"KEY_UP: 阙值+"); //按键上:阀值增加
LCD_ShowString(30,70,240,16,16," KEY1: 阙值-"); //按键1:阀值减少
delay_ms(100);
while(1)
{ //RGB565测试
//RGB数据直接显示在LCD上面
LCD_Clear(WHITE); //清屏函数
POINT_COLOR=RED; //画笔颜 {MOD}
My_DCMI_Init(); //DCMI配置 初始化
DCMI_DMA_Init((u32)&yuv_buf,yuv_buf_size,2,1);//DCMI DMA配置
OV2640_OutSize_Set(160,160);//OV2640输出图像 设置图像输出大小
while(1) //这里将会重复执行{}中的代码
{
u16 i,temp_h,temp_l;
u16 j,k;
u8 n=0;
// u16 signal1=0,signal2=0,signal=0;
OV2640_YUV422_Mode();
DCMI_Start(); //启动传输
DCMI_Stop(); //停止显示
LCD_Set_Window(0,0,160,160); //设置窗口,并自动设置画点坐标到窗口左上角(sx,sy
LCD_WriteRAM_Prepare(); //开始写入GRAM
i=0;
//for(j = 0; j < CAMERA_H; j++)
for(j = 7; j < 154; j++)
{
for(k = 7; k < 148; k=k+2)
{
temp_l=(u16)(yuv_buf[i]);
temp_l=imag_proc(temp_l,i);
// imag_for_gray[j][k]=temp_l>>8;
//Image[j][k] = yuv422_y_to_bitmap(threshold,temp_l);//先写入低16位
Image[j][k] = yuv422_to_Gray(temp_l);
if(Image[j][k]==0)
{
n++;
if(Image[j-2][k-2]==0) n++;if(Image[j-2][k-1]==0) n++;if(Image[j-2][k]==0) n++;if(Image[j-2][k+1]==0) n++;if(Image[j-2][k+2]==0) n++;
if(Image[j-1][k-2]==0) n++;if(Image[j-1][k-1]==0) n++;if(Image[j-1][k]==0) n++;if(Image[j-1][k+1]==0) n++;if(Image[j-1][k+2]==0) n++;
if(Image[j][k-2]==0) n++;if(Image[j][k-1]==0) n++;if(Image[j][k+1]==0) n++;if(Image[j][k+2]==0) n++;
if(Image[j+1][k-2]==0) n++;if(Image[j+1][k-1]==0) n++;if(Image[j+1][k]==0) n++;if(Image[j+1][k+1]==0) n++;if(Image[j+1][k+2]==0) n++;
if(Image[j+2][k-2]==0) n++;if(Image[j+2][k-1]==0) n++;if(Image[j+2][k]==0) n++;if(Image[j+2][k+1]==0) n++;if(Image[j+2][k+2]==0) n++;
if(n>15)
{
if(((j>10)&&(j<150))||((k>10)&&(k<150)))
{
Image[j][k]=255;
x_address=j;y_address=k;
}
}
n=0;
}
temp_h=(u16)(yuv_buf[i]>>16);
temp_h=imag_proc(temp_h,i);
// if((temp_h==0x0000)&&(j>hold_for)&&(j<160-hold_for)&&(k>hold_for)&&(k<160-hold_for))
// {
// if((temp_h==0x0000)&&(j>hold_for)&&(j<160-hold_for)&&(k>hold_for)&&(k<160-hold_for))
// {address[n][0]=j;address[n][1]=k+1;n++;}
// else{address[n][0]=0;address[n][1]=0;}
// }
// imag_for_gray[j][k+1]=temp_h;
// Image[j][k+1] = yuv422_y_to_bitmap(threshold,temp_h);//后写入高16?
Image[j][k+1] = yuv422_to_Gray(temp_h); // LCD->LCD_RAM = Image[j][k+1];
if(Image[j][k+1]==0)
{
n++;
if(Image[j-2][k-1]==0) n++;if(Image[j-2][k]==0) n++;if(Image[j-2][k+1]==0) n++;if(Image[j-2][k+2]==0) n++;if(Image[j-2][k+3]==0) n++;
if(Image[j-1][k-1]==0) n++;if(Image[j-1][k]==0) n++;if(Image[j-1][k+1]==0) n++;if(Image[j-1][k+2]==0) n++;if(Image[j-1][k+3]==0) n++;
if(Image[j][k-1]==0) n++;if(Image[j][k]==0) n++;if(Image[j][k+2]==0) n++;if(Image[j][k+3]==0) n++;
if(Image[j+1][k-1]==0) n++;if(Image[j+1][k]==0) n++;if(Image[j+1][k+1]==0) n++;if(Image[j+1][k+2]==0) n++;if(Image[j+1][k+3]==0) n++;
if(Image[j+2][k-1]==0) n++;if(Image[j+2][k]==0) n++;if(Image[j+2][k+1]==0) n++;if(Image[j+2][k+2]==0) n++;if(Image[j+2][k+3]==0) n++;
if(n>15)
{
if((j>10)&&(j<150)||(k>10)&&(k<150))
{
Image[j][k+1]=255;
x_address=j;y_address=k+1;
}
}
n=0;
}
i++;
}
}
///////////////////////*********LCD显示**********///////////////////////
for(j = 0; j < CAMERA_H; j++)
{
for(k = 0; k < CAMERA_W; k=k+2)
{
LCD->LCD_RAM = Image[j][k];
LCD->LCD_RAM = Image[j][k+1];
}
}
key=KEY_Scan(1); //按键扫描函数
if(key)
{
switch(key)
{
case WKUP_PRES: //阀值+1
hold_for++;break; //hold_for_gray
case KEY1_PRES: //阀值-1
hold_for_gray--;break;
case KEY0_PRES: //阀值-1
hold_for_gray++;break;
case KEY2_PRES: //阀值-1
hold_for--;break;
}
}
img_send();
// for(n=0;n<40;n++)
// {
// if((address[n][0]>0)||(address[n][1]<0))
// {
// address[n][0]=0;
// address[n][1]=0;
// }
// else n++;
// }
// n=0;
LCD_ShowString(10,288,50,16,16,"pianyi:");
LCD_ShowNum(59,288,(u32)hold_for,3,16);
//LCD_Fast_DrawPoint(80,80,RED);
LCD_ShowString(10,260,50,16,16,"fazhi:");
LCD_ShowNum(59,260,(u32)hold_for_gray,3,16);
}
}
}
一周热门 更多>