I'm using an example for ImageMagick's gradient found here:
http://www.imagemagick.org/Usage/photos/#tilt_shift
The arguments are as follows:
magick convert beijing_contrast.jpg -sparse-color Barycentric "0,0 black 0,%h white"-function polynomial 4,-4,1 beijing_blurmap.jpg
It creates a perfect gradient image with white at the top and bottom:
But I can't figure out how to do the same thing for portrait image (make white at the left and right edges).
Please help.
In Imagmagick, just change the arguments to sparse-color. Use %w,0 rather than 0,%h. Note also that in Imagemagick 7, you should use just magick and not magick convert and not convert. Otherwise, you may get IM 6 behavior. For other tools such as identify and mogrify and montage, etc, you do need to preface those with magick. Note also you are missing a space before -function. Try
magick beijing_contrast.jpg -sparse-color Barycentric "0,0 black %w,0 white" -function polynomial 4,-4,1 beijing_blurmap.jpg
If needed, swap the black and white depending upon whether you want it white in the middle or black in the middle.
For IM 6.9.2.5 or higher, there are new convenience defines for creating various directional gradient. But you need to specify the image size. See https://www.imagemagick.org/script/gradient.php
Related
With a few thousand images like the following one, with complex edges from scanning (first a perfectly regular white one, then a very fuzzy gray/black'ish one), is there a good algorithm to figure out the coordinates of the area-to-keep? In the below example, going clockwise from the north-western corner, the optimal coordinates would be:
121,18
1934,18
1934,1312
121,1312
So that from this input image...
... can be cropped to remove anything tinted red, as shown here:
To clarify, I do know how to use ImageMagick or other tools to crop to that area. What I'm not sure about is how to figure out how to get to those above numbers? Do you just binarize the image and then go left to right until you hit "white" for the first time, then do the same from top to bottom, right to left and bottom to top? Or is there some library, script, etc. which already does that for you?
I would use vertical and horizontal projections of the image. By a simple detection of the highest transition, you easily find the limit between the background and the paper.
Your image has a border of white surrounding a border of black. So you can do two fuzzy -trim processes after padding with the appropriate color to ensure it goes all around the image. So in ImageMagick 6, it would be
Input:
convert book.jpg -bordercolor white -border 1 -fuzz 55% -trim +repage -bordercolor black -border 1 -trim +repage book_trimmed.jpg
Result:
Suppose I have some image a.jpg and some other image b.jpg.
The desired output out.jpg should be obtained by copying all the pixels from b.jpg that are not black onto a.jpg, all other pixels shall remain untouched.
I tried using composite but had no success whatsoever.
EDITED TO ADD: A solution here can be quite simple and generic, but going forward, please remember to always include your version of ImageMagick and which OS or platform you're working on. There are some syntax differences that can make that important.
At the very simplest, using ImageMagick v6, you should be able to do something like this...
convert b.jpg -background none -transparent black a.jpg +swap -composite out.jpg
That reads in the B image, changes all the pure black pixels to transparent, then reads in the A image, swaps the images so they're in the right order, then composites the modified B image over the A image and writes the output.
You can add a fuzz value like "-fuzz 5%" ahead of the "-transparent" operation to expand the selection to include near-black pixels, also.
To use with IMv7 change "convert" to "magick".
I am trying to extract a region from an image that is already marked with a certain color. In the picture below
I would like to extract only the pixels which belong to the sidewalk, that is, all pixels that belong to the black blob that is connected to the mid-lower part of the image. There are black dots outside that blob which I am not interested in. So if I could get roughly the region shown below
it would be perfect. Does anyone know of some common algorithms that can do this? Morphology? Region growing using a kind of flooding algorithm?
Thanks,
You can do that quite easily with a flood fill. If I use ImageMagick to demonstrate at the command line because it is installed on most Linux distros and is available for macOS and Windows.
So, bearing in mind that the pixel you identified as your seed is at around 440,520 in the image you supplied that includes the axes, we can floodfill all pixels that match that colour and touch the seed with cyan using:
convert scene.png -fill cyan -draw 'color 440,520 floodfill' result.png
Or, we can make a mask by changing the non-cyan pixels to white and the cyan pixels to black:
convert scene.png -fill cyan -draw 'color 440,520 floodfill' -fill white +opaque cyan -fill black -opaque cyan z.png
There are a thousand other things you can simply do from the command line to take this further... fill small holes in the mask, make a transparency layer from the mask - just ask more questions if you need a hand.
If you want to close the holes in your image, you probably want to use morphological functions. I am away from any computers with ImageMagick for a week so I can only tell you in general terms. Start with the pure black and white (no grey) picture above and try:
convert image.png -morphology open disk:3 result.jpg
Try replacing the word open above with close, erode or dilate. Experiment with disk, disk:3 disk:7 and so on.
I'm trying to remove white lines which cute in pieces an image.
I'm using :
convert input.png -fill white +opaque "#e6e6e6" -fill black -opaque "#e6e6e6" -median 2 -magnify result.png
to remove the background with the following output :
How could I remove those white lines using ImageMagick ?
Thanks
You could use the morphological operators that have been introduced into ImageMagick, specifically the dilation operator. It grows the white regions of the image, which is the opposite of what you want so we negate the image first, making blacks white, do the morphology then negate back to your original.
As the gaps are along a horizontal line, we want a vertical structuring element for the morphology, so we can use a vertical line one pixel wide and several pixels tall - I chose 9 pixels. So, all in all, your command looks like this:
convert in.jpg -negate -morphology dilate rectangle:1x9 -negate out.jpg
The result looks like this:
I just encountered unexpected behavior in ImageMagick, which I'm hoping someone can explain to me.
Version numbers
$ convert --version
Version: ImageMagick 6.7.7-10 2013-02-25 Q16 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2012 ImageMagick Studio LLC
Features: OpenMP
Running on Linux Mint 15 Olivia (based on Ubuntu 13.04 "Raring Ringtail").
Executive summary
Running the same operation with two images that should be quite similar, except that one is a GIF while the other is a JPEG, the resulting output is entirely different. The GIF comes out black, the JPEG comes out white.
To reproduce:
Go to http://karenswhimsy.com/public-domain-images/animal-silhouettes/animal-silhouettes-1.shtm and download the elephant silhouette as elephant.jpg
Download http://www.arthursclipart.org/silhouettes/animals/DUCK1.gif as DUCK1.gif
convert elephant.jpg -negate -alpha shape output-elephant.png
convert DUCK1.gif -negate -alpha shape output-duck.png
Compare the output-elephant.png and output-duck.png images
Can anyone explain why these two output images are different? Why the GIF duck ends up being black after conversion, while the JPEG elephant becomes white after conversion?
Long-winded explanation
The situation is this: I want to take some black-and-white images, turn the background transparent, and turn the foreground different colors. For example, starting with the elephant silhouette at http://karenswhimsy.com/public-domain-images/animal-silhouettes/images/animal-silhouettes-1.jpg (I saved the image as elephant.jpg), I want to produce a .png with a transparent background and an elephant that's green, red, yellow, or whatever color I want.
The command I'm using to do this is:
convert elephant.jpg -negate -alpha shape +level-colors ,green green-elephant.png
This does exactly what I want. First it inverts the image so that the background is black and the elephant is white, because -alpha shape expects an alpha mask where black = fully transparent and white = fully opaque. Then -alpha shape does its magic and produces a white elephant against a transparent background. Then +level-colors ,green kicks in, transforming black-and-white gradients into the two colors specified as parameters to +level-colors; here, the first color is omitted so it would remain black, and the second color is what white turns into. This produces a green elephant with smooth borders -- exactly the result I want -- and I'm quite happy with it.
Next, I tried running the same command against one of the images from http://www.arthursclipart.org/silhouettes/animals.htm (I used DUCK1.gif). The input source is the same -- a black silhouette against a white background -- so I expected the same result, a green duck against a transparent background. But it didn't work. A little research showed me that -alpha shape was behaving differently. Where with the JPEG elephant it was producing a white elephant against a transparent background, with the GIF duck the same command was producing a black duck against a transparent background. In other words, -alpha shape was inverting the result with a GIF image source, but not with a JPEG image source. So to color the animal properly, I needed to rewrite the +level-colors parameters to put "green" before the comma instead of after.
Tweaking my script is no problem at all, but I'd love to understand why this is happening, and so far I'm clueless. Can anyone explain to me why ImageMagick is treating GIFs and JPEGs so differently in the -alpha shape operation?
OK, I think here is the story. With GIF, a background color might be explicitly defined, and I think that is the case with DUCK1.GIF. Not so with JPEG; here the background is, I think, assumed to be "white".
Whatever the case is, converting the DUCK1.GIF to DUCK1.JPG results in a similar image to the elephant. Moreover, you can make sure that the same background color is used with the apropriate Imagemagick option. The two commands below produce similar output:
convert DUCK1.jpg -background Black -negate -alpha shape output-duck.png
convert elephant.jpg -background Black -negate -alpha shape output-elephant.png