ESP-IDF USB摄像头(ov5640 ov7670) 对RGB图片进行JPEG压缩

作者在文中详细描述了使用ESP32-S3开发板进行图像传输的过程,包括解决USB通讯问题、尝试UVC摄像头但因分辨率限制放弃,然后转向OV5640和OV7670摄像头。他们成功驱动了OV7670并实现了RGB到JPEG的压缩,但遇到分辨率和花屏问题。此外,还提到了时钟频率配置对WIFI连接的影响以及指针操作导致的错误,最终找到了解决方案。
摘要由CSDN通过智能技术生成

TCP协议传输图像、USB摄像头尝试、ov5640和0v7670摄像头驱动、ESP官方库函数将图像压缩成jpeg

ESP32-S3的DevKitC-1开发板的USB OTG功能(我买的开发板不是官方的),需要把开发板底下的USB-OTG触点短接

df591d7b70744886b0410261deaeb1f2.png

短接后,终于把USB通讯问题解决了!

UVC问题论坛

Is there any example to capture a image from USB camera (AEGHB-15) · Issue #230 · espressif/esp-iot-solution · GitHub

        但是UVC似乎没法支持30万像素以上分辨率的摄像头,项目需求要高分辨率,故暂时放弃USB摄像头这个选项,各位大佬有什么办法希望指教下。

        买了了OV5640摄像头,原始驱动该摄像头去获取图像,为此,我花了几天踩坑,学习了ESP-IDF,因为Arduino的Camera库总有莫名其妙的错误,而且很多配置没有接口出来,比如翻转180度图片,都要用里面的IIC函数写驱动。

OV7670摄像头成功,下图:

214502d0b13c460dbdf79cdbee5ac539.png

但是OV7670不能直接获取JPEG格式图像,获取的是RGB格式图像,网络传输用得用JPEG压缩一下,JPEG格式数据量会小很多很多,而且像素损失小。

JPEG压缩代码:

size_t  _jpg_len;
uint8_t *_jpg_buf;

//转化JPEG
uint8_t temp = frame2jpg(pic, 90, &_jpg_buf, &_jpg_len);

printf("trunfrom :%d\n",temp);

//socket发送
ESP_ERROR_CHECK(sock_tcp_send(sock, _jpg_buf, maxcache));

但是ESP官方库仅仅支持OV7670最大分辨率640X480,但是成功驱动也是很令人开心的。

        购入的OV5640到了,也是成功驱动,但是都有和上面一样的问题,偶尔会有花屏现象,有时候很严重,可能是杜邦线连接干扰大的原因,后面上PCB试试效果。

        OV5640图像:

867e5c2979dc4c7b92e44f8638f6ed03.png

        发现一个问题,就是S3在将芯片时钟频率从160Mhz配置240Mhz的时候,WIFI的sockt_connect不工作堵塞住了,降回160Mhz就可以,找时间去github上讨论下。

        再发现一个问题,S3驱动OV5640在拍摄到大概16次或者多次的时候,会有报错

a7ca30971f0a4719a378333d8806b832.png

尝试调参数看看是什么问题……

20分钟后.......

解决了,是指针操作问题,这部分是网上一个博主得,得改一改,pic = esp_camera_fb_get()给的pic->buf不能对其本身+和-,需要使用一个变量进行缓存位置计数,例如:

pic = esp_camera_fb_get();

// 将图片数据分段发
size_t leng = pic->len;
// 清空缓存计数
cambuf_count = 0;
// 计算要分发几个数据包
int timess = leng/maxcache;
// 剩余图像数据
int extra = leng%maxcache;


for(int i = 0;i < timess;i++){
    //tcp分包发送图像
    ESP_ERROR_CHECK(sock_tcp_send(sock, pic->buf+cambuf_count, maxcache));
    
    //计数跟上
    cambuf_count+=maxcache;

    printf("send tcp> %d\n", i);

}


if(extra > 0){
    //剩余的图像数据
    ESP_ERROR_CHECK(sock_tcp_send(sock, pic->buf+cambuf_count, extra));
}

//将指针返还
esp_camera_fb_return(pic);

用cambuf_count对buf读取到哪里的位置计数,下次读取就在buf基础上加cambuf_count就可以。

以上也可以用socket 的 write()函数实现,直接给图片帧的指针bud 和图片帧的大小len ,不需要自己进行分包发送。

  • 4
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值