How can I Convert grayscale image to false color gradient with imagemagick - colors

input b/w, output with CLUT
I want to create false color images from grayscale input images. Similar to the typical false color images produced by nasa from b/w inputs to highlight contrast and texture. I can do this in gimp by applying a custom gradient to an indexed color b/w photo. I am sure there is a way to duplicate this with IM but, i cannot find an example in the docs or on stackoverflow. My goal is to automate the process and produce several pseudocolor outputs from each b/w input image. This is for an art project, so no great precision or scientific validity is required. Although, someone may build on my project.
An example would be producing a color relief map from a typical bump map.
Your solution worked. Thank you #MarkSetchell
create new colour look up table named rainbowCLUT.png:
convert -size 1x1! xc:black xc:red xc:orange xc:yellow xc:green xc:blue xc:violet xc:white +append -resize 255x1! rainbowCLUT.png
apply clut to image:
convert FullMoon2010.jpg rainbowCLUT.png -clut result.png;eog result.png

Your solution worked. Thank you #MarkSetchell
create new colour look up table named rainbowCLUT.png:
convert -size 1x1! xc:black xc:red xc:orange xc:yellow xc:green xc:blue xc:violet xc:white +append -resize 255x1! rainbowCLUT.png
apply clut to image:
convert FullMoon2010.jpg rainbowCLUT.png -clut result.png;eog result.png

Related

Resizing does not respect resolution specification

I've got a 16x512 image comprised of 16x16 images. I want to seperate them, individually scale each one down to 16x8, then put them all back into their full 16x512. I've got a basic idea, but I'm having trouble executing it.
Using the commands from unix stackexchange, I split by file by using convert -crop 16x16 my_image.png crop-%d.png, which yields 32 images (512 / 16 == 32). My next step was where trouble has started. From askubuntu, I found the command mogrify -resize 16x8 crop-*.png, however this does not yield 16x8 images, but rather 8x8, which I do not want. Furthermore, this post on stackoverflow gives me the command for merging these images, which is convert crop-*.png -append my_image_cropped.png, however it does not yield a 16x512 like I want, but rather 8x256 (the 8 is due to the previous bug, but I still want a height of 512, not 256).
What do I need to accomplish my goals? The image in question can be found on imgur.
Edit: Here are some images which will describe the basic idea
The full image:
Both 16x16 and 16x8 side by side
The finalized image, basically the 16x8 will sit in the 16x16 area (right at the bottom part, that is essential), but won't fully fill it.
I am not sure I understand what you want to do. But if you resize 16x8, Imagemagick will keep aspect ratio. If you want to force it to be exactly 16x8 and can accept distortion, then use the ! flag. But you then say you want to put the 32 pieces back to form 16x512, but the resize will make it 16x256, since you have 32 image of height 8. So you have to resize again. Here is how to do that, if that is really what you want.
Create a gradient image for testing:
convert -size 16x512 gradient: grad.png
Do the processing:
convert grad.png -crop 16x16 -resize 16x8! -append -resize 16x512! newgrad.png
Note that proper Imagemagick syntax reads the input first.
ADDITION:
Given your new information in your comment, try this:
convert grad.png -crop 16x16 -resize 16x8 -gravity northwest -background none -extent 16x16 -append newgrad.png
Change the background color as desired and the gravity setting as desired for positioning.

Imagemagick crop from northeast

I am trying to crop an image starting from top-right and cut out a 48x48 box.
This is the image I'm working with
I've tried this
in.png -gravity northeast -crop 48x48 out.png
out-0.png
out-1.png
out-2.png
out-3.png
Which creates like 4 files, none of which are what I want.
When I add x and y values (which I don't want to), it crops from the northeast correctly with only 1 output image, but the box is not 48x48, its 46x38
in.png -gravity northeast -crop 48x48+0+0 out.png
out.png
This gives different outputs for different images. I just tried another and ended up with a 33x48 output.
I need to use the gravity setting instead of the x and y offsets because I'm batch processing a lot of images that are different sizes.
This is the desired output
Can someone please explain to me what I'm doing wrong? Thanks!
If your input image has paging information, the result of your crop may not be what you expect. When working with unknown images, you might do a "+repage" right after reading in the image. Also, when you "-trim" an image, the paging information from the original image remains. The "-crop" will use that paging information instead of the actual height and width, so "+repage" after a "-trim" unless you know you'll need that information. Try this...
convert inimage.png -trim +repage -gravity northeast -crop 48x48+0+0 outimage.png
You should also use "+repage" after any crops if you intend to continue processing the images.

Graphics program that will generate a common palette from multiple jpgs

gimp has the ability to generate a palette from a loaded image. I am looking to have all images (i am not necessarily the author of these pictures) share a common palette since this makes it easier displaying them on an LCD screen.
is there a program that does this? or some script in gimp or imagemagick?
There are few ways to do this:
use dithering
with palette designed for dithering like default VGA or WEB palette. I do it like this:
my simple C++ dithering
on how to do this. There are also more sophisticated approaches for this out there just google dithering...
merge all images to single mosaic
and compute the palette for this big image containing all the images you want with tool you use now. After that just use this palette for each of the original images (or on the mosaic and then de-mosaic).
compute the palette yourself
You need to compute histogram of all images and then use some kind of clustering to lower the number of colors. To include more images to this just compute histogram for all the images (do not reset it between images) and the rest is same as for single image. So if you got access to the color quantization code of yours then just change the histogram part ... by adding loop through all the images you want (and clearing histogram just for the first image).
Here example of how I do the color quantization:
Effective gif/image color quantization?
I do not use gimp nor imagemagick so I can not help you there but now you at least know what to look for in their docs ...
I'm not sure what you are trying to do is applicable to JPEG images as they do not have a colour palette. However, a possible technique with ImageMagick at the command line would be to put all the images together, reduce the number of colours to whatever you want and then save that (minimised/de-duplicated) as a "palette" which you can apply to other images.
So, the first step is to extract a common palette, of say 250 colours:
magick image1.jpg image2.jpg ... +append -colors 250 -unique-colors palette.png
Now, before you display any image, map it to that palette:
magick image.jpg -remap palette.png result.png
You can also disable dithering, with:
magick +dither image.jpg -remap palette.png result.png
I have used PNG rather than JPEG throughout because of my issue with JPEG palettes, but you can try with your JPEGs using just the same commands. I would definitely suggest you use GIF, PNG or NetPBM PPM format to store the palette information at least.
Just for fun, let's try that with a picture of the White House:
Let's make a really poor palette of three colours - red, yellow and cyan:
convert xc:red xc:yellow xc:cyan +append palette.png
and apply it with dither:
convert whitehouse.jpg -remap palette.png dither.png
and again without:
convert whitehouse.jpg +dither -remap palette.png undither.png
As #Spektre points out in the comments below, you may be passing that palette to the LCD in some BYTE array or something like a lookup table. If that is the case, you can see the palette in human/ASCII terms like this:
convert palette.png txt:
# ImageMagick pixel enumeration: 3,1,65535,srgb
0,0: (65535,0,0) #FF0000 red
1,0: (65535,65535,0) #FFFF00 yellow
2,0: (0,65535,65535) #00FFFF cyan
And you can get a 9-byte file of the R, G & B values in binary like this - I am choosing to dump it in hex afterwards so you can see it:
convert palette.png -depth 8 rgb:palette.bin
xd palette.bin
00000000: ff00 00ff ff00 00ff ff .........

How to offset image contents by X,Y pixels using ImageMagick?

I need to offset the pixels in a PNG image by -1 in X and -4 in Y axis.
The images were converted from a PDF created by Corel Draw, which adds an offset, breaking the image processing system I'm working on.
align_image_stack from hugin-tools package crashes when processing these files, that's why I resort to trying a fixed offest correction.
I tried this these commands:
$ convert a.png: -geometry 100%-100-100 b.png
$ convert -region '100%+500px+100px' a.png b.png
$ convert -page '100%+500px+100px' a.png b.png
$ convert -repage '100%+500px+100px' a.png b.png
$ convert -crop '100%+500px+100px' a.png b.png
$ convert a.png -geometry 100%-100px-100px b.png
They have all finished without an error, but the gave me the same image I fed them as input.
a.png = b.png
What am I doing wrong? Why the Covert command does not shift the image contents?
EDIT:
Here's a pair of images to illustrate my problem. The first image is what I want, the second is what comes out of Corel Draw, I want to apply an arbitrary X/Y offset to compensate for this difference. The images are faked only to illustrate the problem, this is not authentic data.
New point is that I was able to produce the offset once, but I can't reproduce this. It looks to me like a bug in ImageMagick, because I'm trying the same command that I used before and it doesn't work now.
I also tried using GraphicsMagick to doublechek this.
I was able to get an offset written to PNG header, but that doesn't make Blender use that offset, so I need to "burn" that offset into the bitmap data, not just specify it in the metadata.
This command did a change, but only GIMP seems understands that and I need to make Blender apply the offset:
convert a.png -repage '100%x100%+100+1000' b.png
I tried using -sample to apply the transformation, but it's not alpplied and stays in the metadata - I can check this with GIMP.
convert a.png -repage '100%x100%+100+1000' -sample 100% b.png
I can't believe I am unable to do such a simple thing.
Updated Answer
It is hard to understand what you want without proper images, but here is another attempt at guessing a solution for you. Let's start with this image - ignore the colours as I only added them so you can see the extent of the images and you can remove/change them anyway:
The new plan is to trim your image so there is no border around the letters at all and then to add in whatever border you want afterwards. So, trimming the existing border and adding a 10px border left and right and a 50px border top and bottom:
convert start.png -trim -bordercolor red -border 10x50 result.png
Or, trimming the original border and adding a 10px border to the right side only:
convert start.png -trim -gravity east -background blue -splice 10x0 result.png
Hopefully that will give you an approach to achieve what you seek.
Original Answer
If you want to reset the page offsets back to zero, the easiest way is:
mogrify +repage image.png
Or, slightly harder:
convert image.png +repage result.png

Using ImageMagick to remove all color except black in an image?

The situation is : I have many images of documents from scanning. I want to keep the document's main content - which is printed in color black (a small range of colors around #000000). But, you know, the documents are always full of colors : stamp, background, decorations, logos...etc.
I just want to keep the TEXTS ONLY which were printed in the color black.
I've tried with ImageMagick and this command so far:
convert X.png -matte (+clone -fuzz 20% -transparent "#000000") -compose DstOut -composite X1.png
But the result was not as expected , the text was very damaged that I cannot read.
Someone suggested me to increase the fuzz to 70%:
convert X.png -matte (+clone -fuzz 70% -transparent "#000000") -compose DstOut -composite X1.png
Then the text appeared to be more readable, but the other colors kept remaining too.
Can you please show me a better solution for my situation? Every suggestion would be highly appreciated!
To match all colors except black you can use +opaque "#000000".
In order to include a little range around #000000 you can try different percentages with the fuzz operator:
convert input.png -fill white -fuzz 10% +opaque "#000000" result.png
Tested with ImageMagick 6.6.0-1 on Windows
I stumbled upon this question while looking for an answer to this question. I found a couple imagemagick forum posts that helped. Here is what I came up with:
convert input.gif -matte \( +clone -fuzz 1 -transparent black \) -compose DstOut -composite ~/Desktop/output.png
Forum post: ImageMagick: Removing all but one color
You should try the level command:
convert test.png -level 25%,75% test_level.png

Resources