Delphi显示Opencv的Mat/IplImage图像

     先下载delphi opencv套件: https://github.com/Laex/Delphi-OpenCV

     打开opencv_classes工程, 增加如下 两个函数导出,用于mat->IplImage, IplImage->mat的转换, 因为delphi opencv这个套件里面的ocvView显示用的是IplImage。

ICLASS_API IplImage __stdcall ImageFromMat(Mat* mat){
		IplImage lvRet=IplImage(*mat);	
		return lvRet;
	}
ICLASS_API IplImage* __stdcall CloneImageFromMat(Mat* mat){
		IplImage* lvRet= cvCloneImage(&IplImage(*mat));
		return lvRet;
}
  这两个函数分别是从Mat转出IplImage和从Mat转出一个IplImage副本, 两者的区别在于, 副本是需要手动销毁的。
  再重新编译。


在delphi里面开一个unit, 加上这两个函数的导入:

 /// <summary>
  /// 从MAT转换一份IplImage过来, 使用后无需销毁
  /// </summary>
function ImageFromMat(const mat: TOpenCVClass): TIplImage; stdcall;
  external opencv_classes_lib name '_ImageFromMat@4';
/// <summary>
/// 从MAT复制一份IplImage过来, 使用后需要手动cvReleaseImage销毁。
/// </summary>
function CloneImageFromMat(const mat: TOpenCVClass): pIplImage; stdcall;
  external opencv_classes_lib name '_CloneImageFromMat@4';

开一个project, 新建一个form, form data如下:

object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 314
  ClientWidth = 536
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -13
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 120
  TextHeight = 16
  object Button1: TButton
    Left = 416
    Top = 25
    Width = 75
    Height = 25
    Caption = 'Button1'
    TabOrder = 0
    OnClick = Button1Click
  end
  object ocvView1: TocvView
    Left = 8
    Top = 16
    Width = 385
    Height = 241
    Frames = <>
  end
  object Button2: TButton
    Left = 416
    Top = 56
    Width = 75
    Height = 25
    Caption = 'Button2'
    TabOrder = 2
    OnClick = Button2Click
  end
  object Button3: TButton
    Left = 416
    Top = 96
    Width = 75
    Height = 25
    Caption = 'Button3'
    TabOrder = 3
    OnClick = Button3Click
  end
  object Button4: TButton
    Left = 416
    Top = 136
    Width = 75
    Height = 25
    Caption = 'Button4'
    TabOrder = 4
    OnClick = Button4Click
  end
end

对应的代码:

unit UMainForm;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    ocvView1: TocvView;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses uCvImgObj;

procedure TForm1.Button1Click(Sender: TObject);
var
lvV:IocvImage;
begin
  lvV:=TocvImage.Create(cvLoadImage('resources\1.jpg')) as IocvImage;
  ocvView1.DrawImage(lvV);
end;

procedure TForm1.Button2Click(Sender: TObject);
var lvMat:IMat;
lvCvImgObj:ICvImg;
lvV:IocvImage;
lvP:pIplImage;
lvTmp:TIplImage;
begin
  //lvMat会自动释放
  lvMat:=imread('resources\1.jpg');
  lvTmp:=ImageFromMat(lvMat._InternalData);
  //lvP也会自动释放,因为它们共享图像矩阵,这些内存由mat管理了。
  lvP:=@lvTmp;
  lvV:=TocvImageEx.CreateClone(lvP) as IocvImage; //clone一份希望IocvImage用,然后TocvImageEx销毁的时候自己销毁它
  ocvView1.DrawImage(lvV); //因为ocvView有一份独立的IplImage副本,所以能在wmpaint的时候正常显示图像
end;

procedure TForm1.Button3Click(Sender: TObject);
var lvMat:IMat;
lvCvImgObj:ICvImg;
lvV:IocvImage;
lvP:pIplImage;
lvTmp:TIplImage;
begin
  //lvMat会自动释放
  lvMat:=imread('resources\1.jpg');
  lvTmp:=ImageFromMat(lvMat._InternalData);
  //lvP也会自动释放,因为它们共享图像矩阵,这些内存由mat管理了。
  lvP:=@lvTmp;
  //cvShowImage('aaa',lvP); //正常显示
  lvV:=TocvImageEx.Create(lvP,rtNone) as IocvImage; //不能用这个,因为TocvImage销毁的时候会自动调用cvReleaseImage销毁IplImage对象,会引起AV,因为这个IplImage所对应的不需要销毁
  ocvView1.DrawImage(lvV); //因为ocvView能够显示图像是在wmpaint的时候不断刷新图像,而这时候lvP指向的图像内存早就被mat释放掉了,所以看不到图像

end;

procedure TForm1.Button4Click(Sender: TObject);
var lvMat:IMat;
lvCvImgObj:ICvImg;
lvV:IocvImage;
begin
  //lvMat会自动释放
  lvMat:=imread('resources\1.jpg');
  //lvP从Mat复制一份IplImage过来,使用后需要自己销毁
  lvV:=TocvImageEx.Create(CloneImageFromMat(lvMat._InternalData),rtAll) as IocvImage; //TocvImageEx销毁的时候自己销毁它
  ocvView1.DrawImage(lvV); //因为ocvView有一份独立的IplImage副本,所以能在wmpaint的时候正常显示图像
end;

end.

其中, button1Click显示了怎么通用从文件读入图像并显示

button2click演示了通过dll调用,从mat转出IplImage并用iocvImage的createClone方式制作副本显示到ocvView1上

button3click演示了为什么不能正常显示图像的原因, 但lvTmp在这个过程中是能正常使用的, 比如用途图像处理或图像保存等。

button4click演示了通过dll调用从mat转出一个IplImage副本,并用ocvView1显示出来。




  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
由于文件大小超过csdn限制的70M. Delphi-OpenCV OpenCV version - 2.4.13 Development environment - Delphi 2010-10.1 Contributors: Laentir Valetov (email: [email protected]) Mikhail Grigorev (email: [email protected]) Requirements: Visual C++ redistributable for Visual Studio 2013 Files: msvcp120.dll, msvcr120.dll, msvcp120d.dll, msvcr120d.dll (1) 32-bit in the "Delphi-OpenCV\redist\VC2013x86\" (2) 64-bit in the "Delphi-OpenCV\redist\VC2013x64\" Shared library FFMPEG 3.2 for Windows can be downloaded from here (3) FFmpeg 32-bit Shared (4) FFmpeg 64-bit Shared Dynamic library OpenCV need to download here Files: _2413.dll and _2413d.dll After installing OpenCV: (5) 32-bit in the C:\OpenCV\build\x86\vc12\bin\ (6) 64-bit in the C:\OpenCV\build\x64\vc12\bin\ Some examples (FFMPEG) required SDL 2.0 and SDL 1.2 (7) SDL.dll and SDL2.dll Copy files OS Windows 64-bit Target platform 64-bit: (2),(4),(6) -> "C:\Windows\System32\" Target platform 32-bit: (1),(3),(5),(7) -> "C:\Windows\SysWOW64\" OS Windows 32-bit Target platform 32-bit: (1),(3),(5),(7) -> "C:\Windows\System32\" How to install: Download the archive. Unzip it to a convenient directory, thus get the following directory structure <PROJECT_ROOT> - Directory, for example, "C:\Delphi\OpenCV\" <bin> <redist> <resource> <samples> <source> Add the search path for the modules of the project in Delphi IDE (Tools-Options-Delphi Options-Library-Library path) <PROJECT_ROOT>\source <PROJECT_ROOT>\source\utils <PROJECT_ROOT>\source\component <PROJECT_ROOT>\source\sdl <PROJECT_ROOT>\source\opengl <PROJECT_ROOT>\source\ffmpeg <PROJECT_ROOT>\resource\facedetectxml where <PROJECT_ROOT> directory, which was unzipped project. To install the components, open and install <PROJECT_ROOT>\source\component\DelphiXX\OpenCVXXX.dpk <PROJECT_ROOT>\source\component\DelphiXX\dclCommonOpenCVXXX.dpk <PROJECT_ROOT>\source\component\DelphiXX\dclVCLOpenCVXXX.dpk <PROJECT_ROOT>\source\component\DelphiXX\dclFMXOpenCVXXX.dpk Open in Delphi IDE and compile: Examples of the use of certain functions and procedures <PROJECT_ROOT>\samples\LibDemo\LibDemo.groupproj Examples of the use of video processing algorithms <PROJECT_ROOT>\samples\MultiDemo\MultiDemo.groupproj Examples of the use of video processing algorithms using VCL.Forms <PROJECT_ROOT>\samples\VCLDemo\VCLDemo.groupproj Examples of using FFMPEG library header files are in the <PROJECT_ROOT>\samples\FFMpeg\FFMPEG.groupproj Examples of use of components <PROJECT_ROOT>\samples\Components\ComponentsDemo.groupproj Donate (PayPal USD) Donate (PayPal EUR) Donate (PayPal RUB) Yandex Money: 410012802258318
回答: OpenCV中的MatIplImage是两种不同的图像数据结构。MatOpenCV 2.x版本引入的新的图像数据结构,而IplImageOpenCV 1.x版本中使用的图像数据结构。Mat是一个更加灵活和方便的图像容器,可以方便地进行图像处理和操作。而IplImage则是一个较为底层的图像结构,使用起来相对复杂一些。 在将Mat转换为IplImage时,可以使用cvCloneImage或cvCopy函数来进行转换。cvCloneImage会创建一个新的IplImage对象,并将Mat的数据复制到新的IplImage中。而cvCopy则是将Mat的数据复制到已有的IplImage对象中。 在将IplImage转换为Mat时,可以使用Mat的构造函数来进行转换。默认情况下,该构造函数会进行浅拷贝,只创建图像头而不复制数据。如果需要进行深拷贝,可以将copyData参数设为true。 需要注意的是,MatIplImage之间的转换只是创建了新的图像头,并没有复制图像数据。因此,在进行转换时需要确保原始图像数据的有效性。 #### 引用[.reference_title] - *1* [OpenCv Mat, IplImage 相互转换](https://blog.csdn.net/songzige/article/details/50916575)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [OpenCV MatIplImage比较以及相互转换](https://blog.csdn.net/u012260117/article/details/50932253)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值