2012-07-23 65 views
2

我有一個C++的DLL構建,並將返回Mat對象。 該圖片信息是384 * 384 * 24色。C + + DLL返回到C##

C#代碼

Bitmap a = new Bitmap(384, 384, 3 * 384, PixelFormat.Format24bppRgb, test1()); 
pictureBox0.Image = a; 

C++代碼

uchar* DLL_EXPORT test1(void) 
{ 
    Mat OriginalImg = imread("c:\\20100812133.jpg", 1); 

    return OriginalImg.data; 
} 

在代碼都OK,但我想讀在灰色圖片。 我會做一些圖像處理(例如:Threshod),並轉換爲顏色, 並返回到C#並顯示它!

C++代碼

uchar* DLL_EXPORT test0(void) 
{ 
    Mat OriginalImg = imread("c:\\20100812133.jpg", 0); 
    threshold(OriginalImg,OriginalImg,0,255,THRESH_OTSU); 
    cvtColor(OriginalImg,OriginalImg,CV_GRAY2BGR); 
    return OriginalImg.data; 
} 

C++代碼失敗了,你能幫忙嗎?


UPDATA http://ppt.cc/h2SI圖片是失敗,我認爲原因是內存。 我修復了c#代碼第3個參數3 * 384到2 * 384。 C#運行正常,但畫面打破這樣http://ppt.cc/IRfd

- UPDATA

Bitmap a = new Bitmap(384, 384, 1 * 384, PixelFormat.Format24bppRgb, test0()); 
Bitmap a = new Bitmap(384, 384, 2 * 384, PixelFormat.Format24bppRgb, test0()); 
Bitmap a = new Bitmap(384, 384, 3 * 384, PixelFormat.Format24bppRgb, test0()); 

Bitmap a = new Bitmap(384, 384, 2 * 384, PixelFormat.Format32bppRgb, test0()); 
Bitmap a = new Bitmap(384, 384, 3 * 384, PixelFormat.Format32bppRgb, test0()); 
Bitmap a = new Bitmap(384, 384, 4 * 384, PixelFormat.Format32bppRgb, test0()); 

我嘗試六,運行是好的,但圖片是休息。

+0

什麼樣的故障?詳細信息,請。 – egrunin 2012-07-23 14:38:32

+0

您需要在此設置不同的圖片格式PixelFormat.Format24bppRgb或將圖片數據轉換爲此數據類型描述的格式 – Sam 2012-07-23 14:55:03

回答

0

你檢查了imread的成功嗎?

Mat OriginalImg = imread("c:\\20100812133.jpg", 0); 
if(OriginalImg.empty()) 
    return NULL; 

而在C#(請注意,我寫的代碼不一定是正確的,但你的想法)

char* imgData = test1; 

if(imgData == Null) 
{ 
// do something smart 
} 

Bitmap a = new Bitmap(384, 384, 3 * 384, PixelFormat.Format24bppRgb, imgData); 
pictureBox0.Image = a; 

這是最常見的錯誤,你可以在編程做之一 - 最煩人的一個

+0

我確定圖片路徑正常。 因爲test1函數返回右圖。 http://ppt.cc/IRfd這樣。 上圖是右圖。 – 2012-07-23 14:51:02

+0

但是我相信你的編程模型是有缺陷的 - 即使它在這種情況下工作。沒有它,你永遠不會知道它實際上是一個錯誤的路徑或其他東西。 – Sam 2012-07-23 14:52:26

+0

我測試你的想法,並且C++返回不爲NULL。 – 2012-07-23 14:58:03

0

另一種選擇:有一個C#包裝庫可以使用,所以你可以直接從託管代碼中直接聯繫DLL。

http://code.google.com/p/opencvdotnet/

+0

thx!但我想要沒有任何庫的C#客戶端! – 2012-07-23 16:36:10

+0

你會考慮使用.NET內置圖像功能而不是OpenCV功能嗎?我不得不猜測,你在OpenCV中使用了.NET不提供的有價值的東西。 – 2012-07-23 23:31:46

1

你返回一個指向一個已經被釋放的局部變量,這將永遠是可靠的。

您需要安排Mat對象足夠長的時間以便Bitmap構造函數複製其內容。最簡單的方法是使用C++/CLI,然後您可以從C++返回.NET位圖:

Bitmap^ MyImageProcessor::test0(void) 
{ 
    Mat OriginalImg = imread("c:\\20100812133.jpg", 0); 
    threshold(OriginalImg,OriginalImg,0,255,THRESH_OTSU); 
    cvtColor(OriginalImg,OriginalImg,CV_GRAY2BGR); 
    return gcnew Bitmap(384, 
         384, 
         3 * 384, 
         PixelFormat.Format24bppRgb, 
         IntPtr(OriginalImg.data) 
         ); 
} 
+0

gcnew或新?如果我使用代碼,我需要在visual C++中?沒有GCC? – 2012-07-23 16:42:10

+0

@wi yu:C++/CLI擴展如'gcnew'只能在Visual C++中使用。但是,您是不是已經在使用Visual Studio,因爲部分代碼是C#?無論如何,C++/CLI不是必須的,但在Mat對象死亡之前創建'Bitmap'非常重要。 – 2012-07-23 17:47:35