Detecting multiple images in one image file
Detecting multiple images in one image file
Hello, i have one big image that has other images in them. What i want to be able to do is detect each image and then crop them.
for instance i may have 3 images in one JPG file
image 1 is 300 x 300
image 2 is 400 x 400
image 3 is 500 x 500
each image has a black border of lets say 2px around them
How can i tell imagemagick to find each image and then crop it out for each one.
more importantly i just need imagemagick to be able to detect other images.
thanks
for instance i may have 3 images in one JPG file
image 1 is 300 x 300
image 2 is 400 x 400
image 3 is 500 x 500
each image has a black border of lets say 2px around them
How can i tell imagemagick to find each image and then crop it out for each one.
more importantly i just need imagemagick to be able to detect other images.
thanks
-
- Posts: 12159
- Joined: 2010-01-23T23:01:33-07:00
- Authentication code: 1151
- Location: England, UK
Re: Detecting multiple images in one image file
What version of IM? On what platform? Please show sample inputs.
snibgo's IM pages: im.snibgo.com
Re: Detecting multiple images in one image file
im using ImageMagick 7.0.8-59 Q16 x86_64 2019-08-05
im using it on a macOS Sierra10.12.6
i will be using BASH terminal and Python <- each one separately, not together.
below is the image.
this jpeg contains 5 other images. i want to crop each one out..eliminate all the whitespace..its also possible that other images that i have may contain text right above each picture that would say 300x200 etc... i want to avoid that text too and not crop it
https://ibb.co/dBPxPLQ
im using it on a macOS Sierra10.12.6
i will be using BASH terminal and Python <- each one separately, not together.
below is the image.
this jpeg contains 5 other images. i want to crop each one out..eliminate all the whitespace..its also possible that other images that i have may contain text right above each picture that would say 300x200 etc... i want to avoid that text too and not crop it
https://ibb.co/dBPxPLQ
- fmw42
- Posts: 25562
- Joined: 2007-07-02T17:14:51-07:00
- Authentication code: 1152
- Location: Sunnyvale, California, USA
Re: Detecting multiple images in one image file
See my bash unix shell script that uses ImageMagick called multicrop2 at my link below. It runs on Mac OSX, Linux and Windows Unix.
Input:
Input:
Code: Select all
multicrop2 -f 25 -b white -d 1000 -u 3 crop-me.jpg result.png
Re: Detecting multiple images in one image file
hey thank you chief but i am not looking for a paid solution at the moment.
i am looking to learn how to solve this technical issue as a programmer and how i would go about it.
would anyone know how to best do that using this or what are some generic steps i have to take to achieve my goal?
thanks guys!
i am looking to learn how to solve this technical issue as a programmer and how i would go about it.
would anyone know how to best do that using this or what are some generic steps i have to take to achieve my goal?
thanks guys!
-
- Posts: 12159
- Joined: 2010-01-23T23:01:33-07:00
- Authentication code: 1151
- Location: England, UK
Re: Detecting multiple images in one image file
In Subimage rectangles I describe two methods of segmentation: (1) by guillotine (finding where to "cut" the main image into horizontal or vertical segments) and (2) by connected-components.
snibgo's IM pages: im.snibgo.com
- fmw42
- Posts: 25562
- Joined: 2007-07-02T17:14:51-07:00
- Authentication code: 1152
- Location: Sunnyvale, California, USA
Re: Detecting multiple images in one image file
Threshold your image to get black rectangles on white background. Then use -connected-components to get the bounding boxes of the black rectangles. Then use this to crop your input image.
Re: Detecting multiple images in one image file
Hey, would you be able to give an example how i would threshold an image and perform these steps using imagicmagick. I'm new to it and don't know.. Would it require creating a layer and then masking and applying the layer.
- fmw42
- Posts: 25562
- Joined: 2007-07-02T17:14:51-07:00
- Authentication code: 1152
- Location: Sunnyvale, California, USA
Re: Detecting multiple images in one image file
Do a fuzzy flood fill at some pixel that is the background. See -fuzz XX% -draw "alpha x,y floodfill" at https://imagemagick.org/Usage/draw/#matte (alpha replaces matte in IM 7). Use as small a fuzz value as you can. For JPG images, the compression makes the background uneven. I have found values for fuzz of about 15% usually works. If the background less uniform, increase it. If you know your background is perfectly uniform, then you can go down to 0%. Note that if any interior image's color around its boundary is close to the background color, then you might get a bounding box smaller than your interior image, if too large a fuzz value is used.
Then do connected components and extract the bounding boxes for each white area representing the images. See https://imagemagick.org/script/connected-components.php. Use the various defines for area-threshold=XXX, verbose=true and mean-color=true to remove small objects that might be from the background and to get the data you need.
Then extract each bounding box and use that to crop your image, one bounding box at a time in a script loop.
Then do connected components and extract the bounding boxes for each white area representing the images. See https://imagemagick.org/script/connected-components.php. Use the various defines for area-threshold=XXX, verbose=true and mean-color=true to remove small objects that might be from the background and to get the data you need.
Then extract each bounding box and use that to crop your image, one bounding box at a time in a script loop.
Re: Detecting multiple images in one image file
fmw42 wrote: ↑2019-10-01T19:36:42-07:00 Do a fuzzy flood fill at some pixel that is the background. See -fuzz XX% -draw "alpha x,y floodfill" at https://imagemagick.org/Usage/draw/#matte (alpha replaces matte in IM 7). Use as small a fuzz value as you can. For JPG images, the compression makes the background uneven. I have found values for fuzz of about 15% usually works. If the background less uniform, increase it. If you know your background is perfectly uniform, then you can go down to 0%. Note that if any interior image's color around its boundary is close to the background color, then you might get a bounding box smaller than your interior image, if too large a fuzz value is used.
Then do connected components and extract the bounding boxes for each white area representing the images. See https://imagemagick.org/script/connected-components.php. Use the various defines for area-threshold=XXX, verbose=true and mean-color=true to remove small objects that might be from the background and to get the data you need.
Then extract each bounding box and use that to crop your image, one bounding box at a time in a script loop.
yeah fmw42 so i did a fuzzy flood fill and you were right.
The Fuzzy flood fill leaked into the picture. The background color matched with colors on the edges of some of the pictures. im wondering if theres some sort of other command option that can recognize the squares, close the square and remove the leaked in fill.
heres a picture of the results. Once again. thank you immensely for helping me with this.. this is super cool stuff i didnt know imagemagick was this powerful and that you could do so much via the commandline like this.
https://ibb.co/wgxV9qg
- fmw42
- Posts: 25562
- Joined: 2007-07-02T17:14:51-07:00
- Authentication code: 1152
- Location: Sunnyvale, California, USA
Re: Detecting multiple images in one image file
You should do your fuzzy flood fill. Then use connected components to find each region. Then get the bounding boxes from the the connected components. Then use the bounding boxes to crop out each image from the original, not the flood filled images.
If I misunderstand your question, please elaborate.
If I misunderstand your question, please elaborate.
Re: Detecting multiple images in one image file
after doing the fuzzy fill the images are not covered in white so when i tried to use -connected-components -depth 8 or -depth 20 i get an error saying too many objects.. im guessing cause i have to transform to the boxes/images to white . .. im still trying to find that technique.
you said "Then do connected components and extract the bounding boxes for each white area representing the images" but i dont know the technique to transform the images now to white...i only transformed white background to black
you said "Then do connected components and extract the bounding boxes for each white area representing the images" but i dont know the technique to transform the images now to white...i only transformed white background to black
- fmw42
- Posts: 25562
- Joined: 2007-07-02T17:14:51-07:00
- Authentication code: 1152
- Location: Sunnyvale, California, USA
Re: Detecting multiple images in one image file
Using your posted image, try this:
You should now have a black image with white regions mostly rectangles with some "eaten" partially away. But the bounding boxes will still be rectangles.
If the fuzz value is too low or you have a noisy background, then you will get other small regions. That is why you must use some area-threshold smaller than the estimated area of the smallest pictures in the connected components to remove these regions so you do not get that message.
Code: Select all
convert crop-me.jpg -fuzz 5% -fill none -draw "matte 0,0 floodfill" -background black -alpha background -fill white +opaque none -alpha off crop_me_floodfill.png
You should now have a black image with white regions mostly rectangles with some "eaten" partially away. But the bounding boxes will still be rectangles.
If the fuzz value is too low or you have a noisy background, then you will get other small regions. That is why you must use some area-threshold smaller than the estimated area of the smallest pictures in the connected components to remove these regions so you do not get that message.
Re: Detecting multiple images in one image file
okay awesome, your one liner is great. im going to use that one instead but below is how i did it:
so i did it one by one since i dont know how to combine all commands just yet
// flood fill an image with fuzz (fuzz to blend more pixels in and out of selection)
convert chopped_off_top.jpg -fuzz 10% -draw "alpha 1,10 floodfill" flood-filled.jpg
// Create a threshold of crop_
convert flood-filled -threshold 6% threshold.jpg
// copy the threshold imaged (black and white image) to the alpha channel of crop_me.jpg
convert crop_me.jpg threshold.jpg -alpha Off -compose CopyOpacity -composite hopeful.png
i was able to successfully copy/combine the mask to the alpha channel of the original file.
now what i have to learn is how to create a bounding rectangle box and fill in those rectangles with white...
i tried to use the connected components method using the document you sent me https://imagemagick.org/script/connected-components.php
but i get so many objects back
convert threshold.jpg -connected-components 4 -auto-level -depth 8 segmented.jpg
convert segmented.jpg -define connected-components:verbose=true -connected-components 4 componented.jpg
so i still have to figure out how to do it properly.. you said
That is why you must use some area-threshold smaller than the estimated area of the smallest pictures in the connected components to remove these regions so you do not get that message.
so im going to mess around with the area-threshold in connect-components to see what i get.
the other thing i have to figure out is the next steps.. I'm not sure if i first have to use connect-components to separate the areas where the images live, create a bounding box and then fill it with white ... or create a bounding box first around each image area, separate using connect-components and then fill in..
im also not sure how to create a rectanagle bounding box so thats what i have to figure out next too
hey thanks for help man. this is coming along great! thank you
so i did it one by one since i dont know how to combine all commands just yet
// flood fill an image with fuzz (fuzz to blend more pixels in and out of selection)
convert chopped_off_top.jpg -fuzz 10% -draw "alpha 1,10 floodfill" flood-filled.jpg
// Create a threshold of crop_
convert flood-filled -threshold 6% threshold.jpg
// copy the threshold imaged (black and white image) to the alpha channel of crop_me.jpg
convert crop_me.jpg threshold.jpg -alpha Off -compose CopyOpacity -composite hopeful.png
i was able to successfully copy/combine the mask to the alpha channel of the original file.
now what i have to learn is how to create a bounding rectangle box and fill in those rectangles with white...
i tried to use the connected components method using the document you sent me https://imagemagick.org/script/connected-components.php
but i get so many objects back
convert threshold.jpg -connected-components 4 -auto-level -depth 8 segmented.jpg
convert segmented.jpg -define connected-components:verbose=true -connected-components 4 componented.jpg
so i still have to figure out how to do it properly.. you said
That is why you must use some area-threshold smaller than the estimated area of the smallest pictures in the connected components to remove these regions so you do not get that message.
so im going to mess around with the area-threshold in connect-components to see what i get.
the other thing i have to figure out is the next steps.. I'm not sure if i first have to use connect-components to separate the areas where the images live, create a bounding box and then fill it with white ... or create a bounding box first around each image area, separate using connect-components and then fill in..
im also not sure how to create a rectanagle bounding box so thats what i have to figure out next too
hey thanks for help man. this is coming along great! thank you