图像采集与帧差法

选型

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);
    }
发布了28 篇原创文章 · 获赞 13 · 访问量 7041

猜你喜欢

转载自blog.csdn.net/weixin_44076906/article/details/104486681