选型
OV7670(带FIFO)
STM32F103
/*
函数名:camera_refresh
返回值:void
参数:imageSelect
作用:参数为0时,存入Image_Array1数组中,
参数为1时,存入Image_Array2数组中。
*/
void camera_refresh(u8 imageSelect)
{
u8 gm_red, gm_green, gm_blue;
u32 i, j, k = 0;
u16 color;
if(ov_sta == 2)
{
OV7670_CS = 0;
OV7670_RRST = 0; //开始复位读指针
OV7670_RCK = 0;
OV7670_RCK = 1;
OV7670_RCK = 0;
OV7670_RRST = 1; //复位读指针结束
OV7670_RCK = 1;
//图像数据存入Image_Array1数组中
if(imageSelect == 1)
{
for(i = 0; i < 240; i++)
for(j = 0; j < 320; j++)
{
GPIOB->CRL = 0X88888888;
OV7670_RCK = 0;
color = OV7670_DATA; //读数据
OV7670_RCK = 1;
color <<= 8;
OV7670_RCK = 0;
color |= OV7670_DATA; //读数据
OV7670_RCK = 1;
GPIOB->CRL = 0X33333333;
//对color操作
if((i & 1) == 1 && (j & 1) == 1)
{
gm_red = (color & 0xF800) >> 8;
gm_green = (color & 0x07E0) >> 3;
gm_blue = (color & 0x001F) << 3;
color = (gm_red * 3 + gm_green * 6 + gm_blue * 1) >> 2;
Image_Array1[k] = color;
//USART1_Send_Byte(Image_Array1[k]);
k++;
}
}
}
//图像数据存入Image_Array2数组中
if(imageSelect == 2)
{
for(i = 0; i < 240; i++)
for(j = 0; j < 320; j++)
{
GPIOB->CRL = 0X88888888;
OV7670_RCK = 0;
color = OV7670_DATA; //读数据
OV7670_RCK = 1;
color <<= 8;
OV7670_RCK = 0;
color |= OV7670_DATA; //读数据
OV7670_RCK = 1;
GPIOB->CRL = 0X33333333;
//对color操作
if((i & 1) == 1 && (j & 1) == 1)
{
gm_red = (color & 0xF800) >> 8;
gm_green = (color & 0x07E0) >> 3;
gm_blue = (color & 0x001F) << 3;
color = (gm_red * 1 + gm_green * 2 + gm_blue * 1) >> 2;
Image_Array2[k] = color;
//USART1_Send_Byte(Image_Array2[k]);
k++;
}
}
}
OV7670_CS = 1;
OV7670_RCK = 0;
OV7670_RCK = 1;
EXTI->PR = 1 << 15; //清除LINE8上的中断标志位
ov_sta = 0; //开始下一次采集
}
}
/*
以下是主函数部分
请在设备初始化后使用
GRAYSCALE=255
*/
OV7670_CS = 0;
syscronization = 1; //初始化同步变量
//算法实现部分
//获取第一幅图象
delay_ms(40); //此处延时很关键,必须有的,不然图一不采集。
camera_refresh(1); //更新显示
while(1)
{
//中断触发取值为0
if(syscronization == 0)
{
delay_ms(40);
camera_refresh(1);
syscronization = 1;
}
//取两个图像之间间隔至少1.5s
delay_ms(500);
//获取第二幅图像
camera_refresh(2);
delay_ms(100);
//初始化图像直方图
for(i = 0; i < GRAYSCALE; i++)
{
pixelCount[i] = 0;
}
//将两幅图像相减并且获取图像2中总灰度值
for(i = 0; i < pixelSum; i++)
{
//将两者相减的值赋给图像2
Image_Array2[i] = abs(Image_Array1[i] - Image_Array2[i]);
test = Image_Array2[i];
pixelCount[test]++;
}
//获取图像中灰度直方图
sum_gray = 0;
for(i = 0; i < GRAYSCALE; i++)
{
sum_gray = sum_gray + pixelCount[i] * i;
}
//获取阈值,此阈值为两者图像相减之后的图像的阈值
threshold = (int)(sum_gray / pixelSum);
//USART1_Send_Byte(threshold);
//二值化图像
count = 0;
for(i = 0; i < pixelSum; i++)
{
if(Image_Array2[i] < threshold) //即小于阈值,为背景黑色
{
Image_Array2[i] = 0;
}
else
{
count++;
Image_Array2[i] = 255;
}
}
if(count<10500)
{
GPIO_ResetBits(GPIOB, GPIO_Pin_8);
GPIO_ResetBits(GPIOD, GPIO_Pin_2);
GPIO_ResetBits(GPIOA, GPIO_Pin_8);
}
//count判断条件
printf("%d",count);
}