2015-08-14 62 views
0

我似乎遇到的問題是,當我加載存儲爲xml文件的IplImgaes時,與IplImage對象關聯的某些數據成員已損壞。例如,d1-> width應該是1024,而d1-> height應該是768.相反,無論我加載這些圖像的方式如何,我都會得到像-72538984,-1272467456和0這樣的垃圾值。我也有測試了d1-> depth和d1-> n的通道,它們擁有相似的垃圾值。我使用OpenCV C API xml持久性來向磁盤寫入和讀取這些映像。我已閱讀並重讀相關文檔以確保我正確使用API​​,但似乎無論我如何讀取圖像,仍然存在某種形式的數據丟失或損壞。爲什麼從OpenCV中的XML文件加載會破壞我的數據?

我使用xml持久性的原因是當我在使用圖像的程序中使用函數cvSaveImage時,函數會將數據從16位截斷爲8位格式。這是我的理解,使用XML持久性將避免這個問題。另外,我試圖避免在這個項目中使用C++ API,因爲它是使用C API編寫的以前工作的擴展。根據我在下面包含的代碼,我可以確定我正確地執行了這一部分,並且問題在於圖像創建,存儲,複製和使用過程中的其他地方?還是有什麼我在這裏做的是明顯錯誤的?非常感謝您的幫助。

方法1

CvFileStorage * fs1 = cvOpenFileStorage("/home/bot/luca-HSV/HSVD/GRID1/SQUARE4/DEPTH180.xml", 0, CV_STORAGE_READ); 
CvFileStorage * fs2 = cvOpenFileStorage("/home/bot/luca-HSV/HSVD/GRID1/SQUARE4/DEPTH144.xml", 0, CV_STORAGE_READ); 

d1 = (IplImage*) cvReadByName(fs1, 0, "depthImage"); 
d2 = (IplImage*) cvReadByName(fs2, 0, "depthImage"); 

cvReleaseFileStorage(&fs1); 
cvReleaseFileStorage(&fs2); 

方法2

CvFileStorage * fs1 = cvOpenFileStorage("/home/bot/luca-HSV/HSVD/GRID1/SQUARE4/DEPTH180.xml", 0, CV_STORAGE_READ); 
CvFileStorage * fs2 = cvOpenFileStorage("/home/bot/luca-HSV/HSVD/GRID1/SQUARE4/DEPTH144.xml", 0, CV_STORAGE_READ); 

CvFileNode * node1 = cvGetFileNodeByName(fs1, 0, "depthImage"); 
CvFileNode * node2 = cvGetFileNodeByName(fs2, 0, "depthImage"); 

d1 = (IplImage*) cvRead(fs1, node1); 
d2 = (IplImage*) cvRead(fs2, node2); 

cvReleaseFileStorage(&fs1); 
cvReleaseFileStorage(&fs2); 

方法3

d1 = (IplImage*) cvLoad("/home/bot/luca-HSV/HSVD/GRID1/SQUARE4/DEPTH180.xml"/*, NULL, NULL, NULL*/); 
d2 = (IplImage*) cvLoad("/home/bot/luca-HSV/HSVD/GRID1/SQUARE4/DEPTH144.xml"/*, NULL, NULL, NULL*/); 
// I have tried both using and not using these three NULL parameters. It 
// does not seem to make a lot of difference 

所有這些方法我包括以下行之前:

IplImage * d1 = cvCreateImage(cvSize(IMG_WIDTH, IMG_HEIGHT), IPL_DEPTH_64F, 3); 
IplImage * d2 = cvCreateImage(cvSize(IMG_WIDTH, IMG_HEIGHT), IPL_DEPTH_64F, 3); 

示例XML文件頭

<?xml version="1.0"?> 
<opencv_storage> 
<depthImage type_id="opencv-matrix"> 
    <rows>768</rows> 
    <cols>1024</cols> 
    <dt>"3d"</dt> 
    <data> 
+0

我相信C的imwrite功能++ API只允許16位無符號,我需要能夠保持負值。 –

+0

有人可以解釋爲什麼我的問題被拒絕了嗎?我從不考慮大量不必要的代碼的角度提出了我可以思考的各個角度的詳盡細節。問題的第一行也明確說明了核心問題,並提供了以下相關細節。這個問題如何不明確或研究得很好? –

+0

我同意,問題很好:+1。看看答案,看看它是否適合你。 – Miki

回答

2

在你的XML文件,你救了一個CvMattype_id="opencv-matrix"),而不是一個IplImagetype_id="opencv-image")。

所以,當你加載它時,你應該投到CvMat*,否則你會得到垃圾值。

例如,這將工作:

CvFileStorage* fs = cvOpenFileStorage("path_to_xml", 0, CV_STORAGE_READ); 
CvMat* img = (CvMat*)cvReadByName(fs, NULL, "depthImage", NULL); 
cvReleaseFileStorage(&fs); 
+0

謝謝你的幫助,但實際上我剛剛在幾分鐘之前就明白了。我(有點不好意思)在生成圖像的程序中混合使用C++和C API調用。由於使用C++ API調用編寫結構似乎並未與IplImage類型完全兼容,因爲它使用type_id =「opencv-matrix」保存文件,所以您的解決方案可能也會有效。現在它是「opencv-image」。我想他們真的希望人們切換到新版本。真的,非常感謝! –

+0

很高興你做到了。C api已被棄用,如果你可以切換到C++,它會好很多 – Miki

相關問題