Delphi Programming / Object Pascal
サイトのトップページへ リンクのページへ ロゴマーク
[掲載 2019年02月04日] [更新 2021年03月08日] Delphi 一般・その他
   
OpenCV ライブラリを Delphi で使用する
動作確認等 Windows 7 U64(SP1) + Delphi XE5(UP2) Pro VCL-32
[整理番号 - 1080]







OpenCV ライブラリを Delphi で使用する


OpenCV ライブラリを Delphi から利用するための Delphi 用ライブラリの紹介記事です.
OpenCV ( Open Source Computer Vision ) は,オープンソースの画像処理・画像解析および機械学習等の機能を実装したライブラリです.
OpenCV ライブラリ (DLL) を Delphi で利用可能にするライブラリ,つまり,OpenCV のラッパーはいくつかありますが,Delphi-OpenCV とネタキリラボが提供しているライブラリについて,インストール手順と簡単なテストの結果の記事です.



OpenCV 以外にも Delphi で利用可能な Computer Vision (コンピュータビジョン) 関係のライブラリがあります.TMSSoftware でも Microsoft computer Vision API を利用する VCL を提供しています.
Computer Vision という表記がなくても,画像処理や画像解析のライブラリにも同様の機能が実装されていることがあります.






01_Delphi 用のライブラリ Delphi-OpenCV  関係のダウンロード


今回は以下のウェブページからダウンロードした Delphi 用の OpenCV ライブラリをテストしています.ダウンロードしたファイル名は Delphi-OpenCV-master.zip です.



図1
Delphi-OpenCV のダウンロードのページ
  • OpenCV Version 2.4.13 用
  • ダウンロードはページの右側にあるボタンから

ダウンロードしたファイルの構成は下図のようになっています.ダウンロードしたらブロックを解除して解凍します.



図2
Delphi-OpenCV-master.zip のファイル構成

次に FFmpeg 用ライブラリ (DLL) をダウンロードします.
以下の 2 番目のリンクのブページからダウンロードできますが,この後の手順でダウンロードする FFmpeg 用のヘッダファイルが 4.02 用なので,Previous Builds の shared から該当バージョンのファイルをダウンロードします.
今回ダウンロードしたのは ffmpeg-4.0.2-win32-shared.zip というファイルです.



[備考]
FFmpeg 用ライブラリ (DLL) のダウンロードのページは 2021年03月08日現在,リンク切れとなっています.以下の Internet Archive からダウンロードできます.ffmpeg-4.0.2-win32-shared.zip は,リストの下の方にあります.


ダウンロードしたらブロックを解除して解凍します.
解凍したら [bin] フォルダ内のファイル を Delphi-OpenCV の \redist\ffmpeg\x86 フォルダ内にコピーしておきます.下図はコピーした結果です.



図3
Delphi 用の FFmpeg ヘッダファイルのダウンロード
  • 強調表示のファイルが今回ダウンロードして追加したファイル

FFmpeg のライブラリを利用するには Delphi の FFmpeg 用のヘッダファイルが必要です.
Delphi 用の FFmpeg のヘッダファイルは以下からダウンロードできます.今回ダウンロードしたのは下図の赤枠のファイルです.



図4
Delphi 用の FFmpeg ヘッダファイルのダウンロード

ダウンロードしたらブロックを解除して解凍します.解凍展開したらルート直下のフォルダとファイルを全て,解凍済みの Delphi-OpenCV の \source\ffmpeg フォルダにコピーし貼り付けます.
下図はコピーして貼り付けた状態です.



図5
FFmpeg ヘッダファイルをコピー




02_Delphi-OpenCV に必要な DLL をシステムフォルダにコピー


Delphi-OpenCV に必要な DLL をシステムフォルダにコピーします.システムフォルダは,32 ビットの Windows では以下の場所です.


    // 32 ビットの DLL をここにコピー
    %SystemRoot%\System32

64 ビットの Windows のシステムフォルダは以下の場所ですが,FFmpeg のヘッダファイルが 32 ビット専用なので,今回は 32 ビットのシステムフォルダである SysWOW64 にコピーしています.


    // 32 ビットの EXE を作成する場合は, 32 ビットの DLL をここにコピー
    %SystemRoot%\SysWOW64    

    // 64 ビットの EXE を作成する場合は, 64 ビットの DLL をここにコピー
    %SystemRoot%\System32

まず Microsoft Visual C++ のランタイムライブラリをシステムフォルダにコピーします.
下図の \redist\VC14\x86 フォルタ内の DLL を全てシステムフォルダにコピーします.
筆者の環境には Visual Studio がインストールされているので,今回はこれらの DLL をシステムフォルダにコピーしていません.



図6
Visual C++ のランタイムライブラリをシステムフォルダにコピー
  • x86 内の DLL が 32 ビット EXE の開発用

次に下図の \rdist\ffmpeg\x86 フォルタ内の DLL を全てシステムフォルダにコピーします.



図7
FFmpeg 用の DLL をシステムフォルダにコピー
  • x86 内の DLL が 32 ビット EXE の開発用
  • ハイライト表示のファイルは追加でダウンロードした DLL

次に下図の \bin\Win32 フォルタ内の DLL を全てシステムフォルダにコピーします.



図8
bin フォルダ内の DLL をシステムフォルダにコピー
  • Win32 内の DLL が 32 ビット EXE の開発用

次に SDL 関係の DLL をシステムフォルダにコピーします.
下図の \redist\SDL\1.2\x86 フォルダ内にある DLL と, \redist\SDL\2.0\x86 フォルダ内にある DLL を全てシステムフォルダにコピーします.



図9
SDL 関係の DLL をシステムフォルダにコピー
  • x86 内の DLL が 32 ビットの EXE 開発用

Visual C++ で作成された OpenCV ライブラリ本体 (DLL) をダウンロードします.
今回テストした Delphi-OpenCV は OpenCV Version 2.4.13 用ですから,OpenCV 2.4.13 をダウンロードします.Delphi-OpenCV のダウンロードのページにダウンロード用ページへのンクがありますが,以下のリンクからダウンロードできます.
ダウンロードしたらブロックを解除して解凍します.

古いバージョンは [Release] または [Tags] から探せます.
2019年02月04日現在の最新バージョンは 4.0.1 です.



図10
Visual C++ の OpenCV ライブラリをダウンロード
  • Version は 2.4.13.3
  • 2017年8月1日リリース

ダウンロードした Visual C++ の OpenCV ライブラリのファイル構成は下図のようになっています.
\build\x86\VC14\bin フォルダ内の DLL の内,末尾が 2413 と 2413d の DLL を全てシステムフォルダにコピーします.それらの DLL が 32 ビットの EXE 開発用です.



図11
Visual C++ 用の OpenCV ライブラリのファイル構成




03_Delphi-OpenCV に必要な DLL の存在をチェック


多くの DLL をシステムフォルダにコピーしました.必要な DLL が実際にシステムフォルダに配置されているかを確認します.下図の CheckCVDep.exe を使用して確認できます.



図12
CheckCVDep.exe がチェック用のプログラム
図13
チェックの結果




04_Delphi-OpenCV のインストール


まず,以下のフォルダにライブラリのパスを通しておきます.


\source
\source\classes
\source\component
\source\ffmpeg\headers
\source\opengl
\source\sdl
\source\sdl2
\source\utils
\resource\facedetectxml

インストール用のパッケージは \source\component フォルダ内にあります.
今回は Delphi XE5(UP2) Pro にインストールしましたが,Delphi XE5 のパッケージはありません.そこで Delphi XE2 のパッケージを使用してインストールしました.



図14
インストール用のパッケージの場所

Delphi の IDE を起動して dclCommonOpenCV230.dpk を開きます.開いたら [インストール] して [上書き保存] します.続いて dclVCLOpenCV230.dpk を開いて同じく [インストール] して [上書き保存] します.これでインストールは終了です.



図15
dclCommonOpenCV230.dpk をインストール
図16
dclVCLOpenCV230.dpk をインストール




05_Delphi-OpenCV の使用例


下図は Delphi-OpenCV に添付の \samples\MultiDemo\FaceDetect のプロジェクトをコンパイルして実行した結果てす.画像処理の世界では有名なレナ ( Lenna ) の画像を使用しています.
Delphi-OpenCV に添付のサンプルを使用する前に,以下の att_faces.tar.Z を解凍して,その中のファイルを全て faces フォルダ直下にコピーするか移動しておきます.

Delphi-OpenCV をダウンロードして解凍展開した状態で添付のサンプルのプロジェクトをコンパイルすると,EXE は [bin] フォルダ内に作成されます.


\resource\faces\att_faces.tar.Z

以下のフォルダ内には,テスト用の画像類があります.
参考リンクの記事は英語ですが,関数等を検索してその説明が閲覧できます.

\resource\media


[備考 1]
Delphi-OpenCV に添付のサンプルプログラムのプロジェクトを Delphi XE5 の IDE で開くと,コメント等の文字列が文字化け状態になるファイルがありました.キリル言語またはバルト言語にエンコードすると文字化けしないようです.
この文字化けが原因がどうかは不明ですが,コンパイルできても実行時に例外が発生するサンプルがありました.


[備考 2]
ラベリングの機能は OpenCV Version 3.0.0 で実装されました. したがって,現在の Delphi-OpenCV では利用できません.OpenCV Version 3.0.0 以降で提供されている DLL は,VC++ 専用となっています.Delphi からは利用できません.


図17
添付のサンプルの実行結果
  • FaceDetect 内のプロジェクト
  • コンソールアプリ

画像を読み込んで表示するだけのサンプルです.



図18
画像を表示するたけのテストプログラム

リスト1
画像を表示するだけのテストプログラム
program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  // 本サンプルで全てが必要なわけではない
  System.SysUtils,
  System.Character,
  System.Math,
  ocv.core.types_c,
  ocv.core_c,
  ocv.highgui_c,
  ocv.objdetect_c,
  ocv.imgproc_c,
  ocv.imgproc.types_c,
  ocv.utils;

var
  LFilePath  : AnsiString;
  LpIplImage : pIplImage;

begin
  try
    // 読み込む画像のファイル名
    // AnsiString 型を使用する
    LFilePath := AnsiString('d:\Opencv\resource\media\lena.jpg');
    // 画像を読み込む
    LpIplImage := cvLoadImage(PAnsiChar(LFilePath),
                              CV_LOAD_IMAGE_ANYCOLOR or CV_LOAD_IMAGE_ANYDEPTH);

    // 画像表示用のウィンドウを生成
    cvNamedWindow('lena', CV_WINDOW_AUTOSIZE);

    // 生成したウィンドウに画像を表示
    cvShowImage('lena', LpIplImage);

    // キー入力待ち
    cvWaitKey(0);

    // 画像表示用のウィンドウを破棄
    cvDestroyWindow('lena');

    // 生成した画像データを解放
    cvReleaseImage(LpIplImage);
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.


画像を読み込んで TImage に描画するサンプルです.OpenCV で扱う画像を直接 TImage には描画できません.そこで TBitmap に変換して TImage に描画しています.
OpenCV では画像のアルファチャンネルの処理や操作はできません.したがって,TBitmap のビット深さを明示的に 24 ビット以下にしておく必要があります.



図19
画像を TImage に描画

リスト2
画像を TImage に描画するだけのテストプログラム
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Image1: TImage;
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

uses
  System.Character,
  System.Math,
  ocv.core.types_c,
  ocv.core_c,
  ocv.highgui_c,
  ocv.objdetect_c,
  ocv.imgproc_c,
  ocv.imgproc.types_c,
  ocv.utils;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  LFilePath  : AnsiString;
  LpIplImage : pIplImage;
  LBitmap    : TBitmap;
begin
  // 読み込む画像のファイル名
  // AnsiString 型を使用する
  LFilePath := AnsiString('d:\Opencv\resource\media\lena.jpg');
  // 画像を読み込む
  LpIplImage := cvLoadImage(PAnsiChar(LFilePath),
                            CV_LOAD_IMAGE_ANYCOLOR or CV_LOAD_IMAGE_ANYDEPTH);

  LBitmap := TBitmap.Create;
  try
    LBitmap.PixelFormat := pf24bit;
    // TBitmap に変換
    IplImage2Bitmap(LpIplImage, LBitmap);

    Image1.Canvas.Draw(0, 0, LBitmap);
  finally
    // 生成した画像データを解放
    cvReleaseImage(LpIplImage);
    FreeAndNil(LBitmap);
  end;
end;

end.




06_TocvView コントロールを使用した画像表示と動画再生


インストールした Delphi-OpenCV の画像表示用コントロール TocvView に画像を表示する例です.
OpenCV の画像の型は IplImage (ポインタ型は pIplImage) です.TocvView に表示する画像の型は IocvImage です.そこで TocvImage.Create を使用して画像の形式を変換しています.



図20
TocvView に画像を表示
  • フォームに以下を配置
    TocvView

リスト3
TocvView コントロールに画像を表示
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls,
  ocv.comp.Types, ocv.comp.Source, ocv.comp.View,
  ocv.core.types_c,
  ocv.core_c,
  ocv.highgui_c,
  ocv.objdetect_c,
  ocv.imgproc_c,
  ocv.imgproc.types_c,
  ocv.cls.highgui,
  ocv.cls.core,
  ocv.cls.contrib,
  ocv.cls.types,
  ocv.utils;

type
  TForm1 = class(TForm)
    Button1: TButton;
    ocvView1: TocvView;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

//=============================================================================
//  フォーム生成時の処理
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
  ocvView1.Anchors := [akTop, akBottom, akLeft, akRight];
  ocvView1.Stretch := False;
end;

//=============================================================================
//  画像を TocvView コントロールに表示
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  LFilePath  : AnsiString;
  LpIplImage : pIplImage;
  LIocvImage : IocvImage;
begin
  // 画像を読み込む
  LFilePath  := 'd:\Opencv\resource\media\apple_cropped.jpg';
  LpIplImage := cvLoadImage(PAnsiChar(LFilePath), CV_LOAD_IMAGE_ANYCOLOR);

  // 画像の型を pIplImage から IocvImage に変換
  // IocvImage は TocvView が自動解放するので明示的な解放処理は不要
  LIocvImage := TocvImage.Create(LpIplImage) as IocvImage;
  // 画像を TocvView コントロールに表示
  ocvView1.DrawImage(LIocvImage);
end;

end.


TocvView コントロールと TocvFileSource コンポーネントを使用すると,動画ファイルを指定して動画を再生できます.
TocvView.VideoSource プロパティに TocvFileSource を設定して,動画ファイルを TocvFileSource コンポーネント側で指定します.



図21
TocvView で動画を再生
  • フォームに以下を配置
    TocvView
    TocvFileSource

リスト4
TocvView コントロールで動画を再生
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls,
  ocv.comp.Types, ocv.comp.Source, ocv.comp.View,
  ocv.core.types_c,
  ocv.core_c,
  ocv.highgui_c,
  ocv.objdetect_c,
  ocv.imgproc_c,
  ocv.imgproc.types_c,
  ocv.cls.highgui,
  ocv.cls.core,
  ocv.cls.contrib,
  ocv.cls.types,
  ocv.utils;

type
  TForm1 = class(TForm)
    Button1: TButton;
    ocvView1: TocvView;
    ocvFileSource1: TocvFileSource;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

//=============================================================================
//  フォーム生成時の処理
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
  ocvView1.Anchors   := [akTop, akBottom, akLeft, akRight];
  ocvView1.Stretch   := False;
  ocvView1.VideoSource := ocvFileSource1;
end;

//=============================================================================
//  フォームを閉じる時の処理
//=============================================================================
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  // 動画の再生を終了させる
  ocvFileSource1.Enabled := False;
end;

//=============================================================================
//  TocvView コントロールで動画を再生
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  LFilePath : AnsiString;
begin
  ocvFileSource1.Enabled := False;
  ocvFileSource1.Loop    := True;
  // 再生速度
  ocvFileSource1.Delay := 120;

  // 再生する動画ファイルを指定
  LFilePath  := 'd:\Opencv\resource\media\768x576.avi';
  ocvFileSource1.FileName := LFilePath;

  // 動画の再生を開始
  ocvFileSource1.Enabled := True;
end;

end.




07_Delphi でコンピュータービジョン ( OpenCV ) - ネタキリラボ


ネタキリラボでも Delphi 用の OpenCV ライブラリを提供しています.OpenCV 1.1 相当のヘッダファイルです.以下のリンクの [Delphi で OpenCV を利用するための準備] のページからダウンロードできます.ファイル名は DelphiOpenCV.zip です.ファイル構成は下図のようになっています.

ネタキリラボのライブラリは,同梱の DLL 以外の DLL は必要ありません.DLL はシステム的にパスの通った場所に必要です.ユニットファイルはライブラリのパスが通った場所に必要です.今回は DLL を全てシステムフォルダにコピーしてテストしています.
Ipl と OpenCV を uses に追加して使用します.



[備考]
DLL はシステム的にパスが通った場所に置く必要があります.アプリケーションが最初に DLL を探しにいくのは EXE がある場所です.
一方,ユニットファイルはコンパイル時に必要ですから,ライブラリのパスが通った場所に置く必要があります.Delphi の IDE が最初に検索するのはそのユニットファイルを使用するユニットファイルまたはプロジェクトファイル等がある場所です.

ネタキリラボの [使い方] の説明にある [カレントフォルダ] はプロジェクトファイルがある場所を意味します.Delphi 7 までは,(特に指定しない限り) カレントフォルダに EXE ファイルも作成されていました.



図22
ネタキリラボの OpenCV の Delphi 用ライブラリのファイル構成

このライブラリは Ansi 版の Borland Delphi 4,5,6,7 で開発されています.Delphi 2009 以降で利用するには Ipl.pas と OpenCV.pas 内のコードを以下のように変更します.


  // 変数の型の変更
  // この変更をしても Delphi 2007 以前で使用可能
  string --> AnsiString
  PChar  --> PAnsiChar
  Char   --> AnsiChar


  // uses 部の変更
  // Delphi XE2 以降で使用する場合はユニットスコープ名を付ける
  uses
    Windows, Sysutils, Math, Vcl.Graphics, IPL;
          変更
  uses
    Winapi.Windows, System.SysUtils, System.Math, Vcl.Graphics, IPL; 

[Delphi で OpenCV 利用基本サンプル集] のページで [全サンプルソース] をクリックすると,サンプルのプロジェクトがダウンロードできます.ファイル名は cvSamples.zip です.
下図はその中のサンプル s36_cvRotate (画像の回転を行う) をコンパイルして実行した結果です.



図23
[画像の回転を行う] のサンプルの実行結果