基于AI+RT-THREAD的人检测入侵检测摄像头(二 图像数据处理)

本文详细介绍了在RT-THREAD操作系统中使用OV2640摄像头组件的初始化与配置,包括如何解决编译错误、添加DMA中断支持以及自定义初始化函数。接着,讲解了RGB565数据转换为灰度图的步骤,并通过双线性插值算法将图像压缩至50*50大小,为后续的模型输入做好准备。整个过程涵盖了嵌入式系统的图像数据处理关键技术。
摘要由CSDN通过智能技术生成

二、图像数据的处理

思路:

  • OV2640组件的完善
  • rgb565数据转灰度图
  • 双线性插值算法压缩图片

1.OV2640组件的完善
RT-THREAD提供了对摄像头OV2640的组件支持,我们在RT-THREAD SETTINGS中设置开启OV2640打开OV2640
尝试编译会发现失败,6errors,2warnings编译报错
查看报错我们可以发现是因为有类型未被定义
打开stm32h7xx_hal_conf.h查看没有打开的宏定义在这里插入图片描述
打开DCMI、JPEG的宏JPEG宏
DCMI宏
此时编译虽然不报错,但还有程序上的欠缺,RT-THREAD的OV2640组件是没有DMA中断的,需要加一句代码(见后文),然后是要手动写一个初始化程序配置OV2640的各个引脚
找到drv_ov2640.c和drv_dcmi.c打开drv_ov2640.c和dcmi.c
dcmi初始化中加入标识出的代码开启DMA中断

void ov2640_pin_init(void)
{
    /*
     * SCL             PH15              127
     * SDA             PH13              125
     *
     * D0              PH9               121
     * D1              PH10              122
     * D2              PG10              106
     * D3              PG11              107
     * D4              PH14              126
     * D5              PI4               132
     * D6              PI6               134
     * D7              PI7
     * HSYNC           PH8               120
     * VSYNC           PI5               133
     * PCLK            PA6               6
     *
     * PWON            PC7               39
     * RESET           PC6               38
     */

    GPIO_InitTypeDef GPIO_Initure;

    __HAL_RCC_DCMI_CLK_ENABLE();
    __HAL_RCC_GPIOH_CLK_ENABLE();
    __HAL_RCC_GPIOG_CLK_ENABLE();
    __HAL_RCC_GPIOI_CLK_ENABLE();
    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_GPIOC_CLK_ENABLE();

    GPIO_Initure.Pin = GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_14 | GPIO_PIN_8;
    GPIO_Initure.Mode = GPIO_MODE_AF_PP;
    GPIO_Initure.Pull = GPIO_NOPULL;
    GPIO_Initure.Speed = GPIO_SPEED_FREQ_HIGH;
    GPIO_Initure.Alternate = GPIO_AF13_DCMI;
    HAL_GPIO_Init(GPIOH, &GPIO_Initure);

    GPIO_Initure.Pin = GPIO_PIN_10 | GPIO_PIN_11;
    GPIO_Initure.Mode = GPIO_MODE_AF_PP;
    GPIO_Initure.Pull = GPIO_NOPULL;
    GPIO_Initure.Speed = GPIO_SPEED_FREQ_HIGH;
    GPIO_Initure.Alternate = GPIO_AF13_DCMI;
    HAL_GPIO_Init(GPIOG, &GPIO_Initure);

    GPIO_Initure.Pin = GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7;
    GPIO_Initure.Mode = GPIO_MODE_AF_PP;
    GPIO_Initure.Pull = GPIO_NOPULL;
    GPIO_Initure.Speed = GPIO_SPEED_FREQ_HIGH;
    GPIO_Initure.Alternate = GPIO_AF13_DCMI;
    HAL_GPIO_Init(GPIOI, &GPIO_Initure);

    GPIO_Initure.Pin = GPIO_PIN_6;
    GPIO_Initure.Mode = GPIO_MODE_AF_PP;
    GPIO_Initure.Pull = GPIO_NOPULL;
    GPIO_Initure.Speed = GPIO_SPEED_FREQ_HIGH;
    GPIO_Initure.Alternate = GPIO_AF13_DCMI;
    HAL_GPIO_Init(GPIOA, &GPIO_Initure);

    GPIO_Initure.Pin = GPIO_PIN_6 | GPIO_PIN_7;
    GPIO_Initure.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_Initure.Pull = GPIO_PULLUP;
    GPIO_Initure.Speed = GPIO_SPEED_FREQ_HIGH;
    GPIO_Initure.Alternate = 0x00;
    HAL_GPIO_Init(GPIOC, &GPIO_Initure);

    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_SET);
    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_RESET);
}

你可以将这个函数设置为自动初始化,也可以在ov2640_init里将它调用
2.rgb565数据转灰度图
准备工作完成,现在将RGB565图像转为灰度,思路就是先将其填充转变为RGB888,然后用灰度公式转为灰度

rgb565_len  = 320*240;

          if (rgb565_len)
          {
              for(i=0;i<240;i++)
              {
                  for(j=0;j<320;j++)
                  {
                      B = (*p)&0x1f;
                      G = (*p>>5)&0x3f;
                      R = (*p>>11)&0x1f;
                      B = B<<3;//*8
                      G = G<<2;//*4
                      R = R<<3;//*8
                      Gray=  (rt_uint8_t)( (R*38 + G*75 + B*15) >> 7);//7位精度,测试效果最佳
                      dest[i][j]=Gray;
                      p++;
                  }
              }
              ifperson_app(dest);//进一步处理以及最终判决函数
          }

3.双线性插值算法压缩图片
之前说过,为了简化模型,我们的模型入口参数是5050的u8,需要我们将输入的320240的图片压缩成50*50进行输入,这需要用到双线性插值算法在这里插入图片描述

将二维数组压缩

/*
 * 简述:该函数将320X240图像数组用算法缩小并输出50X50的图像数据
 * 参数:320X240的数组输入,50X50的数组输出
 */
void Bilinear_interpolation_algorithm(rt_uint8_t array_in_320X240[][320],rt_uint8_t array_out_50X50[][50])
{
    rt_uint16_t i_in,j_in,i_out,j_out;
    float Px,Py;
    float R2,R1;
    for(j_out=0;j_out<50;j_out++)
    {
        Py=((float)j_out+0.5)*scaling_y-0.5;//计算纵坐标
        j_in=(rt_uint16_t)Py;
        //经计算320*240->50*50不需要判断边界
        for(i_out=0;i_out<50;i_out++)
        {
            Px=((float)i_out+0.5)*scaling_x-0.5;
            i_in=(rt_uint16_t)(((float)i_out+0.5)*scaling_x-0.5);//计算横坐标
            R2=((float)i_in+1.0-Px)*array_in_320X240[j_in][i_in]+(Px-i_in)*array_in_320X240[j_in][i_in+1];//计算R2的灰度值
            R1=((float)i_in+1.0-Px)*array_in_320X240[j_in+1][i_in]+(Px-i_in)*array_in_320X240[j_in+1][i_in+1];
            array_out_50X50[j_out][i_out]=(rt_uint16_t)((Py-j_in)*R1+(j_in+1-Py)*R2);
        }
    }

}

其实这个函数可以进一步封装,变为任意格式的图像输入,任意格式的缩放输出,大致实现与上面的320240转5050相同.至此,图像数据处理部分结束,下一章写一下红外遥控部分在RT-THREAD系统中遇到的一些问题以及解决

  • 6
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Kejane

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值