各位大佬们好,问题见标,我有一个预研的项目需要使用ESP32-CAM从OV2640获取1600*1200的JPEG数据并通过Wi-Fi(TCP传出)。ESP32使用IDF提供的FreeRTOS,要求传输的帧率达到10FPS。
经过查找,OV2640的UXGA分辨率下最大帧率是15FPS,也就是说在传感器侧是能达到这个速度的。
我做了两个测试:
(1)RTOS启动到app_main()之后,开启一个1s定时器做标定输出,while(1)不停获取图像并仅打印数据长度(也就是不对图像数据做拷贝等操作),获取的速度能达到约11~12FPS。
(2)启动Wi-Fi,通过TCP连接到电脑的网口助手,在TCP连接的状态下,获取数据并使用LWIP的send函数发送裸JPEG数据到PC,帧率只有3FPS左右;将JPEG质量从原来的12(数据量80K/张左右)降低到30(数据量50K/张左右),帧率达到4~5FPS。
请问是我哪里的操作导致了数据处理速度下降么?还是ESP32(432MHz)的性能无法达到这个需求?
又或者...有没有哪些可供优化的方法呢?
感谢大家~嗷呜!!
离线
狼狼 说:各位大佬们好,问题见标,我有一个预研的项目需要使用ESP32-CAM从OV2640获取1600*1200的JPEG数据并通过Wi-Fi(TCP传出)。ESP32使用IDF提供的FreeRTOS,要求传输的帧率达到10FPS。
经过查找,OV2640的UXGA分辨率下最大帧率是15FPS,也就是说在传感器侧是能达到这个速度的。
我做了两个测试:
(1)RTOS启动到app_main()之后,开启一个1s定时器做标定输出,while(1)不停获取图像并仅打印数据长度(也就是不对图像数据做拷贝等操作),获取的速度能达到约11~12FPS。
(2)启动Wi-Fi,通过TCP连接到电脑的网口助手,在TCP连接的状态下,获取数据并使用LWIP的send函数发送裸JPEG数据到PC,帧率只有3FPS左右;将JPEG质量从原来的12(数据量80K/张左右)降低到30(数据量50K/张左右),帧率达到4~5FPS。请问是我哪里的操作导致了数据处理速度下降么?还是ESP32(432MHz)的性能无法达到这个需求?
又或者...有没有哪些可供优化的方法呢?感谢大家~嗷呜!!
就你这里获取15fps来说的话大概你是有66.6ms可以用来传输,这样的话可以保证不丢帧。所以这个问题就是确定你自己的esp32传输速度了。这个芯片我没玩过,但是你可以单独测试传输的速度。我看网上说这个芯片实测的传输速度也就几百K左右,所以按照你80K*3=240KB/s可能也就差不多就这样子。我最近刚测试的ov2640的800x600的jpeg在室内开灯大概是15K一帧的大小。如果没有必须要求1600x1200的话你可以将输出大小设置为800x600这样15k*10fps也就是150KB。这样你的速度就可以达到了。
感谢您的回答。但是很可惜项目是要求200W的JPEG图像的。那按照您的意思,如果网络速度达到要求,10FPS的获取和传输还是有可能达到的对吗?那看起来就是我们事先对这款芯片的Wi-Fi传输速度预估的有太多偏差了。
我们的主要参数要求是这样的:
(1)200W JPEG
(2)Wi-Fi(TCP)传输
(3)整机功耗小于700mW@3.3V
现在如果ESP32的方案要重做,可能还是会考虑上专门的编码芯片,只是那样的话功耗就会成为一个问题。好伤。
最近编辑记录 狼狼 (2020-10-22 20:38:53)
离线
不不不,你搞错了,编码芯片根本就不能解决这个问题。因为ov2640输出的就是jpeg根本不需要你编码。就算你加个编码器也没啥用呀,除非你有啥编码器可以把图片压缩的更小。如果按照你目前的情况来说一张200w像素的jpeg大概是80k的话每秒10帧就是800KB/s也就是你的WIFI传输速度不能低于800KB/s。要么你选择一款无线wifi能达到这个传输速度的。要么你想办法把esp32的网络传输速度达到800KB/s。只要你的网络传输能达到这个速度你的功能就能可以完成。
啊哦,可能是我表达不严谨了。我是这样想的,在关闭Wi-Fi的情况下,只获取数据,比较稳定的速度才达到11帧,就算网络速度达到要求,LWIP协议栈内send的数据拷贝操作(我猜的,TCP发送从数据源到缓冲区应该会存在完全拷贝)也会将处理速度拉低。也就是说,恐怕使用了RTOS之后的性能(或者CPU对任务的资源分配?)也是达不到要求的。
我说的编码芯片的意思是,换用诸如海思+200W sensor+Wi-Fi芯片的方案这样子,(因为我看海思SDK中不直接支持OV2640,觉得直接用它支持的比较方便)。
离线
没用过esp32不是很清楚,但是就我理解来说,camera到内存拷贝应该是DMA在做的事情。在帧信号到来之前你根本就不需要关心摄像头的影响。而vync信号又是66(可以配置2640让其100ms一个)ms一个。所以就启动其他应用来说,应该是不会影响到camera传输的。只要申请两个缓冲区给DMA缓冲应该是妥妥的。还有不是海思的SDK中支不支持ov2640只要mcu支持dvp那么就支持ov2640.驱动嘛。不会就外包给别人做了。
嗯嗯嗯嗯!感谢你的回复,和你交流很开心!
离线
80K 1张,10帧就是800KB每秒,加队列勉强可以达到,但不稳定,也不能保证稳定的间隔,2.4G WIFI 单天线11N就这样子。
这还不考虑干扰的问题。1. 上网线
2. 上支持264/265压缩的芯片,降低数据量。
多谢多谢!目前还是要求JPEG编码...so,看起来换方案是势在必行了。
离线
正好前两天测过ESP32的速度,iperf TCP测试速度能到20Mbps以上。为啥你的速度能降低一个数量级?esp32有两个cpu,一个做采集、一个做传输,应该没太大瓶颈。
你这样说的话我好像想起了什么,项目配置的时候默认是不是单核编程呐?我好像没开双核......我去看看!
离线
楼上的测速我是相信的,确实可以达到。
但是这是测试环境,实际环境中,有时也能到20,但偶尔会掉下来,这点是要考虑到的。
如果能接受,这项目可行性就没问题。
FreeRTOS我也是刚接触,还没用iperf测试过,感谢你的数据。我再花时间好好测一下,比如那个双核编程还有速度究竟损失在何处。
离线
今晚又试了一下,把CPU频率从160M改到240,Wi-Fi和OV2640都不是瓶颈。通过把图片质量降低发现传输帧率依然不变,推测主要问题还是在处理上。
解决的方法是把OV2640的连续采集打开,就是驱动中的fb_count改成大于1的数值,这样驱动会创建一个队列,存放传感器连续采集的图像。通过这种方式,传输帧率可以达到11~12FPS了。
但是这种方式的帧率不是狠稳定,而且我设置队列长10的时候它会超出这个采集值。推测连续采集的时候没有进行帧率控制。我会再看代码确认是不是这样。
另一个问题是,这种连续采集可能不适合当前的需求,需求是,每发送一个采集指令才会回传一张图像。一来一回达到每秒10次以上,队列的方式显然不现实,因为采集指令是随机的。
离线
这WiFi能达到72mbps,应该可以传1600*1200的jpeg15fps,是不是WiFi驱动要设置802.11n模式?
Wi-Fi设置遵循例程,可以达到满足要求的速度。至于是不是要设置为802.11n我不是很清楚,它这个不是自适应的嘛?
离线
双核心的方式我简单的试了一下,比如单纯把之前的采集放在core1上,是没有太大的作用的。我也尝试增大了TCP发送缓冲区到最大,这带来了1~2帧的速度提升。
想了一下,之前采集的方式是单次成像,可能这种方式才是制约了所谓“性能”的罪魁祸首。
离线
你好,我想请问怎么读出是怎么读出JPEG格式的图片?我现在卡在了这一步上
https://github.com/espressif/esp32-camera
当时使用了这个驱动程序,也许会对你有帮助?
离线
@breaded
非常感谢您的经验分享,只可惜那个任务后面被搁置了,我也没有再细究下去。
不过您的回答中关于供电和时钟方面确实给了我一些启发,感谢,也希望这份回答能帮助到别人。笔芯~
离线