2

I have big image https://buildyourboard.pro/userboards/board-img/data/clipart.png

how can I segmentate this image to small images by transparent (or another) background?

Images not in grid, so code should find position of every pic in image

KoIIIeY
  • 533
  • 1
  • 7
  • 26
  • 1
    This question has already been asked and answered here: http://stackoverflow.com/questions/26271757/imagemagick-cropping-large-image-into-xyz-tiles?rq=1 – Erick G. Hagstrom Nov 10 '15 at 18:54
  • 2
    @ErickG.Hagstrom Actually that question is different and simpler. The elements in this question's image are not on a regular grid - they do not align vertically above and below each other so the answer is considerably more involved - I think. – Mark Setchell Nov 10 '15 at 19:49

1 Answers1

3

If you run this command, it will scrunch all the pixels up into an image that is just one pixel wide and has the original height of your image. You will then see that all lines that have the word none correspond to all the locations where you can draw a horizontal line across the image without intersecting with any of your board backgrounds:

convert boards.png -resize 1x! txt: | more
# ImageMagick pixel enumeration: 1,4667,255,srgba
0,0: (0,0,0,0)  #00000000  none
0,1: (0,0,0,0)  #00000000  none
0,2: (0,0,0,0)  #00000000  none
...
...
...
0,547: (0,0,0,0)  #00000000  none
0,548: (0,0,0,0)  #00000000  none
0,549: (0,0,0,0)  #00000000  none
0,550: (0,0,0,0)  #00000000  none
0,551: (0,0,0,0)  #00000000  none
0,552: (0,0,0,0)  #00000000  none
0,553: (0,0,0,0)  #00000000  none
0,554: (0,0,0,0)  #00000000  none
0,555: (39038,36633,35446,0)  #988F8A00  srgba(152,143,138,0)
0,556: (38889,36248,34984,12)  #978D8800  srgba(151,141,136,0.000183108)
0,557: (38348,35253,33873,75)  #95898400  srgba(149,137,132,0.00114443)
0,558: (35061,31775,30664,98)  #887C7700  srgba(136,124,119,0.00149538)
0,559: (33894,30508,29428,164)  #84777301  srgba(132,119,115,0.00250248)
0,560: (34379,30968,29853,243)  #86787401  srgba(134,120,116,0.00370794)

Now you can see that the first place where it goes from there being nothing in a horizontal line to there being something is at line 555. So basically, you want to detect where it changes from none to something.

That is readily done through awk like this:

convert boards.png -resize 1x! txt: | awk 'inside && /none/{inside=0;print;next} !inside && ! /none/{inside=1;print}'
# ImageMagick pixel enumeration: 1,4667,255,srgba
0,0: (0,0,0,0)  #00000000  none
0,555: (39038,36633,35446,0)  #988F8A00  srgba(152,143,138,0)
0,911: (0,0,0,0)  #00000000  none
0,1082: (36701,34188,35001,0)  #8F858800  srgba(143,133,136,0)
0,1433: (0,0,0,0)  #00000000  none
0,1570: (33489,32153,32838,4)  #827D8000  srgba(130,125,128,6.10361e-05)
0,1937: (0,0,0,0)  #00000000  none
0,2135: (29884,28945,29339,4)  #74717200  srgba(116,113,114,6.10361e-05)
0,2486: (0,0,0,0)  #00000000  none
0,2621: (28668,27300,25241,5)  #706A6200  srgba(112,106,98,7.62951e-05)
0,2972: (0,0,0,0)  #00000000  none
0,3216: (35066,32529,28581,2)  #887F6F00  srgba(136,127,111,3.0518e-05)
0,3612: (0,0,0,0)  #00000000  none

So, now we know we can make horizontal cuts across the picture at lines 555, 911, 1082, 1433 etc.

I will draw the first 3 such lines in like this:

convert boards.png -stroke red -draw "line 0,555 12000,555" -draw "line 0,911 12000,911" -draw "line 0,1082 12000,1082" result.jpg

enter image description here

Now, you cut along those lines - like this:

convert boards.png -crop x911+0+0 row1.jpg

enter image description here

convert boards.png -crop x416+911+1082 row2.jpg

enter image description here

Then apply exactly the same procedure in the vertical direction, replacing -resize 1x! with -resize x1!.

Mark Setchell
  • 191,897
  • 31
  • 273
  • 432