Page 1 of 2
Get center coordinates of object
Posted: 2014-07-11T01:38:53-07:00
by Subbeh
Hi,
I can get the coordinates of all pixels that differ between two images using the following command:
Code: Select all
convert image1.png image2.png -compose difference -composite -colorspace gray -threshold 0 txt:-
This returns the list with coordinates and these coordinates together form several shapes in the picture.
I would like to get the center coordinate of each of these shapes. Is this possible to do with ImageMagick or is there any alternative?
Thanks
Re: Get center coordinates of object
Posted: 2014-07-11T05:47:02-07:00
by snibgo
The first step is to separate the shapes.
Code: Select all
convert image1.png image2.png -compose difference -composite -fill White +opaque Black diff.png
All the shapes are white. Unchanged pixels are black.
To find the shapes:
1. Find a white pixel. That is in a shape.
2. Flood-fill black from that pixel. The flooded pixels are in that shape.
3. Repeat from step 1 until there are no more white pixels.
The next question: what do you mean by "center coordinate" of a shape? The centroid is a possibility, and easy: it is the average of all the (x,y) coordinates in the shape. But it may not be within the shape. (Eg neither a crescent moon nor a ring have the centroid in the shape.) I generally use morphology distance, which finds the point within the shape that is furthest from any edge.
EDIT: Another "center" method: from the white shapes on black background, do a morphology skeleton and line-end reduction. This gives one white pixel per shape (provided none of the shapes are rings). If you have many small shapes, this would be faster than the steps 1,2,3.
Re: Get center coordinates of object
Posted: 2014-07-11T09:04:04-07:00
by fmw42
What platform and version of IM. I have a unix bash shell script, separate, that will extract an image for each shape using a technique similar to what snibgo suggested. From there you can use snibgo's suggestions to find whatever kind of "center" you want. See my link below.
Re: Get center coordinates of object
Posted: 2014-07-11T09:15:37-07:00
by Subbeh
Thanks for the tips! I'm running ImageMagick version 6.7.7-10 on Ubuntu, so I'll be sure to check out your script fmw42
Re: Get center coordinates of object
Posted: 2014-07-11T09:21:35-07:00
by fmw42
What kind of "center" did you have in mind?
Also did you want these centers relative to the bounding box of each extracted image or relative to the top left corner of the original image?
Re: Get center coordinates of object
Posted: 2014-07-11T09:23:52-07:00
by Subbeh
fmw42 wrote:What kind of "center" did you have in mind?
Also did you want these centers relative to the bounding box of each extracted image or relative to the top left corner of the original image?
I guess the optimal center would be the point farthest away from each edge and needs to be relative to the top left corner of the original image
Re: Get center coordinates of object
Posted: 2014-07-11T09:36:31-07:00
by fmw42
How urgent is this? I might be able to add that feature to separate when I can get to it, if it looks feasible and easy to do. Can you post a link to an example image you are using, so I can see what your situation might be. Do you need the separate image also or just the "center" coords?
Re: Get center coordinates of object
Posted: 2014-07-11T09:50:14-07:00
by Subbeh
fmw42 wrote:How urgent is this? I might be able to add that feature to separate when I can get to it, if it looks feasible and easy to do. Can you post a link to an example image you are using, so I can see what your situation might be. Do you need the separate image also or just the "center" coords?
It's not urgent, and it would be great if you could add it.
This is an example:
The shapes are not completely filled and there are some lost white pixels around the shapes, so I might have to tweak a little bit with the image to get the shapes completely filled. But it gives you an idea of what my situation is.
I'll continue working on it with snibgo tips as well in case you don't manage to implement it, but in any way thank you!
Re: Get center coordinates of object
Posted: 2014-07-11T10:03:00-07:00
by snibgo
Black pixels within white create problems for my "morphology skeleton and line-end reduction" suggestion, but my other suggestions are okay.
Small groups of white within black, or even single white pixels, are, of course, shapes in their own right.
Re: Get center coordinates of object
Posted: 2014-07-11T10:30:25-07:00
by Subbeh
snibgo wrote:Black pixels within white create problems for my "morphology skeleton and line-end reduction" suggestion, but my other suggestions are okay.
Small groups of white within black, or even single white pixels, are, of course, shapes in their own right.
I think if I expand the white pixels slightly that problem should be fixed
EDIT: This is the image after expanding the white pixels:
Re: Get center coordinates of object
Posted: 2014-07-11T14:01:27-07:00
by fmw42
You can use -morphology close to fill in small details without growing the size of the objects. See
http://www.imagemagick.org/Usage/morphology/#close
I will look it over and see what I can do over the weekend
Re: Get center coordinates of object
Posted: 2014-07-11T14:52:13-07:00
by Subbeh
I don't know if I'm supposed to post this here, but I ended up getting the coordinates with OpenCV and python after creating the shapes with ImageMagick:
Code: Select all
import numpy as np
import cv2
im = cv2.imread("input.png")
contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
for cnt in contours:
M = cv2.moments(cnt)
cx = int(M['m10']/M['m00'])
cy = int(M['m01']/M['m00'])
print cx, cy
I tried to do it with IM but got stuck. If there is a solution in IM or a scripted solution I'm still very interested in hearing about it.
Re: Get center coordinates of object
Posted: 2014-07-11T16:46:42-07:00
by fmw42
The coordinates you obtained from OpenCV are the centroids. You can get them from IM for the image used further down by the command
identify -verbose -moments image_close_open_1d.png
It also gives more information about the region including the equivalent ellipse parameters and Hu Invariant Image Moments. See
http://en.wikipedia.org/wiki/Image_moment
http://www.imagemagick.org/script/identify.php
Code: Select all
Channel moments:
Gray:
Centroid: 269.14,120.671
Ellipse Semi-Major/Minor axis: 329.344,190.159
Ellipse angle: -20.4914
Ellipse eccentricity: 0.650088
Ellipse intensity: 6.31545 (0.0247665)
I1: 0.0290986 (7.42013)
I2: 0.000211642 (13.762)
I3: 2.86929e-05 (475.767)
I4: 4.56978e-06 (75.7733)
I5: -1.55797e-11 (-4283.5)
I6: -3.33744e-09 (-14.1116)
I7: -4.99544e-11 (-13734.6)
I8: -3.31985e-08 (-140.372)
I have just updated my separate script. So if you use -m=4 or 5 or 6 to get the individual trimmed images, it will print the virtual canvas of the trimmed images, area of white pixels, (rel) centroid for the small images, (abs) centroid to the original base image, and the same for the morphology distance centers.
Here is what I did with your image.
# apply -morphology close followed by -morphology open to close the regions mostly and then to remove isolated pixels
convert image.png -morphology close diamond:1 -morphology open diamond:1 image_close_open_1d.png
# apply my new script
separate -m 5 -v -t -l image_close_open_1d.png tmp.png
Code: Select all
numimages=5
Image Virtual-Canvas Area Rel-Centroid Abs-Centroid Rel-MCenter Abs-MCenter
tmp-1.png 61x19+4+0 739 27.3,6.2 31.3,6.2 21,6 25,10
tmp-2.png 54x32+229+0 1055 24.7,12.7 253.7,12.7 24,12 253,241
tmp-3.png 44x49+317+9 1689 23.1,22.9 340.1,31.9 21,24 338,341
tmp-4.png 54x42+293+348 1409 27.3,19.8 320.3,367.8 26,17 319,310
Re: Get center coordinates of object
Posted: 2014-07-12T04:00:49-07:00
by Subbeh
Thanks a lot for the quick implementation and the information fmw42!
However, I can't get your script to work in my environment. I get to following errors with the original image:
Code: Select all
$ separate -m 5 -v -t -l image_close_open_1d.png tmp.png
numimages=5
convert.im6: geometry does not contain image `./separate_2_23747.mpc' @ warning/attribute.c/GetImageBoundingBox/243.
convert.im6: geometry does not contain image `./separate_2_23747.mpc' @ warning/attribute.c/GetImageBoundingBox/243.
convert.im6: geometry does not contain image `./separate_2_23747.mpc' @ warning/attribute.c/GetImageBoundingBox/243.
convert.im6: geometry does not contain image `./separate_2_23747.mpc' @ warning/attribute.c/GetImageBoundingBox/243.
Image Virtual-Canvas Area Rel-Centroid Abs-Centroid Rel-MCenter Abs-MCenter
(standard_in) 1: syntax error
(standard_in) 1: syntax error
convert.im6: missing expression `' @ error/fx.c/FxEvaluateSubexpression/2109.
convert.im6: unknown image property "%[fx:4294967290+]" @ warning/property.c/InterpretImageProperties/3245.
convert.im6: missing expression `' @ error/fx.c/FxEvaluateSubexpression/2109.
convert.im6: unknown image property "%[fx:4294967290+]" @ warning/property.c/InterpretImageProperties/3245.
/home/sysadm/bin/separate: line 465: xx+: syntax error: operand expected (error token is "+")
Re: Get center coordinates of object
Posted: 2014-07-12T07:05:27-07:00
by snibgo
Here is a single command that quickly outputs the location of the (aproximate) centres of all the white areas. Your image needs a black border, so the results need one to be subtracted from X and Y.
Windows BAT syntax.
Code: Select all
convert ^
test2.png ^
-bordercolor Black -border 1 ^
-channel RG ^
-morphology Erode Diamond ^
-morphology Thinning:-1 Skeleton:3 +channel ^
-channel G ^
-morphology Thinning:-1 LineEnds ^
-channel RGB ^
-auto-level ^
-write centres.png ^
+transparent White ^
sparse-color:
Result:
Code: Select all
37,7,white 255,14,white 343,32,white 321,368,white
"-write centres.png" isn't needed, but shows you what it has done: black stays black, the white areas have become blue, the skeleton is magenta, and the centre of the skeletons are single white pixels.
The channel commands make the colors.
See my Islands page for some more details.
EDIT: Silly me. Shaving off the added boundary removes the need to subtract one:
Code: Select all
convert ^
test2.png ^
-bordercolor Black -border 1 ^
-channel RG ^
-morphology Erode Diamond ^
-morphology Thinning:-1 Skeleton:3 +channel ^
-channel G ^
-morphology Thinning:-1 LineEnds ^
-channel RGB ^
-auto-level ^
-shave 1x1 ^
-write centres.png ^
+transparent White ^
sparse-color:
Code: Select all
36,6,white 254,13,white 342,31,white 320,367,white