TCP协议传输图像、USB摄像头尝试、ov5640和0v7670摄像头驱动、ESP官方库函数将图像压缩成jpeg
ESP32-S3的DevKitC-1开发板的USB OTG功能(我买的开发板不是官方的),需要把开发板底下的USB-OTG触点短接
短接后,终于把USB通讯问题解决了!
UVC问题论坛
但是UVC似乎没法支持30万像素以上分辨率的摄像头,项目需求要高分辨率,故暂时放弃USB摄像头这个选项,各位大佬有什么办法希望指教下。
买了了OV5640摄像头,原始驱动该摄像头去获取图像,为此,我花了几天踩坑,学习了ESP-IDF,因为Arduino的Camera库总有莫名其妙的错误,而且很多配置没有接口出来,比如翻转180度图片,都要用里面的IIC函数写驱动。
OV7670摄像头成功,下图:
但是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图像:
发现一个问题,就是S3在将芯片时钟频率从160Mhz配置240Mhz的时候,WIFI的sockt_connect不工作堵塞住了,降回160Mhz就可以,找时间去github上讨论下。
再发现一个问题,S3驱动OV5640在拍摄到大概16次或者多次的时候,会有报错
尝试调参数看看是什么问题……
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 ,不需要自己进行分包发送。