搜索
bottom↓
回复: 53

Qt用QLabel来显示摄像头,CPU占用率过高的问题,定时器变不准

[复制链接]

出0入90汤圆

发表于 2015-5-11 14:14:23 | 显示全部楼层 |阅读模式
本帖最后由 honami520 于 2015-5-11 15:59 编辑

悬赏50元话费,直接支付宝冲给你,遇到过这种问题,而且解决掉了,说下方法,我这边试验好了,马上给你充话费,就我这注册时间,积分,绝对不忽悠。


我用的是linux,板子是全志A20的双核板子,CPU是1GHZ双核,内存512MB。用的摄像头是普通UVC摄像头。用ffmepg对摄像头数据编解码都OK,速度还挺快,结果被Qt的显示给拦住了。

我是V4L2读取一帧数据,然后YUV转换成RGB,然后转换成QImage显示到QLabel上面,定时器开的是40ms,40ms读取一帧数据,显示出来。在PC上面跑得好好的东西,到了开发板上面,就不行了。根据打印信息,定时的时间间隔编程60-70ms。然后在定时器里面执行的时间还是挺快的,只要5-8ms的时间。看来这个时间是在定时器外面,Qt自己运行的里面被消耗掉了的。

下面是我的定时服务程序代码

        video->get_frame((void **)&pp, &pp_len);
        //摄像头内部图片指针还原
        video->unget_frame();

        convert_yuv_to_rgb_buffer(pp, pf, 320, 240);
        ui->label->setPixmap(QPixmap::fromImage(*frame, Qt::AutoColor));

经过研究发现,只要执行了ui->label->setPixmap这句话,定时器间隔就变得不准,系统资源被严重消耗。问下各位,如果做过在开发板上面用Qt来显示摄像头的,有没有解决办法。或者有没有其他方法可以让摄像头的显示变快点的。
一定要是在Arm开发板上面跑过Qt来显示摄像头的,pc平台的一切都正常,不需要说。

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入90汤圆

 楼主| 发表于 2015-5-11 14:17:53 | 显示全部楼层
我用ffmpeg在A20下面来进行视频编码解码,速度都在我的控制之中。
就是这个鬼Qt,图片都专门解码转成RGB的了,嚼碎了喂给它吃,它还跟我捣乱,真是郁闷。
这个函数内部执行时间在板子上面也只有几ms,所以真的是不知道Qt到底执行完了之后做了些什么事情,害得我系统资源被占用,CPU占用率很高,然后定时器都变得不准了。麻烦各位知道的告诉一声

出0入0汤圆

发表于 2015-5-11 14:46:03 | 显示全部楼层
是pc上的经验:你可以尝试把摄像头读取放在另外一个线程里面。ui不用每一帧刷新吧。

出0入90汤圆

 楼主| 发表于 2015-5-11 14:53:00 | 显示全部楼层
ttoto 发表于 2015-5-11 14:46
是pc上的经验:你可以尝试把摄像头读取放在另外一个线程里面。ui不用每一帧刷新吧。 ...

多谢回复!
这个读取摄像头速度是很快的。白天的时候几乎不需要时间。主要是Qt的ui更新速度太慢了。只要把数据给ui,它自己就要折腾半天。
我刚刚又找到了个方法,才用painter的方式,用drawimage的方法来做,定时器的时间正常了,为40ms,不过CPU占用率还是挺高的,现在达到50%左右了。
估计还是因为我是双核的缘故。如果不是双核,那估计就是100%了

出0入90汤圆

 楼主| 发表于 2015-5-11 15:56:23 | 显示全部楼层
本帖最后由 honami520 于 2015-5-11 15:59 编辑

看来我现在技术变得牛逼了,随便问个问题,论坛里面就几乎没人知道的。
那我改一下,不用论坛币了,改RMB,不学那些喊话1000,2000的大忽悠,那些人说的高,最后一分钱也不兑现。
我这边就悬赏50元话费,直接支付宝冲给你,遇到过这种问题,而且解决掉了,说下方法,我这边试验好了,马上给你充话费,就我这注册时间,积分,绝对不忽悠。

出0入90汤圆

 楼主| 发表于 2015-5-11 17:51:03 | 显示全部楼层
这个帖子长期有效,想顺便赚点话费的来吧。问题一直没有解决。

出0入18汤圆

发表于 2015-5-11 19:34:17 | 显示全部楼层
不会  顺路帮忙 顶一个!

出0入0汤圆

发表于 2015-5-11 19:45:30 | 显示全部楼层
看来楼主自己都解决了嘛,QLabel不适合做频繁刷新的图像显示,没有效率。

出0入0汤圆

发表于 2015-5-11 19:53:14 | 显示全部楼层
本帖最后由 ysu533 于 2015-5-11 20:09 编辑
honami520 发表于 2015-5-11 17:51
这个帖子长期有效,想顺便赚点话费的来吧。问题一直没有解决。


QLabel 即使PC上, 分辨率稍高就会卡的. 稍等, 我上传我目前用的代码



你试试, 有什么问题, 互相探讨.  话费什么的就免了.

简单解释下代码, 这个代码主要是用来显示图片的, 本来还有一份主要是显示视频用的. 但是孩子在旁边闹. 我一打开笔记本, 她就给我关了, 我也就不找了. 这个代码是源自显示视频的那个代码, 但是比显示视频的多了局部放大(其实是放大到1:1的功能, 因为经常用小窗体显示高分辨率的图片), 不需要的不管它或者屏蔽掉即可.

函数对外就一个接口 void setData(const QImage &data, const QString &text);
data 为要显示的图片, text 为要附加上面的文字, 不要为空即可.

qt我只在PC平台上用过, 其它平台不太清楚. 这个代码反正在我电脑上播放4个200W的摄像头是流程的. 用QLabel一个都显示不流畅.

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入90汤圆

 楼主| 发表于 2015-5-11 20:07:27 | 显示全部楼层
ysu533 发表于 2015-5-11 19:53
QLabel 即使PC上, 分辨率稍高就会卡的. 稍等, 我上传我目前用的代码

多谢回复。但是,我需要的是在ARM开发板上面能够低占用率的显示摄像头哦,用Qt来做的。如果能够解决,马上话费给你冲上,决不食言。

PC上面因为有显卡的原因(这个原因是我猜得),所以CPU占用率非常低,只占用4%到5%,但是到板子上面就100%或者50%了,很奇怪!

问题一直有效,因为一直想知道怎么样在开发板上面用Qt低CPU占用率的做摄像头显示。

出0入90汤圆

 楼主| 发表于 2015-5-11 20:09:07 | 显示全部楼层
我摄像头只用了320*240分辨率。

出0入0汤圆

发表于 2015-5-11 20:11:54 | 显示全部楼层
honami520 发表于 2015-5-11 20:09
我摄像头只用了320*240分辨率。

你把我的代码去掉一些功能试试, 不去应该也不影响. 视频会自动按比例缩放, 如果和窗体比例不一样, 则会填充黑边.

出0入76汤圆

发表于 2015-5-11 20:12:34 | 显示全部楼层
1. 不要用QLabel来显示图像, 直接画就好了
2. 单独开一个线程来画图, 不要使用UI线程

出0入0汤圆

发表于 2015-5-11 20:14:24 | 显示全部楼层
你应该调用全志本身的GPU处理吧

出0入0汤圆

发表于 2015-5-11 20:25:48 | 显示全部楼层
没自己在label上画过,  推荐用opencv,  很强大的一个库。

出0入0汤圆

发表于 2015-5-11 20:50:30 | 显示全部楼层
坐等大神提出解决方案

出0入8汤圆

发表于 2015-5-11 22:29:25 来自手机 | 显示全部楼层
有了pixmap后直接显示这个pixmap,不要用label
pixmap应该可以把图像内存搞出来,直接改内存

这个问题一定可以解找到关键点
因为qt是开源的
需要的是细心加耐心

出0入90汤圆

 楼主| 发表于 2015-5-12 09:56:28 | 显示全部楼层
ysu533 发表于 2015-5-11 20:11
你把我的代码去掉一些功能试试, 不去应该也不影响. 视频会自动按比例缩放, 如果和窗体比例不一样, 则会填 ...

我这个项目,是只要完成一个功能,就保存一份的,就目前为止一共已经有10份代码了,试验这个Qlable的时候,是用的它单独的功能的。摄像头读取设置也只是320*240,label->setpixmap这句话很快,但是退出之后,CPU自己很耗资源,感觉是在后台消耗一样

出0入0汤圆

发表于 2015-5-12 10:01:18 | 显示全部楼层
honami520 发表于 2015-5-12 09:56
我这个项目,是只要完成一个功能,就保存一份的,就目前为止一共已经有10份代码了,试验这个Qlable的时候 ...

用QWidget重绘不行吗? 一般是在一个线程里面处理yuv数据, 然后发射一个信号. 再把这个信号和我给你代码里面的setData关联就行了, 我觉得你这么大的图片没道理处理不过来. 但是如果用QLabel 是不行的.

出0入90汤圆

 楼主| 发表于 2015-5-12 10:05:35 | 显示全部楼层
skylly3 发表于 2015-5-11 20:25
没自己在label上画过,  推荐用opencv,  很强大的一个库。

opencv我以前也用过,没用的。这个问题一共有3个步骤:
1、从摄像头读数据,很快,1ms内
2、YUV或者JPG转RGB,很快,2-3ms
3、RGB显示到Qt控件,送数据也很快,1-2ms

问题是,定时器40ms执行以上3个流程。内部总共消耗8ms左右。但是执行完成了之后,CPU占用就达到100%或者50%了!神奇。
我个人分析就是,步骤3,只是把数据送给Qt的管理部分,看起来很快,但是它自己内部的执行却花了很久时间。步骤3相当于是非阻塞方式的。

出0入90汤圆

 楼主| 发表于 2015-5-12 10:07:40 | 显示全部楼层
Vmao 发表于 2015-5-11 20:14
你应该调用全志本身的GPU处理吧

全志本身的GPU不会用啊!它本身的GPU还支持opengl es的。但是卖开发板的人都说不会,网上一直在查,也不知道怎么利用。否则的话,有显卡的话,这种问题就根本不是问题了。

出0入90汤圆

 楼主| 发表于 2015-5-12 10:11:41 | 显示全部楼层
ysu533 发表于 2015-5-12 10:01
用QWidget重绘不行吗? 一般是在一个线程里面处理yuv数据, 然后发射一个信号. 再把这个信号和我给你代码里 ...

兄弟你好!我也不想用QLable啊。我也试验了QWidget的,而且我现在的代码已经改成了QWidget的重绘的。我在主线程里面对数据进行处理,生成一个QImage,然后把这个widget给update一下,在它的重绘函数里面drawimage。
效果还是这样。

出0入90汤圆

 楼主| 发表于 2015-5-12 10:13:58 | 显示全部楼层
foxpro2005 发表于 2015-5-11 20:12
1. 不要用QLabel来显示图像, 直接画就好了
2. 单独开一个线程来画图, 不要使用UI线程 ...

你好!请问不用QLabel的话,怎么样能够在窗体上面显示这张图呢?要是单片机,我就直接画了,这玩意Qt没有控件,还真不知道怎么把它画上去。

出0入0汤圆

发表于 2015-5-12 11:42:58 | 显示全部楼层
我当时 在zynq7000上做 用多线程解决

出0入0汤圆

发表于 2015-5-12 11:48:13 | 显示全部楼层
honami520 发表于 2015-5-12 10:13
你好!请问不用QLabel的话,怎么样能够在窗体上面显示这张图呢?要是单片机,我就直接画了,这玩意Qt没有 ...

可以自己做一个绘制图像的控件 或者 可用pixmap+ parinter吧

出0入0汤圆

发表于 2015-5-12 11:49:26 | 显示全部楼层
skylly3 发表于 2015-5-11 20:25
没自己在label上画过,  推荐用opencv,  很强大的一个库。

opencv在 linux 上也是调用 v4l 的库,并且图形界面用的是 gtk 或者qt 的库啊

出0入37汤圆

发表于 2015-5-12 12:06:36 | 显示全部楼层
贴个320x240的图应该不需要40ms吧

你参考下这个,看这个帖子里的paintEvent部分就可以了:
http://www.devbean.net/2012/12/qt-study-road-2-paint-device/


void paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    QPixmap pixmap("qt-logo.png");
    QBitmap bitmap("qt-logo.png");
    painter.drawPixmap(10, 10, 250, 125, pixmap);
    painter.drawPixmap(270, 10, 250, 125, bitmap);
    QPixmap whitePixmap("qt-logo-white.png");
    QBitmap whiteBitmap("qt-logo-white.png");
    painter.drawPixmap(10, 140, 250, 125, whitePixmap);
    painter.drawPixmap(270, 140, 250, 125, whiteBitmap);
}

出10入46汤圆

发表于 2015-5-12 12:09:46 | 显示全部楼层
用QLabel 本身就有问题。
界面刷新会导致假死。 就算开线程,也并不会极大缓解此问题。

可参看QT的范例! 或 GIT上的项目。
QT本身有 multimedia -> QCamera

出0入16汤圆

发表于 2015-5-12 13:29:17 | 显示全部楼层
看各位大神如何解决此问题!顺便学习一下!

出0入0汤圆

发表于 2015-5-12 14:12:58 | 显示全部楼层
帮你顶起,以后可能会用到!

出0入0汤圆

发表于 2015-5-12 17:01:19 | 显示全部楼层
A20 是Mali400  吧

http://linux-sunxi.org/Mali_binary_driver 看看这个能用不

出0入0汤圆

发表于 2015-5-11 14:14:24 | 显示全部楼层
本帖最后由 Vmao 于 2015-5-12 17:20 编辑

http://download.csdn.net/download/yxtouch/7860361

csdn上下的一个东西你参看下

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入90汤圆

 楼主| 发表于 2015-5-12 20:35:27 | 显示全部楼层
Vmao 发表于 2015-5-12 17:18
http://download.csdn.net/download/yxtouch/7860361

csdn上下的一个东西你参看下

多谢回复。这个是硬件编码解码的。我现在不是编码解码速度不够!
是读取完数据,送Qt的控件显示,整个过程只需要8ms,但是造成CPU占用达到100%的问题。

我弄了个定时器,间隔40ms进入执行一段这个操作,这个函数执行8ms。然后我在定时器里面每次进入都打印系统时间,发现,程序是按照间隔40ms进入的,很正常。内部执行了8ms,但是CPU占用率就达到100%。
这个问题是Qt的控件的问题。它在我们可以操作的部分以外的地方,消耗了更多的CPU资源。

上面的各位的方法我都试验过了,一开始是直接加载图片到QLable里面,后来改成了继承QLable,然后重写paintevent的方法。用了drawimage,也用过drawpixmap。
最后,又试验了继承Qwidget,还是这个德行。


我现在只能做成,纯显示的时候就1秒钟刷新25帧摄像头内容到屏上面, CPU 100%占用率。
在做编码成视频的时候,就1秒钟刷新8帧到屏上面,此时CPU占用率只有50%左右,而且是加上了编码的。

退出编码之后,恢复成25帧速度显示,此时CPU占用还是只有50%。

出0入0汤圆

发表于 2015-9-1 22:45:54 来自手机 | 显示全部楼层
你trace一下Qt内的瓶颈呢

出0入84汤圆

发表于 2015-9-2 09:57:23 | 显示全部楼层
正好上个月做过 给你几行代码 自己改下参数就可以了, CPU占用很低。 我采集的是1024*768的分辨率 ,显示240*180预览,一点不卡。 加上图像处理算法也有10+帧 还是单核AM335 800MHZ。
采集格式选YUV比MJPG解码块。
void CMainDlg::paintEvent(QPaintEvent *event)
{
        //显示图像及叠加的信息
        QPainter painter(this);
        m_pixmap = QPixmap::fromImage(m_image.scaled(240, 180,  Qt::KeepAspectRatio));
        painter.drawPixmap(20, 40, m_pixmap);

        QWidget::paintEvent(event);
}

如果你采集图像不是用的阻塞的话 ,定时采集后加判断是否读出了完整图像,因为定时过快会读不出完整图像,如果正确,把YUV转成RGB, 然后通知paintEvent绘制图像
  用  update();  就可以。

出0入84汤圆

发表于 2015-9-2 10:03:05 | 显示全部楼层
这个保证能用,刚做过的项目呵呵。  中间被拦住的是USB的速度和DDR的速度。

2048*1536只能读3帧 ,加上算法后就剩2帧多的输出,还是用了多线程。。CPU占用不高,最高也就50%,剩下都被linux后台传输占用了。。

同样代码4核的IMX6没一点问题,做图像这块还是选DDR带宽高的和CPU性能好的吧, 另外像YUV转RGB这类运算一个是靠CPU,一个是靠内存带宽。

出100入101汤圆

发表于 2016-7-30 18:45:08 | 显示全部楼层
大神很多!

出0入12汤圆

发表于 2016-7-31 07:42:16 | 显示全部楼层
呵呵,标记一下。

出0入0汤圆

发表于 2016-7-31 10:02:28 来自手机 | 显示全部楼层
大神很多,mark一下

出0入0汤圆

发表于 2016-11-3 10:59:38 | 显示全部楼层
大神,请问你是怎么解决这个问题的呢?是先硬件编码成H264格式的再转成RGB吗?还有我利用ffmpeg转换图像格式的时候总是警告说“No accelerated colorspace conversion found from yuv420p to rgb24”,这个我利用x264重新编译ffmpeg也没用,请问您知道怎么解决吗?

出0入90汤圆

 楼主| 发表于 2016-11-3 11:18:33 | 显示全部楼层
ChenTao 发表于 2016-11-3 10:59
大神,请问你是怎么解决这个问题的呢?是先硬件编码成H264格式的再转成RGB吗?还有我利用ffmpeg转换图像格 ...

没有办法解决!这个跟编码没关系;
我直接读出JPG格式的图片,去刷屏也是占用率高;而且我测过,在我的代码部分占用时间并不多,应该是Qt后台在刷新上面废了太多时间;

出0入0汤圆

发表于 2016-11-3 11:26:11 | 显示全部楼层
honami520 发表于 2016-11-3 11:18
没有办法解决!这个跟编码没关系;
我直接读出JPG格式的图片,去刷屏也是占用率高;而且我测过,在我的代 ...

好吧,那利用ffmpeg转格式的时候,我的程序会有上面说的警告,是由swscaler报出来的,而且时间需要50ms左右,请问您在程序中是怎么解决的呢?怎样使得代码运行的时间在几毫秒之内呢?谢谢!

出140入158汤圆

发表于 2016-11-3 11:36:53 | 显示全部楼层
Qt就是这副德行。我以前在LINUX,要不就直接写FrameBuffer(用Memcpy最快),要不就用SDL,记得以前用2440,ffmpeg+SDL,软解压FLV,480x320@20fps,做的电梯楼层显示器,走485,无压力。

出140入158汤圆

发表于 2016-11-3 11:38:34 | 显示全部楼层
honami520 发表于 2016-11-3 11:18
没有办法解决!这个跟编码没关系;
我直接读出JPG格式的图片,去刷屏也是占用率高;而且我测过,在我的代 ...

用QDirectPainter类,应该会快很多

出140入158汤圆

发表于 2016-11-3 11:42:26 | 显示全部楼层
参考这个,QT+ffmpeg+SDL:    http://bbs.csdn.net/topics/390386771

出0入90汤圆

 楼主| 发表于 2016-11-3 12:06:49 | 显示全部楼层
amigenius 发表于 2016-11-3 11:42
参考这个,QT+ffmpeg+SDL:    http://bbs.csdn.net/topics/390386771

多谢回复!我到时候去研究下。

出0入0汤圆

发表于 2016-11-13 17:17:33 | 显示全部楼层
我自己测试没有问题

出0入0汤圆

发表于 2017-8-19 21:52:24 | 显示全部楼层
哥,你这个问题解决没,是用了opengl的库吗,还是咋的,同样遇到了你的问题,不知道怎么解决了

出0入0汤圆

发表于 2017-8-24 23:19:39 来自手机 | 显示全部楼层
图像颜色深度修改看看,如果你的板子设置16bit但qt用32或24就会慢。其实这是qt的先天缺陷,2d没用显卡就这德性

出0入0汤圆

发表于 2017-8-24 23:21:41 来自手机 | 显示全部楼层
stackoverflow一堆问这个问题的,一致的办法就是开opengl利用它来加速,很难搞

出100入101汤圆

发表于 2017-8-25 07:22:55 | 显示全部楼层
amigenius 发表于 2016-11-3 11:36
Qt就是这副德行。我以前在LINUX,要不就直接写FrameBuffer(用Memcpy最快),要不就用SDL,记得以前用2440 ...

楼层显示器,是播放广告的那种?

出0入0汤圆

发表于 2017-8-25 15:36:04 | 显示全部楼层
amigenius 发表于 2016-11-3 11:42
参考这个,QT+ffmpeg+SDL:    http://bbs.csdn.net/topics/390386771

mark一下 这个很给力

出0入0汤圆

发表于 2017-12-12 21:47:06 | 显示全部楼层
我也说下我做的吧  我用的树莓派3 图像不卡 OpenCV读取视频 显示到QLAbel上,图像640*480  ,  但是这个图像大小在我加了图像处理后也卡,后来我把图像改成320*240,就不卡了,也不能叫卡,就是反应滞后,流畅度还是可以的,在WIN7上表示无压力一切OK 图像再大也是没问题。

出0入0汤圆

发表于 2017-12-12 21:53:00 | 显示全部楼层
不知道 楼主有木有遇到Qt里面设置摄像头曝光等参数设置不了得情况,但是用OpenCV可以设置
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-24 22:44

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表