How come imagemagick output has nasty glitchy squares instead of smooth gradients? - image-processing

I'm trying to create filters like instagraph (https://github.com/webarto/instagraph), but the output images have nasty square-shaped transitions instead of smooth gradients. Why and how do I fix this?
The command I'm running is this: convert \( /home/trusktr/Pictures/hawaii_aug-2013/test/DSC05767.JPG -auto-gamma -modulate 120,50,100 \) \( -size 4240x2832 -fill rgba\(255,153,0,0.5\) -draw 'rectangle 0,0 4240,2832' \) -compose multiply /home/trusktr/Pictures/hawaii_aug-2013/test/DSC05767.JPG.kelvin.jpg
Here's the input image:
http://ghz.me/oY
And here's the output (notice the sky isn't a gradient any more):
http://ghz.me/oZ
Here's another example.
input image:
http://ghz.me/p0
output image:
http://ghz.me/p1
You can see in the arms some nast discolorization. Why? How do we defeat this evil magic?

Your version of ImageMagick probably contains a bug. I just tried it with the latest version (6.8.7-8) and it created an image without the strange artifacts.

Related

Apply imagemagick transformation on only part of an image, whilst keeping the rest "stock"?

I have many documents per day that are photographed and I need to organise by QR code. The problem is, zbarimg is struggling to pick up many of the QR codes in the photos, so I have been trialling processing them with imagemagick first, using morphology open, thesholding, etc, which has yielded much better results.
The only issue with this is these apply to the whole image, which makes the rest of the file unusable for me, as I deal with the rest of the image based on colours and information which all gets destroyed in the processing. Could anybody give me an example on how I could apply my imagemagick filters to only a part of an image (coordinate based is fine) and leave the rest of the image untouched, so I can continue my process? I will be applying this to all images in a folder, so it's a batch file running this for me in most instances.
I have tried using crops, however this obviously leaves me with only the cropped portion of the image, which doesn't actually help when trying to process the rest of the file.
I'm running my scripts on Windows 11, if that means anything in terms of the solution.
Many thanks!
Tom
EDIT:
Thank you all for the advice given!
I solved my problem using the following:
convert a.jpg ( -clone 0 -fill white -colorize 100 -fill black -draw "polygon 500,300 500,1500 1300,1500 1300,300" -alpha off -write mpr:mask +delete ) -mask mpr:mask +repage -threshold 50% -morphology open square:4 +mask c.jpg
I did post this as an answer, but (and I have no idea why, I'm brand new to stack exchange) my answer was deleted. I used the clone to make the mask with the coordinates needed, then added the threshold and morphology that would make my QR codes more legible!
Thanks again everyone, really helped me out on my journey to figure it out :D
You can use -region to specify a region to process. So starting with this:
You can then specify a region to colorise with blue and then change the region to blur part of the blue and part of the original:
magick swirl.jpg -region 100x100+50+50 -fill blue -colorize 100% -region 100x100+100+100 -blur x20 result.png
The solution using -region may be the most direct. In ImageMagick versions where -region is not supported the same result can usually be achieved by cropping and modifying a clone inside parentheses.
magick swirl.jpg ( +clone -crop 100x100+50+50 -fill blue -colorize 50 ) -flatten result.png
The cloned, cropped, and and modified piece maintains its original geometry, so the -flatten operation puts it back where it was on the input image after the parentheses.

Batch trim noisy images

I have a massive set of noisy images of drawings that people have created. I'd like to have some function to trim them down to ONLY the drawing.
Here are some examples:
Because of the noise -trim doesn't work
I also tried to use the example linked here (www.imagemagick.org/Usage/crop/#trim_blur), but it was ineffective because of differing noise levels both within and between images.
Lastly, I tried to increase the contrast to increase the likelihood of the lines of the actual drawing being identified, but for similar reasons to the above (differing noise levels), it only sharpened the lines in part of each image.
If anyone has any ideas, I'd love to hear them!
Not sure if this will work for all your images, as there are quite a few problems with them:
artefacts around the edges
uneven lighting, or shadows
noise
low-contrast
but you should get some ideas for addressing some of the issues.
To get rid of the artefacts around the edge, you could reduce the extent of the image by 2.5% on all sides - essentially a centred crop, like this:
convert noisy1.jpg -gravity center -extent 95x95% trimmed.png
To see the shadows/uneven lighting, I will normalise your image to a range of solid black to solid white and you will see the shadow at bottom left:
convert noisy1.jpg -normalize result.png
To remove this, I would clone your image and calculate the low frequency average over a larger area and then subtract that so that slowly changing things are removed:
convert noisy1.jpg \( +clone -statistic mean 25x25 \) -compose difference -composite -negate result.png
That gives this, and then you can try normalising it yourself to see that the shadow is gone:
If I now apply a Canny Edge Detection to that, I get this:
convert noisy1.jpg \( +clone -statistic mean 25x25 \) -compose difference -composite -normalize -negate -canny 0x1+10%+30% result.png
Here is a very crude, but hopefully effective, little script to do the whole lot. It doesn't do any checking of parameters. Save as $HOME/cropper.
#!/bin/bash
src=$1
dst=cropped-$1
tmp="tmp-$$.mpc"
trimbox=$(convert "$1" -extent 95x95% -write "$tmp" \( +clone -statistic mean 25x25 \) -compose difference -composite -normalize -negate -canny 0x1+10%+30% -format %# info:)
convert "$tmp" -crop $trimbox "$dst"
rm tmp-$$.*
Make the script executable with:
chmod +x $HOME/cropper
And run with a single image like this:
cd /path/to/some/images
$HOME/cropper OneImage.jpg
If you have hundreds of images, I would make a backup first, and then do them all in parallel with GNU Parallel
parallel $HOME/cropper {} ::: *.jpg

ImageMagick: Distort and Overlay

I have several pictures of a landscape.
Using the ImageMagick CLI on OSX, I would like to distort and overlay them properly.
I have looked for distortion coordinates between several of the pictures and a reference picture. I fail to understand the diference between -distort and +distort and how it plays with +repage. When I use -distort, the output has the desired offset but it's incomplete (it needs to be bigger). When I use +distort, I get the full image but it's missing the offset.
Reading the documentation I understand that I could do without the offset if I did the overlay composition in the same command before the offset information is lost but what's happening is that the distort is being applied to both the reference and the distorted images.
This is the result of using -distort:
This is the result of using +distort:
The offset of the -distort result would work once I apply it as an overlay (here using the composite in a separate command, but it's missing a big chunk of the picture.
When I tried to consolidate it in a single command this is the result I get:
This is the command I'm currently using:
convert base.jpg overlay.jpg
-matte -virtual-pixel transparent -distort Perspective '961,1695 1856,2461 2279,1520 3185,2303 3564,2173 4441,2970 1547,2817 2441,3594'
-compose blend -define compose:args=50,100 -composite result.jpg
I understand I could use parenthesis there but I fail to see where should I put them.
Thanks!
Update: this is the result of the overlay when using +distort either in two steps or in a single step as recommended by Mark.
The solution was to use -flatten instead of -composite.
convert base.jpg \( b.jpg -matte -virtual-pixel transparent +distort Perspective '961,1695 1856,2461 2279,1520 3185,2303 3564,2173 4441,2970 1547,2817 2441,3594' \) -compose blend -define compose:args=100,50 -flatten result.jpg
Turns out that -composite ignores the image offsets whereas -flatten works with layers and uses the offset information.
The suggestion came from this thread: http://www.imagemagick.org/discourse-server/viewtopic.php?t=20157
This is the documentation to flatten (link broken in the discussion above): http://www.imagemagick.org/Usage/layers/#flatten
Not sure I understand the issues, but would suggest you try this (untested):
convert base.jpg \
\( overlay.jpg -matte -virtual-pixel transparent -distort Perspective '961,1695 1856,2461 2279,1520 3185,2303 3564,2173 4441,2970 1547,2817 2441,3594' \) \
-define compose:args=50,100 -compose blend -composite result.jpg
That would mean that the perspective distortion is only applied to the overlay, not the base. So, in the code above, the first line only processes the base image, the second line only processes the overlay, and the final line blends the two.

Imagemagick: distorting images on top of background?

I've got one background image: sky.jpg
And two transparent PNG images: gradient.png and tree.png
Now I want to draw the two images on the background with a perspective distortion, like this:
The destination coordinates of the two images are, in clockwise order (starting top left) :
gradient: 62,129 421,218 383,458 147,548
tree: 445,100 765,47 698,368 529,396
I cannot figure out how to start with one image (in this case the sky background) and then take another image and draw that with perspective distortion to specific destination coords within the background. Also doing this with more than one image at a time, within one convert command, troubles me.
For example, when I start with just one image (the gradient) and try this:
convert sky.jpg \( gradient.png -alpha set -virtual-pixel transparent \
+distort Perspective "0,0 62,129 255,0 421,218 255,255 383,458 0,255 147,548" \) \
-compose src-over -composite result.jpg
It gets correctly warped (so the coordinates are relatively correct) but it's drawn in the top left corner, not at the coordinates I specify.
Also I'm a bit unsure if my usage of -compose and -composite is correct (I took this from various IM manual examples).
One other thing that is unclear to me: in case of the 256x256 image, should I use 255,0 and 255,255 and 0,255 as the corner coordinates, or 256,0 and 256,256 and 0,256 ?
Any IM experts who can shed light on these issues?
Add a -geometry just before the -composite like this:
convert -size 800x600 xc:black \( -size 300x200 xc:red \) -geometry +90+10 -composite result.png

ImageMagick on iOS: Blurring and blending an image with itself

I'm trying to take an image, blur it with a 10px radius (both -blur and -gaussian-blur should work fine), then give it a 50% opacity, and finally overlay the blurred transparent image with the original. Here's what I've got so far:
convert sample.png \( sample.png -gaussian-blur 10 -matte -channel A
-evaluate set 50% \) -composite dreamy.png
Here's the original image:
And here is what it should look like after the effect is applied:
However, what I get with the command above just looks very similar to the original. Anyone have any ideas how to achieve the effect I want? If I do what I originally described in an image manipulation program, I get the desired effect, so something is probably wrong with the command I'm using.
Edit:
-adaptive-blur seems to get me closer to the desired effect, but still I'd like to use -blur.
Edit 2:
convert round-face-winslet.jpg \( +clone -blur 0x10 \) -compose Screen -composite round-face-winslet_soft.jpg
...gets me yet closer to the result, but no matter what kind of -compose method I choose, the result still does not look like the desired image. It's either too light or too dark. What should be a simple 50% opacity blended with the underlying original picture, for some reason doesn't want to work...
I think the effect you are looking for can be found in the ImageMagick compose examples in the "Softened Blurring" section.
convert face.png -morphology Convolve Gaussian:0x3 face_strong_blur.png
convert face.png face_strong_blur.png \
-compose Blend -define compose:args=60,40% -composite \
face_soft_blur.png
Looks like this:
An older tutorial on this technique (here) suggests lightening the blurred layer and blending in Multiply mode. I expect that darkening the blurred layer and blending with Screen would also work. Don't use a standard 50/50 blend - it doesn't have the same glowing appearance.
In your sample, the shadows of the processed image are lighter. Multiplying can only make an image darker, so I'm guessing they took the darken-Screen approach.

Resources