detect object and crop around it?

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
Posts: 6
Joined: 2019-01-03T12:18:07-07:00
Authentication code: 1152

detect object and crop around it?

Post by newbie_user »

I have 4k+ pics of each cross in a cemetery and I would like to crop it out from rest of photo.


My limited knowledge I came up with this and ran it through a loop, and this did OK
magick convert infile.jpg -crop 1800x2000+1400+1300 +repage infile-cropped.JPG (optimize for web viewing while saving needs to be added.)

Some of the crosses are cut off because the cross falls outside of the crop region. So. I thought that maybe someone can tell me how to dynamically locate cross and crop it out replacing my 1400+1300 offset I had hard coded.

2nd requirement is to make the letters more legible. I have no clue where to start.
Any other suggestions to improve the cropped image would be appreciated, maybe deskew cross, but you are only seeing one at a time, I am now sure it is important.

3rd requirement would be to remove the overlapping cross in background of last two sample images and replace with green grass.

thank you so much

User avatar
Posts: 26383
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: detect object and crop around it?

Post by fmw42 »

With regard to automatically cropping, this is one method, but it may not work in all cases, since the clouds are white also and for the cases where other crosses are behind and overlapped by the main cross.

The idea is to make a copy of the image (clone) and threshold it so that the crosses are white and the rest is black. This will not work completely, but if the main cross is the largest object (most area), then you can use connected components to remove all the ones smaller than some threshold in area. Then get the trim coordinates from %@ string format. Delete the processed clone and crop the original.

Note that the threshold area is going to be image dependent.



This is Unix syntax. Note for IM 7, use magick, not magick convert.

Code: Select all

magick Unknown.jpeg \
\( +clone -fuzz 20% -fill white -opaque white -fill black +opaque white -type bilevel \
-define connected-components:mean-color=true \
-define connected-components:area-threshold=200000 \
-connected-components 8 \
-set option:crop "%@" +delete \) \
-crop "%[crop]" +repage \

I am not sure why the result is coming out grayscale. The parentheses should prevent that. But to do your 2nd request, it is best to be grayscale. It crops as color if the output is PNG, but not if JPG. So this seems to be a bug in Imagemagick 7.

Here is the code to just get the largest white region (assuming the clouds are not larger than the cross)

Code: Select all

crop=$(magick Unknown.jpeg -fuzz 20% -fill white -opaque white -fill black +opaque white -type bilevel \
-define connected-components:verbose=true \
-connected-components 8 null: | grep "gray(255)" | head -n 1 | awk '{print $2}')
magick Unknown.jpeg -crop "$crop" +repage Unknown_crop2.jpg

As for your 2nd request, the only thing I can think of is to increase contrast (see -brightness-contrast or -sigmoidal-contrast) after converting to grayscale and perhaps sharpen (see -sharpen or -unsharp). You can just append these commands to the end of the above just before the output.

Code: Select all

magick Unknown_crop2.jpg -colorspace gray -sigmoidal-contrast 10x100% -sharpen 0x3 Unknown_crop_enhance.jpg

With regard to your 3rd request, that is very hard. There are tools for "inpainting", but not in Imagemagick directly. But those smaller crosses would have to be isolated and make transparent for such tools to work.