2013-01-31 81 views
1

我一直在嘗試做比較我的IplImage對象中的數據內容。無法訪問IplImage數據

我有以下幾點:

IplImage img1 = IplImage(cv::imread("C:\\TestIm\\barrier_snapshot1.png"),    
                CV_LOAD_IMAGE_GRAYSCALE); 
    for (int i=0; i < img1.widthStep * img1.height; i++) { 
     cout << img1.imageData[i] << endl; 
    } 

但是,當我嘗試打印,它是造成異常,我甚至不能抓住它打印的郵件,看看我做錯了。我的圖像是灰度,我相信如果我不使用cvCreateImage()它沒關係?我知道這將是愚蠢的或與數組訪問有關,我似乎無法從IplImage文檔中輕鬆獲取。

* 爲什麼我要在我的設計中混合使用C和C++代碼? *

不幸的是,我別無選擇!我正在研究一個使用改進的運動檢測應用程序的項目。我的遺留應用程序源代碼使用繁重的BOOST和OpenCV內容。尤其是,它使用IplImage *(我討厭它,使生活困難並導致內存泄漏)來存儲像圖像蒙版等東西。我明白,如果我長期保存IplImage *,我將有非法引用和訪問衝突。所以我保存了IplImage指向的實際內容的副本。舉例說明:

// getLongHistory() returns IplImage* 
IplImage history_long = *(motionHistory.getLongHistory()); 

總共有6個使用IplImage *製作的蒙版圖像。此時此刻,我譴責決定在IplImage *中執行此操作的程序員。問題出現時,我試圖加載這些面具圖片,這是我要做的事:

// Passing pointer to the address of the mask stored (alive in the memory) 
motionHistory.setLongHistory(&(matcher.getCurrentSceneObject().getLongHistory())); 

,我相信我有IplImage的對象的深拷貝和淺拷貝的問題。我相信把它保存爲cv :: Mat from IplImage *並將它作爲IplImage *從cv :: Mat加載可能會減輕負擔,因爲我懷疑它可能在高級函數下面有SOMETHING,這樣複製數據並且相應地完成ROI。但是,作爲一個新手,我可以承擔任何事情。請幫忙!

UPDATE

在我的代碼,我過去這樣做:

/* I store all my mask images in a vector of pairs made of <int, IplImage> 
* __MASK_LONG__ etc. are predefined intergers 
* getMaskLong() etc. methods return IplImage* to the respective mask images. 
*/ 

    myImages.clear(); // To make sure that I have no extra stuff 
    myImages.push_back(std::make_pair<int, IplImage>(_MASK_LONG_, maskHistory.getMaskLong())); 
    myImages.push_back(std::make_pair<int, IplImage>(_MASK_SHORT_, maskHistory.getMaskShort())); 

然而,越來越建議,做一些基礎研發& A之後,我現在這樣做是爲了防止淺拷貝:

myImages.clear(); 
    myImages.push_back(std::make_pair<int, IplImage>(_MASK_LONG_, *cvCloneImage(maskHistory.getMaskLong()))); 
    myImages.push_back(std::make_pair<int, IplImage>(_MASK_SHORT_, *cvCloneImage(maskHistory.getMaskShort()))); 

我可以確認t他的作品,我可以看到最新的蒙版圖像加載到OpenCV窗口!而且我非常確定在任何編程任務中至少進行2/3次深度複製的重要性。所以謝謝你讓我走上正軌。但是,現在我遇到了在實現這些更改時遇到的問題 - 內存分配失敗。而遇到消息:(!我別無選擇!這是一個遺留應用程序)

OpenCV Error: Insufficient memory (Failed to allocate 3686404 bytes) in OutOfMemoryError, 
file /home/naresh/OpenCV-2.4.0/modules/core/src/alloc.cpp, line 52 

如果我足夠深的瞭解C/C++,首先我commiting將它們混合在一起的一種犯罪。其次,存在一個不匹配,即在alloc.cpp文件(正在產生問題的地方)中對malloc/free的調用不正確。或者它可能只是堆已損壞或已滿。我是愚蠢的嗎?

+1

你有什麼理由不使用C++ API而不使用C api?使用cv :: Mat而不是IplImage可以讓你的生活更輕鬆。 –

+0

@IanMedeiros我知道有人會罵我!不幸的是,我是的!請檢查我更新的問題描述! – HubbyHaguBear

+0

說真的,我可以完全理解渴望避免矩陣的深層副本,但使用返回指向IplImages的方法是因爲訪問衝突和內存泄漏而導致的SCREAMING。 cv :: Mat拷貝構造函數,賦值運算符和析構函數的實現方式已經避免了數據的深層拷貝。如果有很長一段時間計劃在這個代碼上工作,我會認真考慮做一些重構。 –

回答

2

不要將OpenCV的C接口與C++接口混合使用

理想情況下,你會使用專門的C++接口,像下面這樣解決問題:

cv::Mat gray = cv::imread("C:\\TestIm\\barrier_snapshot1.png", CV_LOAD_IMAGE_GRAYSCALE); 

cv::Mat_<uchar>::iterator it = gray.begin<uchar>(); 
cv::Mat_<uchar>::iterator end = gray.end<uchar>(); 
for (; it != end; ++it) 
{ 
    cout << *it << endl;   
} 

或者:

cv::Mat gray = cv::imread("C:\\TestIm\\barrier_snapshot1.png", CV_LOAD_IMAGE_GRAYSCALE); 

for (int i = 0; i < gray.cols; i++) 
{ 
    for (int j = 0; j < gray.rows; j++) 
    { 
     cout << gray[gray.cols * j + i] << endl; 
    } 
} 

是,cv::imread()還可以加載輸入圖像的灰度。但是,如果您確實需要堅持使用C接口,請刪除cv::imread()並使用cvLoadImage()代替。有幾個帖子解釋如何做到這一點,使用搜索框

如果您決定繼續混合接口(請不要),check this thread,因爲它說明了如何將IplImage*轉換爲cv::Mat

+0

感謝這...我有點想通了,知道我的問題可能是一個非常古老的,但在C/C++中最可怕的問題之一;深和淺複製。問題是我有一個非常大的使用Boost和OpenCV庫的圖像處理(運動檢測)應用程序。編寫用於處理運動檢測算法的遺留代碼嚴重使用IplImage *。請檢查我的問題描述,因爲我更新了一下,讓用戶知道我有什麼問題...我真的很感謝你的幫助,我投你一票:) – HubbyHaguBear

+0

[你見過這個?](http:// stackoverflow.com/a/13403839/176769) – karlphillip