Delphi Programming / Object Pascal
[掲載 2019年02月04日] [更新 2021年03月08日] Delphi 一般・その他 |
OpenCV ライブラリを Delphi で使用する |
動作確認等 |
Windows 7 U64(SP1) + Delphi XE5(UP2) Pro VCL-32 |
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
チェックの結果 |
まず,以下のフォルダにライブラリのパスを通しておきます. |
\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 をインストール |
下図は Delphi-OpenCV に添付の \samples\MultiDemo\FaceDetect のプロジェクトをコンパイルして実行した結果てす.画像処理の世界では有名なレナ ( Lenna ) の画像を使用しています.
Delphi-OpenCV に添付のサンプルを使用する前に,以下の att_faces.tar.Z を解凍して,その中のファイルを全て faces フォルダ直下にコピーするか移動しておきます.
Delphi-OpenCV をダウンロードして解凍展開した状態で添付のサンプルのプロジェクトをコンパイルすると,EXE は [bin] フォルダ内に作成されます. |
\resource\faces\att_faces.tar.Z |
以下のフォルダ内には,テスト用の画像類があります.
参考リンクの記事は英語ですが,関数等を検索してその説明が閲覧できます. |
[備考 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
画像を表示するたけのテストプログラム |
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 に画像を表示
|
リスト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
[画像の回転を行う] のサンプルの実行結果 |
|