OpenCV中将Mat RGBA4通道转换成RGB3通道

在OpenCV中,有一种数据结构是Mat,我们一般会定义一个frame的变量,这个变量可以是4通道的,也可以说3通道的。
前不久在一个项目中遇到了这个问题,要求是用ZED相机来实时拍摄视频并实时显示。ZED相机中的Mat是4通道的,虽然也可以调用3通道的模式,但是调用3通道的模式有问题。如果将ZED中sl转化成OpenCV格式后的image_ocv直接转换成3通道模式的话,会导致预览窗口只有一帧画面卡死,不会连续采集图像。所以将ZED相机中的sl::Mat结构(image_zed)先变成OpenCV的Mat结构(image_ocv),然后赋值给OpenCV中的Mat(frame),然后再将frame转换成3通道的,就就可以实现实时采集视频了。
代码如图:
下图是OpenCV中的Mat,命名frame
OpenCV中将Mat RGBA4通道转换成RGB3通道_第1张图片
下图是将ZED相机中sl的Mat,命名image_zed,然后转化成OpenCV格式的Mat:image_ocv
OpenCV中将Mat RGBA4通道转换成RGB3通道_第2张图片

先将image_ocv转换成frame,然后将frame变成3通道。这样不会出问题,如果将image_ocv先转换成三通道,而后赋值给frame,会只显示一帧画面。
OpenCV中将Mat RGBA4通道转换成RGB3通道_第3张图片

			frame = image_ocv;

			//四通道->三通道
			cvtColor(frame, frame, COLOR_RGBA2RGB);

下面是部分代码:

	// To share data between sl::Mat and cv::Mat, use slMat2cvMat()
// Only the headers and pointer to the sl::Mat are copied, not the data itself
	sl::Mat image_zed(new_width, new_height, sl::MAT_TYPE::U8_C4);
	cv::Mat image_ocv = slMat2cvMat(image_zed);

#ifndef HAVE_CUDA // If no cuda, use CPU memory
	sl::Mat depth_image_zed(new_width, new_height, sl::MAT_TYPE::U8_C4);
	cv::Mat depth_image_ocv = slMat2cvMat(depth_image_zed);
#else
	Mat depth_image_zed_gpu(new_width, new_height, MAT_TYPE::U8_C4, sl::MEM::GPU); // alloc sl::Mat to store GPU depth image
	cv::cuda::GpuMat depth_image_ocv_gpu = slMat2cvMatGPU(depth_image_zed_gpu); // create an opencv GPU reference of the sl::Mat
	cv::Mat depth_image_ocv; // cpu opencv mat for display purposes
#endif


	char key = ' ';
	while (1) {
		// A new image is available if grab() returns SUCCESS
		if (zed.grab(runtime_parameters) == sl::ERROR_CODE::SUCCESS) {

			// Retrieve left image
			zed.retrieveImage(image, sl::VIEW::LEFT);
			// Retrieve depth map. Depth is aligned on the left image
			zed.retrieveMeasure(depth, sl::MEASURE::DEPTH);
			// Retrieve colored point cloud. Point cloud is aligned on the left image.
			zed.retrieveMeasure(point_cloud, sl::MEASURE::XYZRGBA);
			// Retrieve the left image, depth image in half-resolution
			zed.retrieveImage(image_zed, sl::VIEW::LEFT, sl::MEM::CPU, new_image_size);
#ifndef HAVE_CUDA 
			// retrieve CPU -> the ocv reference is therefore updated
			zed.retrieveImage(depth_image_zed, sl::VIEW::DEPTH, sl::MEM::CPU, new_image_size);
#else
			// retrieve GPU -> the ocv reference is therefore updated
			zed.retrieveImage(depth_image_zed_gpu, VIEW::DEPTH, MEM::GPU, new_image_size);
#endif
			// Retrieve the RGBA point cloud in half-resolution
			// To learn how to manipulate and display point clouds, see Depth Sensing sample
			zed.retrieveMeasure(point_cloud, sl::MEASURE::XYZRGBA, sl::MEM::CPU, new_image_size);

			//显示相机信息
			if (display_map)
			{
				cv::imshow("Image", image_ocv);
				//cv::waitKey(30);
			}


#ifdef HAVE_CUDA
			// download the Ocv GPU data from Device to Host to be displayed
			depth_image_ocv_gpu.download(depth_image_ocv);
#endif
			if (display_depth)
			{
				cv::imshow("Depth", depth_image_ocv);
				//cv::waitKey(30);
			}

			frame = image_ocv;

			//四通道->三通道
			cvtColor(frame, frame, COLOR_RGBA2RGB);

你可能感兴趣的:(opencv,计算机视觉)