【问题标题】:How can I use OpenCV with Unicode versions of Delphi?如何将 OpenCV 与 Unicode 版本的 Delphi 一起使用?
【发布时间】:2011-10-28 07:01:53
【问题描述】:

我正在编辑一个名为 Opencv for Delphi 的开源项目,它可以与 Delphi 6 、Delphi 2009 和 Delphi xe2 一起正常编译。

我刚刚删除了 Delphi 6 编译的不兼容(例如:Application.MainFormOnTaskbar := True;)。

在运行时 d6 应用程序运行良好,没有错误,但其余的编译良好,但在调用 cvopencv.dll 时出现运行时错误。

原始项目是使用 Delphi 2007 编译的西班牙项目,运行良好。

在 d6 exe 中,除了 ???????但其他人以西班牙语显示,这意味着这是一个 UNICODE 问题,当调用cvopencv.dll时会发生错误。

如何使这个项目与 Delphi 2009 或更高版本一起工作(仍然 d2009 编译良好)

==========================大卫·赫夫曼回答后================== ===

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.

【问题讨论】:

    标签: delphi unicode opencv


    【解决方案1】:

    您引用的 OpenCV 库在标题顶部这样说:

    用于英特尔开源计算机视觉库的 Borland Delphi 4、5、6、7 API

    此代码提供了一个围绕 OpenCV DLL 的 Delphi 包装器。

    对于这些较旧的 Delphi 版本,CharPCharstring 分别映射到 AnsiCharPAnsiCharAnsiString。这与纯 ANSI 的 OpenCV DLL 相匹配。 OpenCV 中没有 Unicode API(至少据我所知)。

    如果您希望在 Delphi 2009 及更高版本中使用此单元,您需要认识到在 Delphi 2009 中添加了 Unicode 支持。这将CharPCharstring 的映射分别更改为WideCharPWideCharUnicodeString。这是您遇到不兼容的原因,因为该单元后面的 DLL 仍在处理单字节 ANSI 文本。

    可能对这个单元最明智的方法是将其更改为使用AnsiCharPAnsiCharAnsiString。您可以通过在单元中进行全局搜索和替换来做到这一点。

    这将使 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 数量相对较少。

    【讨论】:

    • 谢谢;我想我已经阅读了你的指导方针,但仍然是同样的问题,我已经附上了新的(更新的)源代码和答案。
    • 好吧,我马上就可以看到可以执行file1 := PAnsiChar(ExtractFilePath..... 的代码。 ExtractFilePath 返回一个 UnicodeString 将其转换为 AnsiString。我建议您再次仔细阅读您的代码。
    • 谢谢,它有效,抱歉没有正确遵循您的指南
    【解决方案2】:

    在 github 上查看项目 - Delphi-OpenCV(OpenCV 版本 - 2.4.6,环境 - Delphi XE2-XE4)。 Delphi中OpenCV库头文件的翻译:https://github.com/Laex/Delphi-OpenCV

    【讨论】:

      猜你喜欢
      • 2015-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-02
      • 2020-07-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多