要轉換到Mat
BitMap
,我用下面的代碼從here內存泄漏而轉換opencv的墊到.NET BitMap的
System::Drawing::Bitmap^ MatToBitmap(const cv::Mat& img)
{
PixelFormat fmt(PixelFormat::Format24bppRgb);
Bitmap ^bmpimg = gcnew Bitmap(img.cols, img.rows, fmt); //unfortunately making this variable global didn't help
BitmapData ^data = bmpimg->LockBits(System::Drawing::Rectangle(0, 0, img.cols, img.rows), ImageLockMode::WriteOnly, fmt);
byte *dstData = reinterpret_cast<byte*>(data->Scan0.ToPointer());
unsigned char *srcData = img.data;
for (int row = 0; row < data->Height; ++row)
memcpy(reinterpret_cast<void*>(&dstData[row*data->Stride]), reinterpret_cast<void*>(&srcData[row*img.step]), img.cols*img.channels());
bmpimg->UnlockBits(data);
return bmpimg;
}
首先,我抓住從網絡攝像頭(opencv的)圖像然後傳遞到Mat
上述方法,則顯示winform中的BitMap
(C++/Cli)。
我爲視頻中的每一幀調用上面的方法。當發生這種情況時,我注意到內存消耗以指數形式增加(在Visual Studio的診斷工具中)
在幾秒鐘內我得到OutOfMemoryException
(當內存使用量超過2 GB時,只有250mb就足夠了)
如何釋放上面的所有資源方法完成後執行
任何人都可以指出問題嗎?
感謝
更新:我不得不出售/刪除Bitmap
,一旦我釋放Bitmap
,內存使用量保持不變(約177MB),但圖像也不會被顯示出來。所有的方法都是從用戶定義的線程調用的,所以我不得不使用委託,然後調用UI組件(PictureBox來顯示圖片)。下面是完整的代碼
private: delegate Void SetPicDelegate(System::Drawing::Image ^pic);
SetPicDelegate^ spd;
System::Threading::Thread ^user_Thread;
private: Void Main()
{
user_Thread= gcnew System::Threading::Thread(gcnew ThreadStart(this, &MainClass::run));
user_Thread->Start();
}
private: void run()
{
while(true)
{
cv::Mat img; //opencv variable to hold image
///code to grab image from webcam using opencv
Bitmap ^bmpimg;
spd = gcnew SetPicDelegate(this, &MainClass::DisplayPic);
bmpimg = MatToBitmap(img);
this->pictureBox1->Invoke(spd, bmpimg);
delete bmpimg;
//above line helps control of memory usage, but image will not be displayed
//perhaps it will be displayed and immediately removed!
}
}
private: Void DisplayPic(System::Drawing::Image ^pic)
{
try { this->pictureBox1->Image = pic; }catch (...) {}
}
在run
方法需要時,直到下一個到達保留當前位圖一些修改?
我懷疑它是在這個函數的調用者中,當你完成從這個函數返回的'Bitmap'之後,它是否被處理? – kennyzx
@kennyzx,謝謝你的回覆。你是對的!我不得不發佈'Bitmap',我以爲'.net'會自動處理它。我已經更新了這個問題,你能回答嗎? –
is this line'this-> pictureBox1-> Invoke(d,bmpimg);'本意是this-> pictureBox1-> Invoke(spd,bmpimg);'? – kennyzx