Qt+大恒相机回调图片刷新使用方式

一、前言

        上篇文章介绍了如何调用大恒SDK获得回调图片,这篇介绍如何使用这些图片并刷新到界面上。考虑到相机的帧率很高,比如200fps是很高的回调频率。那么我们的刷新频率是做不到这么快,也没必要这么快。一般刷新在60帧左右就够了。

二、思路

1,回调函数采用Qqueue队列的方式储存图片

2,主函数设置定时器QTimer,间隔20ms从队列拿去到一张图片刷新到界面上去,注意利用异步的方式执行耗时的操作,在完成格式转化后,再传给UI现场刷新界面,否则会造成界面卡顿。

3,注意对队列使用QMutex,避免资源冲突。

三、部分代码

① 回调函数将相机的原始数据转换为cv::Mat,并调用writeImageQueue(capturedImg),存入队列。因为队列是先入先出,所以队列超过4后,需要先出队,然后再入队,保证图片更新最近的几张。

void Class_CaptureEventHandler::DoOnImageCaptured(CImageDataPointer & objImageDataPointer, void* pUserParam)
{
	if (GX_FRAME_STATUS_SUCCESS == objImageDataPointer->GetStatus())
	{
		//图像获取为完整帧,可以读取图像宽、高、数据格式等
		uint64_t ui64Width = objImageDataPointer->GetWidth();
		uint64_t ui64Height = objImageDataPointer->GetHeight();
		GX_PIXEL_FORMAT_ENTRY emPixelFormat =objImageDataPointer->GetPixelFormat();

		uchar* pbit = (uchar*)objImageDataPointer->GetBuffer();

		void* pRGB24Buffer = NULL;
		cv::Mat capturedImg;
		//原始数据是 Mono8 图像
		if (objImageDataPointer->GetPixelFormat() == GX_PIXEL_FORMAT_MONO8)
		{
			pRGB24Buffer = objImageDataPointer->ConvertToRaw8(GX_BIT_0_7);
			capturedImg = cv::Mat::zeros(cv::Size(ui64Width, ui64Height), CV_8UC1);
			memcpy(capturedImg.data, pRGB24Buffer, ui64Width * ui64Height);
		}
		if (objImageDataPointer->GetPixelFormat() == GX_PIXEL_FORMAT_MONO10)
		{
			pRGB24Buffer = objImageDataPointer->ConvertToRGB24(GX_BIT_2_9, GX_RAW2RGB_NEIGHBOUR, true);
			capturedImg = cv::Mat::zeros(cv::Size(ui64Width, ui64Height), CV_8UC3);
			memcpy(capturedImg.data, pRGB24Buffer, ui64Width * ui64Height * 3);
		}
		writeImageQueue(capturedImg);
	}
}

void Class_CaptureEventHandler::writeImageQueue(cv::Mat mat_Image)
{
	mutex.lock();
	if (CameraImage_queue.count() > 4)
	{
		CameraImage_queue.dequeue();
	}
	CameraImage_queue.enqueue(mat_Image);
	mutex.unlock();
}

② 主函数设置定时器QTimer,间隔20ms从队列拿去到一张图片刷新到界面上去,QFutureWatcher和QFuture组合利用,可以完成异步处理长耗时的图片处理,然后将处理好的图片刷新到界面上,避免界面卡顿。

void CameraConfig::do_timeForUpdateView()
{
	QFutureWatcher<QImage>* watcher = new QFutureWatcher<QImage>(this);
	connect(watcher, &QFutureWatcher<QImage>::finished, this, [this, watcher]() {
		QImage result = watcher->result(); // 获取结果
		if (!result.isNull())
		{
			graphicsView_Camera->displayImage(result);
		}
		watcher->deleteLater(); // 清理 watcher
		});

	QFuture<QImage> future = QtConcurrent::run([this]()->QImage {
		cv::Mat tempMat= dynamic_cast<Class_CaptureEventHandler*>(pCaptureEventHandler)->readImageQueue();
		QImage Image;
		if (!tempMat.empty())
		{
			Image=Mat2QImage(tempMat);
		}
		return Image;
		});
	watcher->setFuture(future);
}

③ 从队列中拿去可用的图片,可以使用tryLock方式,如果10ms内没能拿到就不等了

cv::Mat Class_CaptureEventHandler::readImageQueue()
{
	cv::Mat readImage;
	if(mutex.tryLock(10))
	{
		if (CameraImage_queue.count() > 0)
		{
			readImage = CameraImage_queue.dequeue();
		}	
		mutex.unlock();
	}
	return readImage;
}

四、效果展示

相机未安装镜头,故采集的图片只有亮暗变化

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值