Page 1 of 1

cutting picture and resamble the pieces

Posted: 2010-07-28T09:50:25-07:00
by h.nietnagel
Hello,

I would like to cut pictures into pieces and then assemble the pieces randomly into a new picture with the same size and dimension of the original picture. Unfortunately, I could not find an appropriate command.
So I tried to use

Code: Select all

convert testorig.png -crop 25% test_%d.png 
and tried to write a shell script for assembling the pieces which is pretty harsh since it has to be taken care of that no piece will be used more than once and I would also like to rotate the pieces every now and then.

Code: Select all

convert \( test_0.png test_2.png test_4.png test_6.png +append \)  \( test_1.png test_3.png test_5.png test_7.png +append \) \( test_8.png test_10.png test_12.png test_14.png  +append \) \( test_9.png test_11.png test_13.png test_15.png +append \) -append testf2.png
But I am pretty sure that ImageMagick already provides a command to do this job.

Does anyone have a hint for me?

Thank you very much in advance!


Hannes

Re: cutting picture and resamble the pieces

Posted: 2010-07-28T10:29:01-07:00
by fmw42
IM will not automatically reassemble your images into arrangements other than its original, as far as I know.

The -crop operator without adding +repage will keep the offsets in the virtual canvas (page geometry) of each piece. Thus simply by listing the cropped images, you can reassemble them back to their original order.

A typical way to reassemble them in other orders is to use -page ... -flatten, where you tell -page the location you want each cropped piece to be placed.

See http://www.imagemagick.org/Usage/crop/#crop and http://www.imagemagick.org/Usage/layers/#flatten

Your append is another method if all pieces are the same size.

Re: cutting picture and resamble the pieces

Posted: 2010-07-28T19:16:51-07:00
by anthony
For odd shapes, you generally use a shape mask image of the cut. You can then use the IM compose methods Dst-IN abnd Dst-Out to extract the two parts of the mask.

The two parts are designed specifically so that adding the two images together (using Plus compose) will return the image to its original form.

See IM Examples Image Composition, Dst-In
http://www.imagemagick.org/Usage/compose/#dstin
This continues into Dst-Out for the other part, and re-joining.

Also see Alpha Channel Handling for converting grey-scale masks into shape maskes
and visa versa.
http://www.imagemagick.org/Usage/basics/#alpha_extract

I only have raw notes on handling and aligning image parts. But hope to add more in the future
http://www.imagemagick.org/Usage/channels/#aligning
The key is to use the SAME MASK for extracting both halves of the image.
I hope to use some jigsaw templates from another example, for demonstrating this.
http://www.imagemagick.org/Usage/advanced/#jigsaw

You can use 'Over' to overlay one mask image (from one image) over the complete image (a different one) will also result in the correct mask handling.

You need to be careful with Over as merging the two masked images with 'Over' will probably leave a slightly transparent edge along the join. That is Over is only truely useful with 'parts' of images when one of the parts is a complete image and not a 'part' image.

This is a problem that is also seen in examples in
3d Cubes - Affine
http://www.imagemagick.org/Usage/distorts/#cube3d
and again in
3d Boxes - Prespective
http://www.imagemagick.org/Usage/distorts/#box3d
and in Isometric Cube using Shears
http://www.imagemagick.org/Usage/warping/#sheared_cube

These examples have the problem in that the parts were NOT generated using the same mask!

Re: cutting picture and resamble the pieces

Posted: 2010-08-03T01:31:26-07:00
by h.nietnagel
Hi,

thanks for the detailed reply. I found another way:

Code: Select all

#!/bin/bash

declare dir=Reassembled
if [ ! -d $dir ]; then
mkdir $dir; fi

declare -a eqORgt
eqORgt=("-eq" "-gt");

for k in *.tif; do
		
op=$(($RANDOM % ${#eqORgt[@]}))
noEntries=25
count=0
numbers=()
files=()

# crop the interesting part
convert $k -crop 42%x86%+260+80 ${k%.*}_crop.jpg
# resize
convert $ECHO "${k%.*}_crop.jpg" -resize 35x50 rf${k%.*}.jpg
# cut into pieces
convert $ECHO "rf${k%.*}.jpg" -crop 20% %d_mask.jpg
 
while [ $count -lt $noEntries ]; do
        random=$(($RANDOM % $noEntries))

        case " ${numbers[@]} " in *" ${random} "*) continue ;; esac

        numbers[$count]=${random}
        files[$count]=${random}_mask.jpg

		let Even=$random%2
		if [ $Even ${eqORgt[op]} 0 ] ; then
		convert -rotate 180 $ECHO "${files[$count]}" $ECHO "${files[$count]}"; fi
				
		let count++		
done

echo NUMBERS: ${numbers[@]}
echo FILES: ${files[@]}

# reassemble the pieces
convert \( $ECHO "${files[0]}" $ECHO "${files[1]}" $ECHO "${files[2]}" $ECHO "${files[3]}" $ECHO "${files[4]}" +append \) \( $ECHO "${files[5]}" $ECHO "${files[6]}" $ECHO "${files[7]}" $ECHO "${files[8]}" $ECHO "${files[9]}" +append \) \( $ECHO "${files[10]}" $ECHO "${files[11]}" $ECHO "${files[12]}" $ECHO "${files[13]}" $ECHO "${files[14]}" +append \) \( $ECHO "${files[15]}" $ECHO "${files[16]}" $ECHO "${files[17]}" $ECHO "${files[18]}" $ECHO "${files[19]}" +append \) \( $ECHO "${files[20]}" $ECHO "${files[21]}" $ECHO "${files[22]}" $ECHO "${files[23]}" $ECHO "${files[24]}" +append \) -append rf${k%.*}_mask.jpg 

# create a gray background
convert $ECHO "rf${k%.*}_mask.jpg" -background 'rgb(170,170,170)' -gravity center -extent 800x600 rf${k%.*}_mask.png
convert $ECHO "rf${k%.*}.jpg" -background 'rgb(170,170,170)' -gravity center -extent 800x600 rf${k%.*}.png

# clear the mess
rm $ECHO ${files[@]}
rm $ECHO "rf${k%.*}_mask.jpg"
rm $ECHO "rf${k%.*}.jpg"
mv $ECHO "rf${k%.*}_mask.png" $ECHO ${dir}/.
mv $ECHO "rf${k%.*}.png" $ECHO ${dir}/.
done

It's surely not the most elegant way, but it works for me.

There is only one thing left:
the pictures are actually displaying faces. Unfortunately, the faces are not on all the pictures centered, and they also differ slightly in size.
So with my command:

Code: Select all

# crop the interesting part
convert $k -crop 42%x86%+260+80 ${k%.*}_crop.jpg
I do not obtain always the face centered. All the pictures should have the same size in the end. But I need to crop from each picture a slightly different part.
How can I do this?
My idea was to create a black and white mask of each picture and then cut from each picture the part where the black (= background) starts.
But since I am not so familiar with ImageMagick, I did not find the right way to do that.
Any hint is most appreciated!

Thank you very much in advance!

Hannes

Re: cutting picture and resamble the pieces

Posted: 2010-08-03T09:34:05-07:00
by fmw42
You can automatically crop your mask to the bounds of the black using -trim. If you do that (and don't add +repage), then identify -verbose imagename will give you the new image size and crop offsets in the page geometry field. You can script that to crop your image correspondingly.

see -trim
http://www.imagemagick.org/script/comma ... s.php#trim
http://www.imagemagick.org/Usage/crop/#trim

If your face image is the face surrounded by some near constant color, then you can just use -fuzz XX% -trim +repage on that image. If you need all images the same size and trim makes it too small, then you can add -backround somecolor -extent WxH

see

http://www.imagemagick.org/Usage/crop/#extent


Can you provide a link to an example image that you need to crop?

Re: cutting picture and resamble the pieces

Posted: 2010-08-04T17:23:57-07:00
by h.nietnagel
Hi,
fmw42 wrote: Can you provide a link to an example image that you need to crop?
Unfortunately, not. That are pictures from a non public database and restricted to solely scientific usage. But I found something that could give an impression of what I am talking about:
http://www.redbox.de/news/_data/zoom_Fa ... es_New.jpg

Imagine, these faces were all black and white and one picture consists of one face and they all share the same solid gray background that extends the canvas to a size of approximately 800 x 600 pixels. Oh: take into account only the faces looking directly frontally at you. Not the ones where the head is turned to one side.

However, I will try what you adviced using -trim or maybe even -fuzz could already work.
Or do you have another idea?

Thank you very much!

Hannes

Re: cutting picture and resamble the pieces

Posted: 2010-08-04T17:32:41-07:00
by fmw42
If the background is relatively constant color, then

convert image -fuzz XX% -trim +repage -background gray -extent WxH result

should do. the -fuzz XX% allows the trim to remove colors that are nearly constant. The larger the XX% the more tolerant it will be. I used -background gray, but you should use whatever grayshade is the existing background in your image. The -extent will pad it out to be some fixed size WxH that you supply in case the trim makes the image smaller than desired. If larger, then you will need to crop or resize. The latter is probably better as you won't cut off any of the face


convert image -fuzz XX% -trim +repage -resize "WxH>" -background white -extent WxH result

The > symbol tells resize only to work if the image is larger than WxH. The quotes are important; otherwise you may need to escape the > symbol.