square patterns generation
square patterns generation
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!
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!
-
- Posts: 12159
- Joined: 2010-01-23T23:01:33-07:00
- Authentication code: 1151
- Location: England, UK
Re: square patterns generation
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.
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.
snibgo's IM pages: im.snibgo.com
Re: square patterns generation
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?
-
- Posts: 12159
- Joined: 2010-01-23T23:01:33-07:00
- Authentication code: 1151
- Location: England, UK
Re: square patterns generation
Then what problem are you trying to solve?jhz wrote:I am not able to control the position of the squares.
snibgo's IM pages: im.snibgo.com
Re: square patterns generation
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.
- fmw42
- Posts: 25562
- Joined: 2007-07-02T17:14:51-07:00
- Authentication code: 1152
- Location: Sunnyvale, California, USA
Re: square patterns generation
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.
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
Thank you both of you. It helped me.
- fmw42
- Posts: 25562
- Joined: 2007-07-02T17:14:51-07:00
- Authentication code: 1152
- Location: Sunnyvale, California, USA
Re: square patterns generation
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
Re: square patterns generation
Thank you very much. It is what I was looking for but I was unable to code the program. It is much appreciated.
- fmw42
- Posts: 25562
- Joined: 2007-07-02T17:14:51-07:00
- Authentication code: 1152
- Location: Sunnyvale, California, USA
Re: square patterns generation
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.jhz wrote:... but I was unable to code the program.
Re: square patterns generation
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
- fmw42
- Posts: 25562
- Joined: 2007-07-02T17:14:51-07:00
- Authentication code: 1152
- Location: Sunnyvale, California, USA
Re: square patterns generation
With your code are you able to avoid overlaps of the black squares?
Re: square patterns generation
No and it was the problem I was facing. Your code helped me to avoid the overlaps and thank you for your help.
- GeeMack
- Posts: 718
- Joined: 2015-12-01T22:09:46-07:00
- Authentication code: 1151
- Location: Central Illinois, USA
Re: square patterns generation
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...fmw42 wrote:Create a white tile of desired size [...] Then montage all the tiles together.
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
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.