Recent

Author Topic: Does anyone have experience using OpenCV in Lazarus?  (Read 7446 times)

xiyi0616

  • Jr. Member
  • **
  • Posts: 69
Does anyone have experience using OpenCV in Lazarus?
« on: July 15, 2025, 09:52:53 am »
I'm using Lazarus 3.9 on Ubuntu 22.04.5 LTS. I installed OpenCV version 4.5.4 using apt-get install libopencv-dev.

The code is as simple as:

unit OpenCVDisplayMain;

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, LCLType,
  ctypes, LCLIntf, ExtCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    Image1: TImage;
    procedure FormCreate(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

  TSize = record
    width, height: Integer;
  end;
  PSize = ^TSize;

var
  Form1: TForm1;

implementation

{$R *.lfm}

function cv_imread(filename: PAnsiChar; flags: Integer): Pointer; cdecl; external 'libopencv_imgcodecs.so.4.5.4d';
function cv_GetSize(img: Pointer): PSize; cdecl; external 'libopencv_core.so.4.5';
procedure cv_releaseImage(img: PPointer); cdecl; external 'libopencv_core.so.4.5'; /
function cvCvtColor(src, dst: Pointer; code: Integer): Integer; cdecl; external 'libopencv_imgproc.so.4.5';
function cvCreateImage(size: PSize; depth: Integer; channels: Integer): Pointer; cdecl; external 'libopencv_core.so.4.5';


{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
var
  OpenCVImage, ConvertedImage: Pointer;
  Size: PSize;
  Filename: string;
  OpenCVImagePtr: PPointer;
  Bitmap: TBitmap;
begin
  Filename := 'test.jpg';

  OpenCVImage := cv_imread(PAnsiChar(AnsiString(Filename)), 1);

  if OpenCVImage <> nil then
  begin
    Size := cv_GetSize(OpenCVImage);

    ConvertedImage := cvCreateImage(Size, 8, 3); // 8 bits per channel, 3 channels (BGR)

    cvCvtColor(OpenCVImage, ConvertedImage, 6); // COLOR_BGR2BGR = 6

    Bitmap := TBitmap.Create;
    try
      Bitmap.PixelFormat := pf24bit;
      Bitmap.Width := Size^.width;
      Bitmap.Height := Size^.height;

      Move(Pointer(ConvertedImage)^, Bitmap.ScanLine[0]^, Bitmap.Width * Bitmap.Height * 3);

      Image1.Picture.Assign(Bitmap);

    finally
      Bitmap.Free;
    end;

    OpenCVImagePtr := @OpenCVImage;
    cv_releaseImage(OpenCVImagePtr);

    OpenCVImagePtr := @ConvertedImage;
    cv_releaseImage(OpenCVImagePtr);

  end else
    ShowMessage('Failed to load image: ' + Filename);
end;

end.

However, I keep getting the following compile-time error: Error: opencvdisplaymain.pas:(.text.n_opencvdisplaymain$_$tform1_$__$$_formcreate$tobject+0x7e): undefined reference to \cv_imread'`.

I've already tried asking AI for help, but haven't been able to resolve the issue. Does anyone have experience with this?


ls /usr/lib/x86_64-linux-gnu/ | grep libopencv_imgcodecs
libopencv_imgcodecs.a
libopencv_imgcodecs.so
libopencv_imgcodecs.so.4.5.4d
libopencv_imgcodecs.so.4.5d
« Last Edit: July 15, 2025, 10:02:58 am by xiyi0616 »

Gustavo 'Gus' Carreno

  • Hero Member
  • *****
  • Posts: 1353
  • Professional amateur ;-P
Re: Does anyone have experience using OpenCV in Lazarus?
« Reply #1 on: July 15, 2025, 02:23:40 pm »
Hey xiyi0616,

Not trying to answer your question, just providing a better display of your code.
It's better on the eyes and will probably capture the attention of more people,

Code: Pascal  [Select][+][-]
  1. unit OpenCVDisplayMain;
  2.  
  3. interface
  4.  
  5. uses
  6.   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, LCLType,
  7.   ctypes, LCLIntf, ExtCtrls;
  8.  
  9. type
  10.  
  11.   { TForm1 }
  12.  
  13.   TForm1 = class(TForm)
  14.     Image1: TImage;
  15.     procedure FormCreate(Sender: TObject);
  16.   private
  17.     { private declarations }
  18.   public
  19.     { public declarations }
  20.   end;
  21.  
  22.   TSize = record
  23.     width, height: Integer;
  24.   end;
  25.   PSize = ^TSize;
  26.  
  27. var
  28.   Form1: TForm1;
  29.  
  30. implementation
  31.  
  32. {$R *.lfm}
  33.  
  34. function cv_imread(filename: PAnsiChar; flags: Integer): Pointer; cdecl; external 'libopencv_imgcodecs.so.4.5.4d';
  35. function cv_GetSize(img: Pointer): PSize; cdecl; external 'libopencv_core.so.4.5';
  36. procedure cv_releaseImage(img: PPointer); cdecl; external 'libopencv_core.so.4.5'; /
  37. function cvCvtColor(src, dst: Pointer; code: Integer): Integer; cdecl; external 'libopencv_imgproc.so.4.5';
  38. function cvCreateImage(size: PSize; depth: Integer; channels: Integer): Pointer; cdecl; external 'libopencv_core.so.4.5';
  39.  
  40.  
  41. { TForm1 }
  42.  
  43. procedure TForm1.FormCreate(Sender: TObject);
  44. var
  45.   OpenCVImage, ConvertedImage: Pointer;
  46.   Size: PSize;
  47.   Filename: string;
  48.   OpenCVImagePtr: PPointer;
  49.   Bitmap: TBitmap;
  50. begin
  51.   Filename := 'test.jpg';
  52.  
  53.   OpenCVImage := cv_imread(PAnsiChar(AnsiString(Filename)), 1);
  54.  
  55.   if OpenCVImage <> nil then
  56.   begin
  57.     Size := cv_GetSize(OpenCVImage);
  58.  
  59.     ConvertedImage := cvCreateImage(Size, 8, 3); // 8 bits per channel, 3 channels (BGR)
  60.  
  61.     cvCvtColor(OpenCVImage, ConvertedImage, 6); // COLOR_BGR2BGR = 6
  62.  
  63.     Bitmap := TBitmap.Create;
  64.     try
  65.       Bitmap.PixelFormat := pf24bit;
  66.       Bitmap.Width := Size^.width;
  67.       Bitmap.Height := Size^.height;
  68.  
  69.       Move(Pointer(ConvertedImage)^, Bitmap.ScanLine[0]^, Bitmap.Width * Bitmap.Height * 3);
  70.  
  71.       Image1.Picture.Assign(Bitmap);
  72.  
  73.     finally
  74.       Bitmap.Free;
  75.     end;
  76.  
  77.     OpenCVImagePtr := @OpenCVImage;
  78.     cv_releaseImage(OpenCVImagePtr);
  79.  
  80.     OpenCVImagePtr := @ConvertedImage;
  81.     cv_releaseImage(OpenCVImagePtr);
  82.  
  83.   end else
  84.     ShowMessage('Failed to load image: ' + Filename);
  85. end;
  86.  
  87. end.

Cheers,
Gus

Gustavo 'Gus' Carreno

  • Hero Member
  • *****
  • Posts: 1353
  • Professional amateur ;-P
Re: Does anyone have experience using OpenCV in Lazarus?
« Reply #2 on: July 15, 2025, 02:41:14 pm »
Hey xiyi0616,

Now that I had a look at your code, can I suggest that you use:
  • libopencv_core.so instead of libopencv_core.so.4.5
  • libopencv_imgcodecs.so instead of libopencv_imgcodecs.so.4.5.4d
  • libopencv_imgproc.so instead of libopencv_imgproc.so.4.5

Usually the .so is a symlink to the correct versioned file. Please confirm what it points at. It's also future proof that you use the .so, since after future updates of the package, it will point to the correct versioned one.

From the little that I could perceive from the error, it looks like you're linking to the incorrect library and you're trying to use definitions that don't exist in the lib that you're linking to. Maybe using the .so instead of the versioned one might solve the issue.

If not, please confirm that the functions that you need are exported. You can use objdump, readelf or nm to confirm that:

Give it a try and then report back please.

Cheers,
Gus

gidesa

  • Sr. Member
  • ****
  • Posts: 260
Re: Does anyone have experience using OpenCV in Lazarus?
« Reply #3 on: July 15, 2025, 02:52:41 pm »
Hello,
you are using the C API of Opencv, it's abandoned and deprecated from Opencv version 2.4, although retained until now. And it expose only a fraction of Opencv functions/classes (it's written in C++).
You can use ocvWrapper46 for Opencv version 4.6, that exposes all C++ classes. For FPC and Delphi, on Windows, Linux, Macos.

https://github.com/gidesa/ocvWrapper46


 

Gustavo 'Gus' Carreno

  • Hero Member
  • *****
  • Posts: 1353
  • Professional amateur ;-P
Re: Does anyone have experience using OpenCV in Lazarus?
« Reply #4 on: July 15, 2025, 03:02:27 pm »
Hey Gidesa,

you are using the C API of Opencv, it's abandoned and deprecated from Opencv version 2.4, although retained until now. And it expose only a fraction of Opencv functions/classes (it's written in C++).
You can use ocvWrapper46 for Opencv version 4.6, that exposes all C++ classes. For FPC and Delphi, on Windows, Linux, Macos.

https://github.com/gidesa/ocvWrapper46

This is valuable information indeed!!!
Thanks for that!!

EDIT
And thanks for the monumental effort in producing the C wrapper and the Object Pascal ones !!!

I'm gonna guess that if he used the tools to search for the functions, they would not return what he expected !!

Cheers,
Gus
« Last Edit: July 15, 2025, 03:45:58 pm by Gustavo 'Gus' Carreno »

gidesa

  • Sr. Member
  • ****
  • Posts: 260
Re: Does anyone have experience using OpenCV in Lazarus?
« Reply #5 on: July 15, 2025, 03:26:07 pm »
Using ocvWrapper46, the code is as simple as this:
(Note that Opencv 4.6 is required, so first you have to remove Opencv 4.5, and then install Opencv 4.6 and ocvWrapper 46 using the instructions for Linux)
Code: Pascal  [Select][+][-]
  1. unit frmtxocvimage;
  2.  
  3. {$mode Delphi}{$H+}
  4. interface
  5.  
  6. uses
  7.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls,
  8.   unOCVImage;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     btStart: TButton;
  16.     Image1: TImage;
  17.     procedure btStartClick(Sender: TObject);
  18.   private
  19.  
  20.   public
  21.  
  22.   end;
  23.  
  24.  
  25. var
  26.   Form1: TForm1;
  27.  
  28. implementation
  29.  
  30. {$R *.lfm}
  31.  
  32. procedure testOcvImage();
  33. var
  34.   ocvimg: TOCVImage;
  35.   filename: string;
  36. begin
  37.   filename:='xxx.jpg';
  38.   ocvimg:=TOCVImage.Create(filename);
  39.   ocvimg.showInImage(form1.image1);
  40.  
  41.   ocvimg.Free;
  42.  
  43. end;
  44.  
  45.  
  46. { TForm1 }
  47.  
  48. procedure TForm1.btStartClick(Sender: TObject);
  49. begin
  50.   testOcvImage();
  51. end;
  52.  
  53. end.
  54.  


xiyi0616

  • Jr. Member
  • **
  • Posts: 69
Re: Does anyone have experience using OpenCV in Lazarus?
« Reply #6 on: July 15, 2025, 04:31:49 pm »
Hey, Gustavo 'Gus' Carreno
First, thank you for your suggestion regarding the code demonstration. It seems you're right, and I'm not very proficient in that area. The reason I need to use OpenCV is that the current version of Lazarus's built-in controls are not good at decoding Tiff Group 4 format. Additionally, I need to analyze lines in images. I'm not very familiar with unOCVImage, and I'm unsure if it can perform these functions, but I will give it a try. Thank you for your advice.

xiyi0616

  • Jr. Member
  • **
  • Posts: 69
Re: Does anyone have experience using OpenCV in Lazarus?
« Reply #7 on: July 15, 2025, 04:34:27 pm »
Hello gidesa, thank you for your suggestion,  I will give it a try.

xiyi0616

  • Jr. Member
  • **
  • Posts: 69
Re: Does anyone have experience using OpenCV in Lazarus?
« Reply #8 on: July 15, 2025, 04:40:57 pm »

Also, I initially used libopencv_core.so, and then, based on AI's suggestion, I tried libopencv_core.so.4.5.

Gustavo 'Gus' Carreno

  • Hero Member
  • *****
  • Posts: 1353
  • Professional amateur ;-P
Re: Does anyone have experience using OpenCV in Lazarus?
« Reply #9 on: July 15, 2025, 05:06:52 pm »
Hey xiyi0616,

Hey, Gustavo 'Gus' Carreno

Please just call me Gus ;)

First, thank you for your suggestion regarding the code demonstration. It seems you're right, and I'm not very proficient in that area. The reason I need to use OpenCV is that the current version of Lazarus's built-in controls are not good at decoding Tiff Group 4 format. Additionally, I need to analyze lines in images. I'm not very familiar with unOCVImage, and I'm unsure if it can perform these functions, but I will give it a try. Thank you for your advice.

Welp, in the end, it looks like @gidesa is the REAL expert in this, so it's awesome he dropped his pearls of wisdom!!

Cheers,
Gus

Gustavo 'Gus' Carreno

  • Hero Member
  • *****
  • Posts: 1353
  • Professional amateur ;-P
Re: Does anyone have experience using OpenCV in Lazarus?
« Reply #10 on: July 15, 2025, 05:10:40 pm »
Hey xiyi0616,

Also, I initially used libopencv_core.so, and then, based on AI's suggestion, I tried libopencv_core.so.4.5.

Yeah... The bots sometimes have some hallucinations ;)

Like I said: The .so is usually a symlink to the versioned file. So best use that, cuz if and when you upgrade your package from the repo, there could be a new versioned file and then your program won't work.
But now, with @gidesa's wrapper, you don't have to care about any of that, as long as you update the wrapper from @gidesa's repo !!

All the luck in your project!!

Cheers,
Gus

gidesa

  • Sr. Member
  • ****
  • Posts: 260
Re: Does anyone have experience using OpenCV in Lazarus?
« Reply #11 on: July 15, 2025, 05:38:45 pm »
Hello xiyi0616,
here a code adapted for your task, reading a TIFF image. For display, there is a conversion from BGRA format (4 channels) to the 3 channels format required by TImage.
Code: Pascal  [Select][+][-]
  1. unit frmtxocvimage;
  2.  
  3. {$mode Delphi}{$H+}
  4. interface
  5.  
  6. uses
  7.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls,
  8.   unOCVImage,
  9.   OPENCVWrapper;
  10.  
  11. type
  12.  
  13.   { TForm1 }
  14.  
  15.   TForm1 = class(TForm)
  16.     btStart: TButton;
  17.     Image1: TImage;
  18.     procedure btStartClick(Sender: TObject);
  19.   private
  20.  
  21.   public
  22.  
  23.   end;
  24.  
  25.  
  26. var
  27.   Form1: TForm1;
  28.  
  29. implementation
  30.  
  31. {$R *.lfm}
  32.  
  33.  
  34. procedure testOcvImage();
  35. var
  36.   ocvimg: TOCVImage;
  37.   ocvimg2: TOCVImage;
  38.   filename: string;
  39. begin
  40.   filename:='..\..\Sample-Tiff-File.tif';
  41.   ocvimg:=TOCVImage.Create(filename);
  42.   if ocvimg.nchannels>3 then
  43.   begin
  44.        ocvimg2:=TOCVImage.Create(ocvimg.width, ocvimg.height, 3);
  45.        pCvcvtColor(ocvimg.PCvMatPtr, ocvimg2.PCvMatPtr, ord(COLOR_BGRA2BGR));
  46.   end else
  47.       ocvimg2:= ocvimg.clone();
  48.   ocvimg2.showInImage(form1.image1);
  49.  
  50.   ocvimg2.Free;
  51.   ocvimg.Free;
  52. end;
  53.  
  54.  
  55. { TForm1 }
  56.  
  57. procedure TForm1.btStartClick(Sender: TObject);
  58. begin
  59.   testOcvImage();
  60. end;
  61.  
  62. end.
  63.  

xiyi0616

  • Jr. Member
  • **
  • Posts: 69
Re: Does anyone have experience using OpenCV in Lazarus?
« Reply #12 on: July 16, 2025, 03:05:14 am »
Okay, Gus.

With Lazarus's version upgrades, it feels better and better to use. I'm happy to see this trend.

Cheers,
xiyi0616

xiyi0616

  • Jr. Member
  • **
  • Posts: 69
Re: Does anyone have experience using OpenCV in Lazarus?
« Reply #13 on: July 16, 2025, 03:18:50 am »
Hello gidesa

Thank you for your time.

I believe unOCVImage is not included in the standard Lazarus installation. I will need to research, install, and familiarize myself with it. In the meantime, I'm temporarily using libtiff for reading images., which seems to be working.

Code: Pascal  [Select][+][-]
  1.        LibHandle := LoadLibrary('libtiff.so');
  2.        if LibHandle = NilHandle then
  3.           raise Exception.Create('Failed to load libtiff');
  4.  
  5.        Pointer(TIFFOpen) := GetProcAddress(LibHandle, 'TIFFOpen');
  6.        Pointer(TIFFClose) := GetProcAddress(LibHandle, 'TIFFClose');
  7.        Pointer(TIFFGetField) := GetProcAddress(LibHandle, 'TIFFGetField');
  8.  

Cheers,
xiyi0616
« Last Edit: July 16, 2025, 03:27:44 am by xiyi0616 »

Gustavo 'Gus' Carreno

  • Hero Member
  • *****
  • Posts: 1353
  • Professional amateur ;-P
Re: Does anyone have experience using OpenCV in Lazarus?
« Reply #14 on: July 16, 2025, 03:23:56 am »
Hey Y'All,

Ermmm, isn't TIFF one of the image formats supported natively by Lazarus?!

I was under the impression it was, but again, most of the times my assumptions end with me inserting foot in mouth... So... dunno...

Cheers,
Gus

 

TinyPortal © 2005-2018