Как я могу использовать OpenCV с Unicode-версиями Delphi? - PullRequest
1 голос
/ 28 октября 2011

Я редактирую проект с открытым исходным кодом под названием Opencv для Delphi , который прекрасно компилируется с Delphi 6, Delphi 2009 и Delphi xe2.

Я только что удалил несовместимое (например: Application.MainFormOnTaskbar := True;) для компиляции Delphi 6.

Во время выполнения приложение 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.

Ответы [ 2 ]

7 голосов
/ 28 октября 2011

Библиотека OpenCV, на которую вы ссылаетесь, говорит в верхней части заголовка:

Borland Delphi 4,5,6,7 API для Intel Open Source Computer Vision Library

Этот код представляет оболочку Delphi для библиотек DLL OpenCV.

Для этих более старых версий Delphi Char, PChar и string отображаются на AnsiChar, PAnsiChar и AnsiStringсоответственно.Это соответствует библиотекам OpenCV, которые являются чистыми ANSI.В OpenCV нет API-интерфейсов Unicode (по крайней мере, насколько я могу заметить).

Если вы хотите использовать этот модуль с Delphi 2009 и выше, вам необходимо признать, что в Delphi 2009 была добавлена ​​поддержка Unicode.Это изменило отображение Char, PChar и string map на WideChar, PWideChar и UnicodeString соответственно.Это является причиной несовместимости, с которой вы столкнулись, потому что DLL-библиотека позади этого устройства все еще обрабатывает однобайтовый текст ANSI.

Вероятно, наиболее разумный подход с этим модулем - изменить его на использование AnsiChar, PAnsiChar и AnsiString.Вы можете сделать это с помощью глобального поиска и замены в устройстве.

Это заставит модуль 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, которые получают текст.

1 голос
/ 30 июля 2013

См проект - Delphi-OpenCV на github (версия OpenCV - 2.4.6, среда - Delphi XE2-XE4) Перевод заголовочных файлов библиотеки OpenCV на Delphi: https://github.com/Laex/Delphi-OpenCV

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...