2017-05-08 316 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); 

可以輕鬆去除使用該結構的。