Page 1 of 1

Locate position of frame and crop image to it

Posted: 2013-01-11T05:19:42-07:00
by Aesthir
Ok, this should be a simple one... :D I have a huge mass of images that all have common identifying features, the most important is a solid color frame that is always the same color. I want to locate the top-left and bottom-right positions of this frame in the image, then use those positions to crop anything outside of the frame. Here is an example:

I want this photo: Image
... to turn into this photo: Image

These are always true:
  • • always sRGBA PNGs saved loss-less (do not want re-sampling/dithering/fuzz/etc…)
    • they have a Generic RGB profile
    • frame color is always srgba(18,139,4,1) or #128B04
    • image inside frame is always 220x220px
    • frame is always 2px wide
    • total dimensions always 224x224px
These are random:
  • • framed portion is located randomly within the larger image
    • generally 70,000-80,000 colors in each
So how easy is this? Just locate the first horizontal green line of 224px, if it's first pixel also has a green line at 224px down, use those dimensions to crop.

Anyone?

Aesthir

Re: Locate position of frame and crop image to it

Posted: 2013-01-11T12:31:04-07:00
by Aesthir
If the solution takes too much time to write, can I have the IM script that will get the srgba value of a particular pixel? I can write a bash script from there to finish it up...

I'd want to be able to choose the pixel x and y location within the png... so crop image to 1x1px, save as text | grep/sed/awk?

for...
  • convert Sample.png ("crop ... left with 1x1 image from 10x0") Sample.txt | grep -Fiwe '#128B04'
    convert Sample.png ("crop ... left with 1x1 image from 10x2") Sample.txt | grep -Fiwe '#128B04'
    convert Sample.png ("crop ... left with 1x1 image from 10x4") Sample.txt | grep -Fiwe '#128B04'
    etc...
done

That'll make it easier. :D

Aesthir

Re: Locate position of frame and crop image to it

Posted: 2013-01-11T15:32:53-07:00
by fmw42
try this. you can strip out too much information if you want with sed


convert image txt:- | grep "#128B04"

or

convert image txt:- | grep "#128B04" | sed -n 's/^\(.*\):.*$/\1/p'

Re: Locate position of frame and crop image to it

Posted: 2013-01-12T09:48:59-07:00
by Aesthir
thx, that's the first thing I tried, but converting the entire image to txt takes about a minute of processing and makes a file about a Gb big. This is why I want to do it pixel by pixel if possible... (I know it is).

Aesthir

Re: Locate position of frame and crop image to it

Posted: 2013-01-12T11:55:41-07:00
by glennrp
Try the "-trim" option.

Re: Locate position of frame and crop image to it

Posted: 2013-01-12T11:55:50-07:00
by fmw42
I am not sure this will work. But try making an image that it just your green border with transparency inside. Then try using the IM compare to search for the border template inside the larger image. This works in general, but I have not tried it with transparency. Also it is slow. It may be that IM will ignore the transparency and use black instead and so that will not likely work well. But I think there is one metric, fuzz, that is transparency aware, but I am not sure if that means a "don't care condition"

see
http://www.imagemagick.org/script/compare.php
http://www.imagemagick.org/Usage/compare/ (see section on statistics for fuzz metric)


An old example is at
viewtopic.php?f=1&t=14613&p=51076&hilit ... ric#p51076

but you now need to add -subimage-search to inform IM that the two images are different sizes. see
http://www.imagemagick.org/script/comma ... age-search

If the search bails without a match, you may also need to use -dissimilarity-threshold. see
http://www.imagemagick.org/script/comma ... -threshold

Re: Locate position of frame and crop image to it

Posted: 2013-01-20T17:49:34-07:00
by anthony
This is not about digital image processing in generate, but how to do this in ImageMagick -- wrong section.

I have moved it to Users

Re: Locate position of frame and crop image to it

Posted: 2013-01-20T18:01:09-07:00
by anthony
As the frame color is very specific, I would just create a mask of just that color (white on black).
EG: map any pixel not that color to black, then map that color to white.
convert image.png -fill black +opaque "#128B04" -fill white -opaque "#128B04" frame_mask.png

With that mask you can then either look for a 'corner'
* Using Hit and Miss morphology http://www.imagemagick.org/Usage/morphology/#hitmiss
* or Correlation (convolution variant) http://www.imagemagick.org/Usage/convol ... ate_search

* or just a "Compare" sub-image search (slower be returns the result directly) http://www.imagemagick.org/Usage/http:/ ... #sub-image

Or compess (scale) the mask to a vertical image, and later a horizontal image, and look for the edges of the box


I'm not sure which I would settle with as being the best for your situation with regard to 'noise' (other parts containing that specific green frame color.

Re: Locate position of frame and crop image to it

Posted: 2013-01-20T19:01:06-07:00
by snibgo
Fred's method works fine, and it's fast as the frame occupies most of the image, so IM doesn't need to search far.

Code: Select all

compare -metric AE -dissimilarity-threshold 1 -subimage-search deframe.jpg just_the_frame.png f.png
I can't test it properly because the supplied image is JPG. But it works, giving the coordinates of the top-left corner of the green frame.