2011-10-28 73 views
1

我正在編輯一個名爲Opencv for Delphi的開源項目,它使用Delphi 6,Delphi 2009和Delphi xe2進行編譯。如何將OpenCV與Unicode版本的Delphi一起使用?

我只是刪除不兼容的(如:Application.MainFormOnTaskbar := True;)的Delphi編譯6。

在運行時D6應用程序工作正常且沒有錯誤,但調用cvopencv.dll休息時被編譯良好,但與運行時錯誤。

原來的項目是用Delphi 2007編譯的西班牙項目工作正常。

在d6 exe中,我無法讀取任何東西,除了???????但其他顯示西班牙語,這意味着這是一個UNICODE問題,當調用cvopencv.dll錯誤發生。

我能做些什麼,使這個項目與2009年或更高版本的Delphi工作(仍然D2009編譯好)

====================== ===大衛Heffemans答案後=====================

procedure TForm1.Button2Click(Sender: TObject); 
var 

    file1 : PAnsiChar; // "haarcascade_frontalface_alt.xml"; 
    file2 : PAnsiChar; //"haarcascade_eye.xml"; 
    file3 : PAnsiChar; //"haarcascade_upperbody.xml"; 
    SourceFileName : AnsiString; 
    StorageType : Integer; 
    ImSize : CvSize; 

begin 
    memo1.Lines.Clear; 
    GetMem(Storage, SizeOf(CvMemStorage)); 
    SourceFileName:=Edit1.Text; 
    StorageType:=0; 
    storage:=nil; 
    storage :=cvCreateMemStorage(storageType); 
    file1 := PAnsiChar(ExtractFilePath(Application.ExeName)+'haarcascade_frontalface_alt.xml'); 
    file2 := PAnsiChar(ExtractFilePath(Application.ExeName)+'haarcascade_eye.xml'); 
    file3 := PAnsiChar(ExtractFilePath(Application.ExeName)+'haarcascade_upperbody.xml'); 

    cascade_f := cvLoad(file1, nil, nil, nil); 
    cascade_e := cvLoad(file2, nil, nil, nil); 
    cascade_ub := cvLoad(file3, nil, nil, nil); 

    if cascade_f=nil then ShowMessage('Íå ìîãó çàãðóçèòü êàñêàä Face'); 
    if cascade_e=nil then ShowMessage('Íå ìîãó çàãðóçèòü êàñêàä Eye'); 
    if cascade_ub=nil then ShowMessage('Íå ìîãó çàãðóçèòü êàñêàä UpperBody'); 

    img := cvLoadImage(PAnsiChar(AnsiString(SourceFileName)), 1); 

    cvNamedWindow((PAnsiChar(AnsiString(Edit1.Text))), 1); 

    detectEyes(img); 
    cvShowImage(PAnsiChar(AnsiString(SourceFileName)), img); 

end; 

end. 

回答

7

你引用的OpenCV庫說在標題的頂部:

Borland Delphi 4,5,6,7 API for Intel開源計算機視覺庫

此代碼提供了一個圍繞OpenCV DLL的Delphi包裝。

對於這些舊版本的Delphi,CharPCharstring地圖AnsiChar,分別PAnsiCharAnsiString。這與純ANSI的OpenCV DLL相匹配。 OpenCV中沒有Unicode API(至少據我所知)。

如果您希望從2009年德爾福使用本機,並把你需要認識到,在2009年德爾福,加入對Unicode的支持。這改變的CharPCharstring地圖映射到WideCharPWideCharUnicodeString分別。這是您遇到的不兼容性的原因,因爲本機後面的DLL仍在處理單字節ANSI文本。

本機可能是最明智的做法是將其更改爲使用AnsiChar,PAnsiCharAnsiString。您可以使用全局搜索來完成此操作並在單元中進行替換。

這將使OpenCV.pas單元再次匹配的DLL。您現在需要小心如何與此OpenCV.pas單元連接。接收PAnsiChar參數的功能需要特殊處理。

例如,考慮下面的例子:

Function cvLoadImage(const filename : PChar; 
    iscolor : integer=1) : PIplImage; cdecl; 

這是原來的聲明。你的查找後和替換它會這樣寫:

Function cvLoadImage(const filename : PAnsiChar; 
    iscolor : integer=1) : PIplImage; cdecl; 

當你調用它,你需要確保你通過一個適當的PAnsiChar。就像這樣:

var 
    FileName: string; 
... 
image := cvLoadImage(PAnsiChar(AnsiString(FileName))); 

必須從string轉換(映射到UnicodeString)到AnsiString,然後纔可以轉換爲PAnsiChar。做不是PAnsiChar(FileName)。這不會將Unicode字符串轉換爲ANSI,並會失敗。

幸運的是OpenCV庫具有相對小的數字,接收文本的API。

+0

謝謝;我認爲我已經通過了你的指導路線,但仍然是同樣的問題,我附上了新的(更新的)源代碼和答案。 – VibeeshanRC

+1

好吧,我可以看到'file1:= PAnsiChar(ExtractFilePath .....「)的代碼,這正是我們所說的不要做的事情,'ExtractFilePath'返回'UnicodeString'將它轉換爲'AnsiString'。你有另一個非常仔細的通讀你的代碼 –

+0

謝謝,它的工作原理,抱歉沒有正確地遵守你的指導 – VibeeshanRC

相關問題