Recent

Author Topic: How to draw polygons on an image as region of interest and manage them?  (Read 3543 times)

barsoom

  • Jr. Member
  • **
  • Posts: 51
First of all, let me explain the whole idea to make easy to focus my question:

I would like to analyze color from a group of images acquired by a time-lapse camera, for example studing the pizel colors like this (just a simple example):
https://forum.lazarus.freepascal.org/index.php?topic=37242.0
or showing the color histograms.

To do it, i have a TPicture where one of the images is loaded as the base where the user should be able to draw one or more areas of interest on runtime (that could be saved to be loaded latter without requiring to draw them again). Each polygon should be able to have as many nodes as required, and they should be able to be added, deleted or moved (the nodes and the polygons) as many times as desider. The polygons could be filled or not (just only showing the perimeter, or even showed as a "hole" meanwhile the rest of the image is partially covered). Of course, the images should be not modified. Moreover, the user should be able to zoom in and out of the image, and the polygon should zoom in the same ration keeping it in position over the image. Finally, the program should analyze the pixels of each image "included" into each polygon defined by the user.

Here are some examples of what i would like to do:
https://www.researchgate.net/publication/331602837/figure/fig1/AS:734257630679040@1552072069130/Phenocam-regions-of-interest-ROIs-for-the-pinyon-and-juniper-woodland-valley.png
https://www.researchgate.net/profile/Yingying-Xie-3/publication/322575501/figure/fig1/AS:584151702970369@1516284027909/Camera-system-and-examples-of-ROI-region-of-interest-selection-for-four-canopy-trees-at.png

So, in this context, my question is how to do the polygon drawing on top of the image and manage their nodes. Wait, wait, wait... i am not asking to you to write the code for me! Not at all! My question if how to head this task of drawing the polygons.

I saw some ideas about it:
https://stackoverflow.com/questions/15534947/draw-polygon-on-image
https://wiki.lazarus.freepascal.org/Graphics_-_Working_with_TCanvas
So, the problem is not how to draw them in a canvas. In fact i know how to draw polygons and how to save/load the nodes' coordinates  to be used in othee datasets. The problem is that I do not see how to select a node i order to move/delete it, or to add a new node in between other two.

Then, i am lost in the starting point: I do not know if i should do it drawing in the tpicture canvas, or if to overlap the image with a Tpaintbox, neither how to be able to manage the nodes, or if to use a svg-like component, or if there is a component that could help me on this work (i didn´t found after a long research)...

So, could you give some idea about how to start with this?
Sorry for this very long post, and thanks so much in advance!



« Last Edit: October 11, 2021, 08:29:46 pm by barsoom »

Handoko

  • Hero Member
  • *****
  • Posts: 4379
  • My goal: build my own game engine using Lazarus
What you want to do is not simple but that wouldn't be hard if you know the basics. You may learn something useful here:

https://forum.lazarus.freepascal.org/index.php/topic,43474.msg304272.html#msg304272

Read all the posts in the link above. Especially reply #6 - @furious programming's code for making a user resizable selection and reply #12 - @krolikbest's code.

Also my example code (sorry, it has a bug):
https://forum.lazarus.freepascal.org/index.php/topic,41036.msg284131.html#msg284131

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 9686
  • FPC developer.
Re: How to draw polygons on an image as region of interest and manage them?
« Reply #2 on: October 11, 2021, 09:17:28 pm »
In our vision app, we represent regions as runlists. This goes for circles, polygons, and some more odd shapes (like a rough bottle silhouette and a rectangle with a rectangle cut out)

A run is a jump (in bytes) and a number of pixels to inspect.

A runlist is, as the name says, a list of runs. The first jump is relative to coordinate (0,0) of the image or relative to some bounding box that encompasses the shape.

So then the algorithm to visit all pixels of a box becomes roughly:

Code: Pascal  [Select][+][-]
  1.  
  2. px:=<address of first pixel>;
  3. p:=prun(@runlist[0]);
  4. for i:=0 to length(runlist)-1 do
  5.   begin
  6.       inc(px,prun^.jumpbytes);
  7.       for j:=0 to px.len-1 do
  8.        begin
  9.           processpixel(px^);
  10.           inc(p);
  11.        end;
  12.      inc(p,sizeof(trun));
  13.   end;
  14.  

which are all very cheap operations

VTwin

  • Hero Member
  • *****
  • Posts: 1075
  • Former Turbo Pascal 3 user
Re: How to draw polygons on an image as region of interest and manage them?
« Reply #3 on: October 11, 2021, 11:14:18 pm »
I do something similar, users draw polygons or other shapes on bitmap images. I define an image using  multiple layers, either bitmaps or vector graphics. Rendering an image draws them in order. The vector graphics layers are lists of device independent graphics objects which are rendered depending on the selected output device.

The vector graphics are in (arbitrary) world coordinates, but include a world to viewport function to examine pixels within a polygon.

You could likely simplify this by sticking with pixel coordinates and saving polygons as a layer drawn above the bitmap. However maintaining the ability to select and edit the polygons is not simple. If you maintain them as a layer you can query them on mouse clicks.

All bitmap display uses BGRABitmap.
« Last Edit: October 12, 2021, 12:11:46 am by VTwin »
“Talk is cheap. Show me the code.” -Linus Torvalds

Free Pascal Compiler 3.2.0
macOS 10.13.6: Lazarus 2.0.12 (64 bit Cocoa)
Ubuntu 18.04.3: Lazarus 2.0.12 (64 bit on VBox)
Windows 7 Pro SP1: Lazarus 2.0.12 (64 bit on VBox)

winni

  • Hero Member
  • *****
  • Posts: 2792
Re: How to draw polygons on an image as region of interest and manage them?
« Reply #4 on: October 12, 2021, 12:02:40 am »

barsoom

  • Jr. Member
  • **
  • Posts: 51
Re: How to draw polygons on an image as region of interest and manage them?
« Reply #5 on: October 29, 2021, 07:16:04 pm »
Sorry for the delay,
Thanks so much for your tips for not to invent the whell again.
I will explore all these options to see what i am able to do. Probably i will ask here mode doubts. Thanks so much.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 9686
  • FPC developer.
Re: How to draw polygons on an image as region of interest and manage them?
« Reply #6 on: October 29, 2021, 08:00:09 pm »
You could likely simplify this by sticking with pixel coordinates and saving polygons as a layer drawn above the bitmap.

The trouble with mask images (or any other structure that scales with the size of the image, iow O(height*width), is that it immensely pollutes cache. Runlists are linear with one dimension of the image, typically O(height)

 

TinyPortal © 2005-2018