png mat 转 osg

始:在项目中需要用opencv将视频流抠出需要的区域后进行实时显示到osg中,在测试过程中发现用mat保存后的png文件可以在osg中正常显示,内存数据则不行

过程:

1.抠图


bool CuseMat::makeContours(cv::Mat &mat, cv::Mat &matRoi, std::vector<std::vector<cv::Point>> contours)
{
	cv::Mat _matRoi = cv::Mat::zeros(mat.size(), CV_8UC1);;   
	cv::drawContours(_matRoi, contours, 0, cv::Scalar(255), -1);
	cv::Mat tmp;
	mat.copyTo(tmp, _matRoi);
	toPng(tmp, matRoi, 0);
	return true;
}

void CuseMat::toPng(cv::Mat &src, cv::Mat &dst, int mark)
{
	cv::Mat cv_input = src.clone(); 
	if (cv_input.channels() != 4)
	{
		cv::cvtColor(cv_input, dst, CV_BGR2BGRA);
	}
	else
	{
		return;
	}
	for (int y = 0; y < dst.rows; ++y)
	{
		for (int x = 0; x < dst.cols; ++x)
		{
			cv::Vec4b & pixel = dst.at<cv::Vec4b>(y, x); 
			if (pixel[0] == mark && pixel[1] == mark && pixel[2] == mark)
			{
				pixel[3] = 0;
			}
		}
	}
}

2.osg显示图片

void setImageData(unsigned char* data, int cols, int rows, int internalFormat = GL_RGB8, int pixelFormat = GL_RGB)
{
	if (image)
	{
		image->setImage(cols, rows, 1, internalFormat, pixelFormat, GL_UNSIGNED_BYTE, (BYTE*)data, osg::Image::NO_DELETE, 1);
		image->dirty();
	}
}

3.测试内存方式  --失败

	dt.umat.makeContours(dt.tmat, dt.roimat, { {{142,421}, {285,255},{432,380} } }); 
					simpleVieoProject->setImageData(dt.roimat.data, dt.roimat.cols, dt.roimat.rows, GL_RGBA, GL_RGBA); 

4.测试文件方式 -- 成功


tempImage = osgDB::readImageFile(testImage);
setImageData(tempImage->data(), tempImage->s(), tempImage->t(), tempImage->getInternalTextureFormat(), tempImage->getPixelFormat());

5.查找资料

        to osg -- jpg

         https://blog.csdn.net/SJTU_dodoro/article/details/40111067

         https://blog.csdn.net/qq_30547073/article/details/82823848

         https://blog.csdn.net/qq_23191991/article/details/51036051

         ....

         最终 参考  png  -----

         https://blog.csdn.net/tajon1226/article/details/90605051

6.测试网上代码  -- 成功 --png

osg::ref_ptr<osg::Image> CVMat_2_OSGImage(cv::Mat& cvimg)
	{
		unsigned char* data = cvimg.data;
		int width = cvimg.cols;
		int height = cvimg.rows;
		int bytesPerLine = static_cast<int>(cvimg.step);
		switch (cvimg.type())
		{
		case CV_8UC4:
		{
			osg::Image* osgframe = new osg::Image();
			osgframe->setImage(cvimg.cols, cvimg.rows, 1,
				GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, data, //GL_BGRA //cvimg.data  GL_RGBA8
				osg::Image::NO_DELETE, bytesPerLine);
			return osgframe; 
		} 
		default:
		{ 
			return NULL;
		}
		} 
	}


					tcvImg = cv::imread(testImage, cv::IMREAD_UNCHANGED);  
					tempImage =  CVMat_2_OSGImage(tcvImg);

结: mat的png的data数据排列方式与osg image data的png内部排列方式不同,所以osg展示mat的png数据存在问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值