Extracting sprites/images from a bigger image

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?".
jmspaggi
Posts: 25
Joined: 2020-02-09T15:15:17-07:00
Authentication code: 1152

Extracting sprites/images from a bigger image

Post by jmspaggi »

Hi,

I have a scan of puzzle pieces and I'm trying to extract all the pieces separately. I first tried to put them alligned and then cut verticaly and horizontaly but I realized it's not really realistic :-/ Is there something in ImageMagick which can help me with that? (I will try to put the file here).

The background is white, but it's not necessary 255/255/255.

Thanks,

JMS

jmspaggi
Posts: 25
Joined: 2020-02-09T15:15:17-07:00
Authentication code: 1152

Re: Extracting sprites/images from a bigger image

Post by jmspaggi »

Here is the image (If it works)

Image

https://drive.google.com/file/d/1AKwGhG ... sp=sharing

PS: I saw that post http://www.imagemagick.org/discourse-se ... b2#p154400 but it doesn't seems to be working for me...

jmspaggi
Posts: 25
Joined: 2020-02-09T15:15:17-07:00
Authentication code: 1152

Re: Extracting sprites/images from a bigger image

Post by jmspaggi »

Ha! My bad!!! It was because my background was not transparent...

I found this command in the forum: convert test1.tiff.tif -fuzz 2% -transparent white output.png

And by cleaning my background I can get the steps on the other thread to work :-/

I will post the list of commands and there results here shortly. I'm pretty sure it can be improved ;)

jmspaggi
Posts: 25
Joined: 2020-02-09T15:15:17-07:00
Authentication code: 1152

Re: Extracting sprites/images from a bigger image

Post by jmspaggi »

so here are the 4 steps that I'm following.

1) Change the background:
convert test1.tiff.tif -fuzz 1% -transparent white pieces_with_transparency.png

2) Then add border to all the pieces:
convert pieces_with_transparency.png -bordercolor none -border 1 -background white -alpha background -bordercolor white pieces_with_border.png

3) Then extract all the forms:
convert pieces_with_border.png -alpha off -negate -threshold 0 -type bilevel pieces_white_forms.png

4) And from there extract all the pieces:

Code: Select all

OLD_IFS=$IFS
IFS=$'\n'
arr=(`convert pieces_white_forms.png \
-define connected-components:verbose=true \
-define connected-components:area-threshold=10 \
-define connected-components:mean-color=true \
-connected-components 8 \
null: | tail -n +2 | sed 's/^[ ]*//'`)
IFS=$OLD_IFS
num=${#arr[*]}
for ((i=0; i<num; i++)); do
bbox=`echo "${arr[$i]}" | cut -d\  -f2`
color=`echo "${arr[$i]}" | cut -d\  -f5`
if [ "$color" = "gray(255)" ]; then
convert pieces_with_border.png -crop $bbox +repage -background none -deskew 40% pieces_$i.png
fi
done
This works pretty well. Except that there is some imperfections/dust in the initial picture and I end up with way more pieces that the real one. So now the question is, is there a parameter that I can give to convert to drop areas that are too small? I can definitely modify the script to extract width and height and drop those lower than a threshold but I was wondering if ImageMagic had a threshold parameter for that...

Thanks.

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

Re: Extracting sprites/images from a bigger image

Post by fmw42 »

In you code,

Code: Select all

-define connected-components:area-threshold=10 \
change 10 to be a larger threshold on the area.

See https://imagemagick.org/script/connected-components.php

jmspaggi
Posts: 25
Joined: 2020-02-09T15:15:17-07:00
Authentication code: 1152

Re: Extracting sprites/images from a bigger image

Post by jmspaggi »

Ha, thanks. It seems to work.

Now, something related. If I scan with the scanner open, I get a black background. However, it's not 100% black, it's black with some dust here and there. When I try to replace "white" by "black" in the first commands, it doesn't work. Same when the white is not 100% white but has some small defects here and there.

Is there a way to make all the white being really white and all the black being really black, but only on sections that are very black or very white? Like, I don't want to affect the pieces pictures.

I can provide files as examples again. I just don't know how easily add the pictures on the message :-/

Thanks.

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

Re: Extracting sprites/images from a bigger image

Post by fmw42 »

Use

Code: Select all

-fuzz XX% -fill black -opaque black -fill white -opaque white
Just after reading in the input image and before anything to do with connected components. Adjust the XX%. 0% means an exact match when finding white or black. So try typically 15% or 20%.

See

https://imagemagick.org/script/command- ... s.php#fuzz
https://imagemagick.org/script/command- ... php#opaque
https://imagemagick.org/Usage/color_basics/#fuzz

jmspaggi
Posts: 25
Joined: 2020-02-09T15:15:17-07:00
Authentication code: 1152

Re: Extracting sprites/images from a bigger image

Post by jmspaggi »

Thanks again for your guidance.

The "issue" with this approach is that it "eats" some of the pieces :(

The image before trying to clear the black background:
Image

The image after:
Image

The command:

Code: Select all

convert input_black_01.tif -fuzz 30% -fill white -opaque white -fill black -opaque black test.tif
And even wit 30% there is still some pixels in the black on the left of the picture. When I scan with the white background, I get a similar issue but with the clear pieces.

I saw one of your other posts where it suggest to use despeckle. So I tried. With those commands:

Code: Select all

convert input_black_01.tif  -despeckle -despeckle -despeckle -despeckle -despeckle -despeckle -despeckle -despeckle -despeckle -despeckle -despeckle result_preview_lat.tif
convert input_black_01.tif -fuzz 30% -fill white -opaque white -fill black -opaque black test.tif
convert pieces_with_transparency.png -bordercolor none -border 1 -background white -alpha background -bordercolor white pieces_with_border.png
convert pieces_with_border.png -alpha off -negate -threshold 0 -type bilevel pieces_white_forms.png
And it gives me this:
Image
Which is not that bad. But the issue is that there is still some small almost black pixels here and there that I would like to remove (On the left of the top connection). I'm loosing a bit of the picture derails, but I think that for my usecase it will be acceptable. The best will have been to get all the pieces without loosing any quality, but seems that the background will definitely be a challenge.

Here are my 2 input files for reference.
White background
Black background

Thanks again for your support.

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

Re: Extracting sprites/images from a bigger image

Post by fmw42 »

I do not understand. What black pixels are left? Any isolated small black spots will be removed by the connected components area threshold. Did you increase the area-threshold value? Please identify where there are spots you need to remove.

jmspaggi
Posts: 25
Joined: 2020-02-09T15:15:17-07:00
Authentication code: 1152

Re: Extracting sprites/images from a bigger image

Post by jmspaggi »

Image

Here. You see the small black dot? You need to click on the pictures and zoom to see them. That'S the remaining black dots I get when i use the despeckle approach

Below are the small color dots I get in the black when I use the -fill -opaque approach.The dots are on the left of the picture, close to the border, almost in the middle.


Image

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

Re: Extracting sprites/images from a bigger image

Post by fmw42 »

Post a link to your full image and I will try to see what is happening.

jmspaggi
Posts: 25
Joined: 2020-02-09T15:15:17-07:00
Authentication code: 1152

Re: Extracting sprites/images from a bigger image

Post by jmspaggi »

Here are 2 examples of files.

Black background 01
Black background 02

I can also make them with a white background if it's better, but here again, the white is not always 100% white :-/
White background 01
White background 02

The white pattern is a bit more easy to scan, but I had more trouble isolating the pieces. The black schema i more difficult to scan, because of the dust, but I got better results at the end...

Thanks.

snibgo
Posts: 12863
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Extracting sprites/images from a bigger image

Post by snibgo »

For the dust, I suggest you brush the glass of your scanner, and perhaps clean it.

Isolating a background is easier if it is a different colour to the foreground. For example, place a sheet of red paper over the jigsaw pieces before scanning.
snibgo's IM pages: im.snibgo.com

jmspaggi
Posts: 25
Joined: 2020-02-09T15:15:17-07:00
Authentication code: 1152

Re: Extracting sprites/images from a bigger image

Post by jmspaggi »

I thought about that, but issue is pieces can be any color. There are red pieces, black one, blue one, etc. I will definitely clean the glass for the next set of test pictures. I will remove some white dots, but will not make the black become real black :-/ The black is when I scan at night and I keep the cover open. The white is when I close the cover. So the white can probably be more consistent.

Except the little leftover black dots, the option with despeckle is not that bad...

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

Re: Extracting sprites/images from a bigger image

Post by fmw42 »

You have a very hard problem, since some of your puzzle pieced have nearly white regions on a nearly white background. I did the following using a fuzz value of 1.5%. If I go lower to 1%, then the image will have a vertical line between the first and second columns of pieces. But either one show a little of the second row, last column piece is slightly "eaten away" on its edge.

Code: Select all

convert input_white_01.tif \
-bordercolor white -border 1 \
-fuzz 1% -fill white -draw "color 0,0 floodfill" -alpha off \
-fill black +opaque white \
input_white_01_binary_1.gif
Image

From this image, you can use connected components (with area-threshold large enough to get rid of the small dust spots) to get the bounding boxes and crop the pieces from the input image. Or you can crop both images and use the binary one as a mask. You can process the masks with morphology open to try to fill out the edges better. And you can use -blur 0x1 or 0x2 and -level 50x100% to antialias the edges to smooth them out to make the background transparent.

The following code (adding morphology) seems to clean the edges of your puzzles and remove the small speck. But it rounds the corners a bit. You need to zoom in at full resolution to do the comparing of the two images.

Code: Select all

convert input_white_01.tif \
-bordercolor white -border 1 \
-fuzz 1.5% -fill white -draw "color 0,0 floodfill" -alpha off \
-fill black +opaque white \
-morphology close disk:15 \
input_white_01_binary2.gif
Image

Post Reply