Page 1 of 1

square patterns generation

Posted: 2016-10-24T23:21:43-07:00
by jhz
Hi Everybody,

Sorry for my bad english.
I am trying to generate a random(size, position and rotation) square pattern on a white image. I tried with ImageMagick and succeeded to get image in the link https://drive.google.com/open?id=0BypRK ... XJDYl9xT3c. I am pasting black squares onto a white image randomly using Linux bash script but the problem is some of the squares are overlying onto other and making cluster of squares(as can see in the image). I want them to paste only in empty spaces and not on each other. I want random space filling of the background image with squares.
Any hint to solve my problem.

P.S: I don't know whether I am posting at the right forum, if not then I am sorry!

Re: square patterns generation

Posted: 2016-10-24T23:29:15-07:00
by snibgo
You could do this with trial and error.

Make a copy of the image. Add a NxN square. You hope that NxN pixels have turned from white to black. If they have, then that's fine. Otherwise, forget about this copy.

Repeat for as long as you want.


How do you count the number of white pixels? The mean of the image is the proportion that are white. Multiply this by height and width, and that's the number of white pixels. This might be: "%[fx:mean*w*h]". The squares are rotated, so the numbers won't be exact.

Re: square patterns generation

Posted: 2016-10-25T00:31:57-07:00
by jhz
I am sorry to say that I am not a good programmer. Actually I created a background image of 1280x720px and I let the squares to decide where they will paste in the given boundary i.e background image size. I am not able to control the position of the squares. I am looking for a simple method to do this and I was thinking that it would be easier in ImageMagick. Can we do this using overlay=false parameter?

Re: square patterns generation

Posted: 2016-10-25T00:39:31-07:00
by snibgo
jhz wrote:I am not able to control the position of the squares.
Then what problem are you trying to solve?

Re: square patterns generation

Posted: 2016-10-25T00:45:50-07:00
by jhz
I want to paste the squares in empty spaces but by the way I am using they are pasting on each other as well as on empty spaces. I just want to copy them in empty spaces. I can also share my script if you want to have look on it.

Re: square patterns generation

Posted: 2016-10-25T00:55:30-07:00
by fmw42
Create a white tile of desired size (multiplied by sqrt(2) to account for 45 deg rotation). For each possible total number of these tiles that will fill out N rows and M columns, get a random number. Also threshold the random number to 0 and 1. Also get a random angle and a random size (in range 0 to 1).

If the thresholded random number is 0, then just use the white tile.

If the thresholded random number is 0, then just inscribe a black square of desired size (not multiplied by sqrt(2)), rotated by the random angle and scaled by the random factor into the center using -distort srt and compose over -composite

Then montage all the tiles together.

Re: square patterns generation

Posted: 2016-10-25T01:26:23-07:00
by jhz
Thank you both of you. It helped me.

Re: square patterns generation

Posted: 2016-10-25T01:49:37-07:00
by fmw42
Here is one way. It is a bit slow due to the use -fx to compute the random values.

Code: Select all

dim			# tile size
ww				# image width (should be multiple of tile size, but image will be cropped to make it a multiple)
hh				# image height (should be multiple of tile size, but image will be cropped to make it a multiple)
mindim			# percent of full tile size (limits smallest black square)
binthresh			# binary threshold fraction between 0 and 1 (larger means more black squares)
				# (binthresh is the fraction of tiles that will be black)

Code: Select all

dim=32
ww=512
hh=512
mindim=25
binthresh=0.50
ww=`convert xc: -format "%[fx:$dim*floor($ww/$dim)]" info:`
hh=`convert xc: -format "%[fx:$dim*floor($hh/$dim)]" info:`
numw=$((ww/dim))
numh=$((hh/dim))
num=$((numw*numh))
echo "numw=$numw; numh=$numh; num=$num;"
# use 1.5 rather than sqrt(2) to ensure no overlap
www=`convert xc: -format "%[fx:$ww/1.5]" info:`
hhh=`convert xc: -format "%[fx:$hh/1.5]" info:`
(
for ((i=0; i<num; i++)); do
binary=`convert xc: -format "%[fx:(random()<$binthresh)?1:0]" info:`
angle=`convert xc: -format "%[fx:random()*90]" info:`
fraction=`convert xc: -format "%[fx:max($mindim,100*random())]" info:`
echo >&2 "$i; $binary; $angle; $fraction;"
if [ $binary -eq 1 ]; then
convert -size ${www}x${hhh} xc:black -scale $fraction% -background white -rotate $angle +repage -scene 0 miff:-
else
convert -size ${www}x${hhh} xc:white +repage -scene 0 miff:-
fi
done
) |\
montage - -tile ${numw}x${numh} -geometry +0+0 random_squares.jpg
Image

Re: square patterns generation

Posted: 2016-10-25T03:51:00-07:00
by jhz
Thank you very much. It is what I was looking for but I was unable to code the program. It is much appreciated.

Re: square patterns generation

Posted: 2016-10-25T09:04:01-07:00
by fmw42
jhz wrote:... but I was unable to code the program.
What do you mean by that? Are you on Unix or Windows? The code is for Unix. I do not know how to convert that to Windows scripting.

Re: square patterns generation

Posted: 2016-10-25T19:43:03-07:00
by jhz
Yes I am using Unix and this code worked for me. I meant by that I understood the logic but I couldn't code the program. Below is my code that I wrote for random square patterns using very basic techniques.

Code: Select all

#!/bin/bash

# PX	position of squares on X-axis
# PY	position of squares on Y-axis
# ROT	rotation angle of squres

# generating background image of size 1280x720
convert -size 1260x720 canvas:white  bg.jpg

# generating 100 squares of random size in between 20x20 px
for (( count=1; count <= 100; count++ ))
do

X=$((RANDOM%20+20))
convert -size "$X"x"$X" canvas:black  square.jpg

# copying squares on background image

PX=$((RANDOM%1260+1))
PY=$((RANDOM%720+1))

ROT=$((RANDOM%90+0))

convert \( bg.jpg \) \( square.jpg -background none -rotate "$ROT" \)  -geometry +"$PX"+"$PY" -composite bg.jpg


done

Re: square patterns generation

Posted: 2016-10-25T20:20:27-07:00
by fmw42
With your code are you able to avoid overlaps of the black squares?

Re: square patterns generation

Posted: 2016-10-25T20:33:48-07:00
by jhz
No and it was the problem I was facing. Your code helped me to avoid the overlaps and thank you for your help.

Re: square patterns generation

Posted: 2016-10-27T05:53:58-07:00
by GeeMack
fmw42 wrote:Create a white tile of desired size [...] Then montage all the tiles together.
Just to add in another way of looking at this, and following from the first idea offered by fmw42 above: Using IM7 on Windows I can generate a pseudo random arrangement of black squares on a white background with this single command...

Code: Select all

magick -background white -bordercolor white -gravity northwest xc:black -duplicate 99 ^
   -resize %[fx:rand()*72+24] -rotate %[fx:rand()*360] -border 6x6 -splice 36x36 ^
   -rotate %[fx:floor(rand()*4)*90] -resize 144x144! +append -crop 10x1@ +repage ^
   -roll +%[fx:(t%2)*72]+0 -append -resize 720x720 squares.png
That makes 100 black squares, resizes them to random sizes between 24x24 and 96x96, gives them all random rotations, offsets them on their backgrounds with "-splice", resizes them to a uniform dimension, then arranges them into a grid with every other row rolled horizontally by half a unit.

The sizes and rotations are random. The layout grid isn't really random, but it gives the impression of random because of the offsets and rotations. No squares touch and none overlap. Also, it will seamlessly tile!

This could be adapted to *nix shell command pretty easily, but it does require ImageMagick 7.