Treasure hunt for edges - imagemagick

I want to make a children's treasure hunt where the next location is given by a picture e.g.
To make a more suitable printable picture, I can use -canny like this:
convert hut.jpg -canny 0x1+10%+30% -negate hutCanny.jpg
To make it more interesting, I was thinking that I want to make two images -one with horizontal lines and one with vertical lines:
convert hut.jpg -colorspace gray -morphology Convolve Sobel -negate hutH.jpg
convert hut.jpg -colorspace gray -morphology Convolve Sobel:90 -negate hutV.jpg
I would like the location to be only guessable when both picture are found and can be combined using a light source. The problem is that Sobel not only detects vertical lines but also angled lines. As can be seen, the location is far too easy to recognise with just one picture. I have been trying with different kernels and trying to erode the pictures. -nothing woks.
How do I make two images that by themselves are not 'guessable' but can be combined to one. e.g. by making one image with only near horizontal lines and an other with only near vertical lines?

You could do something like the following in ImageMagick. Make a random mask and apply it to the image. Then invert the mask and do the same. The two images, when added together, will make the input.
Input:
convert \( hut.png -write mpr:img +delete \) \
\( mpr:img +noise random -channel g -separate +channel -blur 0x5 -threshold 50% +write mpr:mask +delete \) \
\( mpr:img mpr:mask -compose multiply -composite +write hut_out1.png \) \
\( mpr:img \( mpr:mask -negate \) -compose multiply -composite +write hut_out2.png \) \
null:
Output 1:
Output 2:
ADDITION
If it has to be grayscale, then you can do the above and make each output gray.
convert \( hut.png -write mpr:img +delete \) \
\( mpr:img +noise random -channel g -separate +channel -blur 0x5 -threshold 50% +write mpr:mask +delete \) \
\( mpr:img mpr:mask -compose multiply -composite -colorspace gray +write hut_out1.png \) \
\( mpr:img \( mpr:mask -negate \) -compose multiply -composite -colorspace gray +write hut_out2.png \) \
null:
Output 1:
Output 2:
Now add them together to reconstitute:
convert hut_out1.png hut_out2.png -evaluate-sequence add hut_out12.png

Related

Imagemagick: channel gets lighter after separate/combine operation

I'm trying to combine PBR normal/roughness/metallic map images (.png) into a single RGBA image (also .png), with the normal map in the red and green channels, the roughness map in the blue channel, and the metallic map in the alpha channel.
The following bash command line works, but for some reason the green channel is slightly lighter in the composite image than it is in the original normal image (e.g. a value of 0x7e in the original is raised to 0x87 in the composite). All three other channels keep their original values. If I switch the order of the red and green separation, it's the red channel in the final image that gets lighter. What could be causing that, and how do I avoid it?
convert ImageName_Normal.png -colorspace sRGB -write mpr:NORMAL_R -channel R -separate +channel \
-write mpr:NORMAL_G -channel G -separate +channel +delete \
ImageName_Roughness.png -colorspace Gray -flatten -write mpr:ROUGHNESS +delete \
ImageName_Metallic.png -colorspace Gray -flatten -write mpr:METALLIC +delete \
mpr:NORMAL_G mpr:NORMAL_R mpr:ROUGHNESS -combine -write mpr:RGBCOMP +delete \
mpr:RGBCOMP mpr:METALLIC -alpha off -compose Copy_Opacity -composite -depth 8 \
png32:ImageName_NormRoughMetal.png
ImageMagick version is 6.9.11-60
I tried different variations on it - using \( +clone , another copy of the normal map (with and without +delete after the first one), and so on. None of them worked any better (and some actually gave me two copies of the normal map's red channel even though green was specified on the command line for the second one).
I do not think your command is what you want in Imagemagick. I think you are not keeping the first two parts properly separate.
Try this
convert TestImage_Normal.png -colorspace sRGB -write mpr:NORMAL +delete \
\( mpr:normal -channel R -separate +channel -write mpr:NORMAL_R +delete \) \
\( mpr:normal -channel G -separate +channel -write mpr:NORMAL_G +delete \) \
\( TestImage_Roughness.png -colorspace Gray -flatten -write mpr:ROUGHNESS +delete \) \
\( TestImage_Metallic.png -colorspace Gray -flatten -write mpr:METALLIC +delete \) \
\( mpr:NORMAL_G mpr:NORMAL_R mpr:ROUGHNESS -combine -write mpr:RGBCOMP +delete \) \
mpr:RGBCOMP mpr:METALLIC -alpha off -compose Copy_Opacity -composite -depth 8 \
png32:TestImage_NormRoughMetal_fred.png

How to colorize an image with multiply to add transparency to the colour with Image Magick

I would like to colorize an image with two colours, red on the left half and green on the right half but the colorize function just adds a coloured overlay to the image rather than multiplying it on. So I would like my image to look like this but it is currently looking like this. Here is the original image
My code at the moment is this:
convert normal.png \
\( -clone 0 -crop 50x100% -fill red -colorize 60% \) \
\( -clone 0 -crop 50x100%+64 -fill green -colorize 60% \) \
-delete 0 -background none -flatten result.png
I have tried adding -compose multiply -composite to the code but I just get this which has the right effect but I cannot get it to the position that I want, heres the code for that:
convert normal.png \
\( -clone 0 -crop 50x100% -fill red -colorize 70% \) \
\( -clone 0 -crop 50x100%+64 -fill green -colorize 70% \) \
-background none -compose multiply -composite result.png
One simple approach would be to assemble the red-green overlay inside parentheses, then do a multiply composite over the input image.
magick lena_circ.png -size %wx%h \
\( xc:red xc:green +append -scale 50x100% \) \
-compose multiply -channel rgb -composite result.png
That command give me this result...

ImageMagick, set relative size in chain of convert operators

I'd need to set the size relative to the size already set. I'd need it because my flow involves defining primitives inside other ones. Eg
convert -size 200x100 xc:black \( -size 30x40% xc:red \) -gravity West -composite out.png
That 30x40% is not working this way, it becomes pixels 30x40. I can achieve this specific goal in the first example by using resize
convert -size 200x100 xc:black \( xc:red -resize 30x40% \) -gravity West -composite out.png
In this second version, xc:red inherits the size 200x100, so -resize works as expected. Though the size of further/inner primitives are not reduced to 60x40, it remains 200x100, so in the third example, the green rectangle has orientation landscape and not portrait
convert -size 200x150 xc:blue \
\( xc:red -resize 50x100% \
\( xc:green -resize 40% \) \
-gravity Center \
-composite \
\) \
-gravity West \
-composite \
out.png
So green area is 80x60 pixels, 40% of 200x150. I'd like to somehow reset the size to the size of xc:red after resize by the time I'm introducing xc:green.
I think you are trying to create canvases whereby each one is a percentage of the the size of the previous one. There may be an easier way, but you could save each canvas (and implicitly its size) in a MPR "Magick Persistent Register" (named lump of RAM) as you create it, then recall the latest one and overwrite it each time you want to do something relative to that:
convert -gravity west -size 200x100 xc:black -write MPR:S \
\( MPR:S -resize 30x40% -fill red -colorize 100 -write MPR:S \) -composite \
\( MPR:S -resize 50x50% -fill blue -colorize 100 -write MPR:S \) -composite \
\( MPR:S -resize 50x50% -fill lime -colorize 100 \) -composite result.png
Alternatively, you could let your bash/POSIX shell do it for you inside an "arithmetic expression":
W=200
H=100
convert -gravity west -size ${W}x${H} xc:black \
\( -size $((W=W*30/100))x$((H=H*40/100)) xc:red \) -composite \
\( -size $((W=W*50/100))x$((H=H*50/100)) xc:blue \) -composite \
result.png
Be aware that the shell only deals with integer maths, so it's not going to end well if you aim for 50% of 25 pixels...

Trying to add a stroke around a PNG, can it be improved?

I'm trying to find a good way to add a 3px white stroke to a ton of png files, effectively to make them look like "stickers." I've got some sample code that does a decent job, but I can't seem to get the cropping right. Also, the stroke looks a bit pixelated and I wanted to know if it's possible to get cleaner edges!
I did a bunch of internet scouring, found some sample code, tweaked it around, and came to something that almost resembles what I'm looking for. The images are always going to be PNGs, so I looked into things like inkscape/gimp from the command line but realized I should be able to do this just using convert from the terminal.
convert in.png \
\( -clone 0 -alpha extract -threshold 0 \) \
\( -clone 1 -blur 10x65000 -threshold 0 \) \
\( -clone 2 -fill red -opaque white \) \
\( -clone 3 -clone 0 -clone 1 -alpha off -compose over -composite \) \
-delete 0,1,3 +swap -alpha off -compose copy_opacity -composite \
out.png
in:
out:
ideally:
Your main problem is it is that you do not have enough space bettween your object and the sides of the image. You just need to add your image with transparency and then remove any excess later.
In ImageMagick 6, this should do what you want.
1) read the input
2) add a larger border than you need to add
3) extract the alpha channel from the input and dilate it by the amount of border (in this case 10)
4) copy the previous image and color the white as red and the black as transparent
5) composite the original over the red/transparent image
6) delete the original and the red/transparent image
7) swap the composite with the dilated alpha channel and put the dilated alpha channel into the alpha channel of the previous image
8) trim the excess transparency from the border padding
9) save to output
convert img.png \
-bordercolor none -border 20 \
\( -clone 0 -alpha extract -morphology dilate diamond:10 \) \
\( -clone 1 -fuzz 30% -fill red -opaque white -fill none -opaque black \) \
\( -clone 2,0 -compose over -composite \) \
-delete 0,2 \
+swap -alpha off -compose copy_opacity -composite \
-trim +repage \
result.png
For ImageMagick 7, replace convert with magick.
If on a Unix-like system, you might be interested in my bash ImageMagick script, contour, at http://www.fmwconcepts.com/imagemagick/index.php
A better result can be achieved by replacing diamond:10 with disk:10

Strange effect using 'distort perspective' on multiple images using ImageMagick

I want to create a 3D effect on an image so it looks like a folder, using the +distort Perspective' commands from ImageMagick.
However, if I use the distort multiple times (on different layers) in ImageMagick the result doesn't look correct.
Please see the attached image, left is correct, but the top-right corner of the right image looks strange.
I have used the following commands:
convert square.jpg -brightness-contrast 0x0 -resize 700x700 \
\( -clone 0 -flip -crop 700x140+0-0 -size 700x140 gradient:gray60-black -compose CopyOpacity -composite \) \
-append front.png
convert square.jpg -brightness-contrast -50x0 -resize 700x700 \
\( -clone 0 -flip -crop 700x140+0-0 -size 700x140 gradient:gray60-black -compose CopyOpacity -composite \) \
-append inner.png
convert -background None -virtual-pixel transparent -background white \
\( inner.png +distort Perspective '0,0 0,0 700,0 735,-35 700,700 735,665 0,700 0,700' \) \
\( front.png +distort Perspective '0,0 0,0 700,0 665,35 700,700 665,735 0,700 0,700' \) \
-layers merge +repage 3dimage.jpg
I'm using ImageMagick v6.8
I'm not sure if I understand the layers in ImageMagick correctly.
Can someone see what's wrong? Thanks!
I'm not sure if I understand the layers in ImageMagick correctly. Can someone see what's wrong?
You're doing fine. Just need to repeat the -virtual-pixel transparent on the sub-image for front.png (and perhaps the inner.png too).
convert -background None -virtual-pixel transparent -background white \
\( inner.png +distort Perspective '0,0 0,0 700,0 735,-35 700,700 735,665 0,700 0,700' \) \
\( front.png -virtual-pixel transparent +distort Perspective '0,0 0,0 700,0 665,35 700,700 665,735 0,700 0,700' \) \
-layers merge +repage 3dimage.jpg

Resources