2017-05-08 254 views
0

我在下面的格式imdecode无法加载图像

cv::Mat TestIm(400,400,CV_8UC1,cv::Scalar(0)); 
cv::putText(TestIm,"Hello !",cv::Point(100,200),CV_FONT_HERSHEY_COMPLEX,1,cv::Scalar(255)); 
QByteArray ImData = QByteArray((char *)TestIm.data,TestIm.total()); //this is 1D image data 

现在假设我想从这个数据得到原始图像有一个一维图像数据,我用下面的代码片段:

cv::Mat rawData = cv::Mat(1, ImData.size(), CV_8UC1, ImData.data()); 

cv::Mat decodedImage = cv::imdecode(rawData , CV_LOAD_IMAGE_GRAYSCALE); 
if (decodedImage.data == NULL) 
{ 
    qDebug()<<"Error in decompression !"; 
} 

正如opencv文档中所述,它会猜测图像尺寸并创建输出。但在这种情况下,它总是写

"Error in decompression !" 

这里有什么问题吗?我在不同的项目中多次使用过这段代码,但我不知道它为什么会在这里失败!

如果我改变的第二部分,以这种假设我知道图像尺寸它的工作原理:

cv::Mat decodedImage = cv::Mat(400,400,CV_8UC1,ImData.data()); 

,但我不希望这样,因为在现实场景中我有图像数据的一维数组(未知尺寸),我想获得完整的2D图像。

我也不喜欢使用第三方库,如libjpeg。我想要的只是使用OpenCV来解决它。

我有OpenCV 3.0.0和Qt 5.7,我的操作系统是Ubuntu 16.04。

+0

cv :: imdecode应该用来解码一些编码的图像数据,如带有jpeg或png图像数据的缓冲区。如果我理解它是正确的,你只是简单的rawdata保存到一维byteArray,我想你不能用这种方式“解码”它。但是,如果您仍然知道像素格式和图像尺寸,则可以将原始缓冲区轻松转换回Mat。 – Micka

+0

如果你想编码你的图像,你可以使用openCV cv :: imencode。它会创建一维的编码数据字节阵列,并将维度信息存储在内部的某个位置(例如,在一个jpeg头部或某处),但这会花费一些计算时间,并且取决于编解码器,它将会或不会有损。 – Micka

+0

@Micka请写一个完整的答案。你是对的 – PsP

回答

0

由于有人在评论中提到这些数据(代码中的ImData变量)没有编码!他们只是一些解码的像素值!

为了使cv :: imdecode工作,您必须将初始数据编码为一些已知格式,例如“.jpg”,然后使用该函数获取原始数据。

cv::Mat DecodedImage = TestIm; 
std::vector<uchar> OutputBuffer; 
cv::imencode(".jpg",DecodedImage,OutputBuffer); 
cv::Mat rawData = cv::Mat(1, OutputBuffer.size(), CV_8UC3, OutputBuffer.data()); 
cv::Mat Output = cv::imdecode(cv::Mat(rawData) , CV_LOAD_IMAGE_COLOR); 
+0

对不起,我正在等待那个人(“Micka”)写答案,但他没有在上个月做,所以我写了我自己的答案。 – PsP

0

另一方面,如果你想避免固定一个值,你可以这样做:

define:

​​

前imdecode初始化:

memoryStruct temp; 
temp.memory = NULL; 
temp.size = 0; 

分配临时到您的QByteArray然后调用imdecode

cv::imgTmp = cv::imdecode(cv::Mat(1, temp.size, CV_8UC1, temp.memory), CV_LOAD_IMAGE_UNCHANGED); 

可以轻松去除使用该结构的。