Plotting a histogram (not what you think)

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
Post Reply
jmac698
Posts: 48
Joined: 2013-12-20T01:57:16-07:00
Authentication code: 6789

Plotting a histogram (not what you think)

Post by jmac698 »

Hello,
I've been told that ImageMagick "does everything" but I'm stuck on one small point.

I want to plot a histogram as brightnesses rather than a graph, for example a pure grey image would result in one point at x=128 with a value of (255,255,255), in an image 255x1 in size. I'll be concatenating many of these lines later, but let's start with the basics. I found that you can save a histogram as data here: http://www.imagemagick.org/Usage/files/#histogram and that a plain text table is stored as a comment in an image file. I can then use a memory register to work on that data further. Where I'm lost is where I can use -draw 'point x,y' commands based on that data table.

I was also told to look into GnuPlot, and it seems more concerned with normal graphs (though it does every kind).

Is this even possible?
jmac698
Posts: 48
Joined: 2013-12-20T01:57:16-07:00
Authentication code: 6789

Re: Plotting a histogram (not what you think)

Post by jmac698 »

I have an idea that might work, if you use -histogram and then -format %c you can get the text table of unique colours, then use the .txt format import of an image, only problem is I can't find documentation of the txt format or how to use it. There's also the pbm with no compression which uses ASCII for a list of pixel values, but there's still some text reformatting somewhere that needs to be done.

Also what I want to do is related to the idea of a heatmap graph. gnuplot can do that but still not sure how to draw it without any scales or labels and then save as a picture, or if it can read the histogram imagemagick produces.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Plotting a histogram (not what you think)

Post by fmw42 »

I want to plot a histogram as brightnesses rather than a graph, for example a pure grey image would result in one point at x=128 with a value of (255,255,255), in an image 255x1 in size

Not quite sure what you want? Why would the values be (255,255,255) at coordinate x=128. X is the graylevel, which in this case is gray or 128. But why the 255 colorvalues? In a histogram, the value would be the counts for that graylevel. Please clarify.

If on Linux/MacOSX or Windows with Cygwin, see my scripts colorspectrumn and spectrumhist at the link below. Then let me know if that is what you need.

Also what platform are you using and what version of IM?

Also see my script, plot, which can make a normal histogram using GNUPLOT
jmac698
Posts: 48
Joined: 2013-12-20T01:57:16-07:00
Authentication code: 6789

Re: Plotting a histogram (not what you think)

Post by jmac698 »

Thanks for the reply Fred!

Yes, I messed up my example. If my image were 200x1 and dark grey (64,64,64), then the result I want is 255x1 (oops 256x1) and (0,0,0) except at x=64 where it would be (200,200,200).
Another example, a perfect linear ramp would be a solid line of (1,1,1) from x=0 to x=199.

I'll check your script, thanks.

p.s. ok, -t spectrum -s lum might work.
Last edited by jmac698 on 2014-08-08T19:01:04-07:00, edited 2 times in total.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Plotting a histogram (not what you think)

Post by fmw42 »

What platform are you on and what version of IM?

If on unix, I would use awk to process the histogram from -format "%c" histogram:info

So if I understand, you want a 3 channel by 255x1 image, with each pixel representing the count at that channels intensity. AWK can do this combine with some IM processing. I do something like that in my scripts that I mentioned.

The problem you have is if your input image is very large, you can get counts that exceed 255 or even 65535. How are you going to deal with that?
jmac698
Posts: 48
Joined: 2013-12-20T01:57:16-07:00
Authentication code: 6789

Re: Plotting a histogram (not what you think)

Post by jmac698 »

Hi,
The platform is windows, and the version would be the latest.

As far as scaling, I could crop or scale my image, or else have the heatmap scaled from the minimum count to the maximum count. I have a usb stick with Linux, but I can't do a lot of things while in Linux so I don't like to spend a lot of time there.

Since this is looking possible, I want to do this analysis line-by-line for the whole image. I want to sort the lines in a special way, they will be ordered by average luminence. I am really only interested in one channel and the image is greyscale. I'm doing this for an analysis of an unknown (in image terms, it's actually an analog electronic error) artefact on a video. I want to use cluster analysis, guassian mixing model, and classification, if that means anything to you, and this plot will let me see some things (I won't bother explaining :) ). Thanks.

p.s. my result should be 256x1 of course!
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Plotting a histogram (not what you think)

Post by fmw42 »

This will give you the IM histogram information in text format to the terminal. You can of course redirect to a text file if you want or filter further as you see fit. Since you are on Windows, I cannot help with my use of unix AWK. So you will either have to proceed by yourself or get further help from one of the Windows users.

Code: Select all

convert image -depth 8 -define histogram:unique-colors=true -format "%c" histogram:info:
See
http://www.imagemagick.org/Usage/files/#histogram

For those on Unix, this will do what is desired. In this case, the image is a constant gray level gray50 (mid gray at value 127)

Code: Select all

array=(`convert -size 255x1 xc:"gray50" -depth 8 -define histogram:unique-colors=true -format "%c" histogram:info:- \
| tr -cs '0-9\012' ' ' |\
awk '
# AWK to generate a histogram and max count
{ bin[int($2)] += $1; }
END { for (i=0;i<256;i++) { hist = bin[i]+0; print "xc:gray("hist")" } } '`)
#echo "${array[*]}"
convert ${array[*]} -background black +append hist1D.png
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Plotting a histogram (not what you think)

Post by snibgo »

For a Windows BAT script that makes a histogram (optionally cumulative), see my col2histo.bat at http://im.snibgo.com/ckbkClut.htm#cumhist The actual script is at the bottom of that page.
jmac698 wrote:... cluster analysis, guassian mixing model, and classification, if that means anything to you, ...
I confess that means nothing to me.

On my to-do list is to write C-code that can be incorporated into ImageMagick for these functions:
1. For all the images in the list, sort every line into ascending order of intensity. (Typically this could be used with one image, size Nx1.)
2. For all the images in the list, create a (cumulative) histogram, dimension Nx1.
3. Invert a cumulative histogram.

I want it in C because scripts for 65536x1 histograms are painfully slow.

These are simple tasks; I just need to figure out how to incorprate them into IM. I need an idiot's guide to "-process module", or other mechanism. [EDIT: Thanks to Fred for pointing me to http://www.imagemagick.org/script/archi ... hp#filters, and especially the Magick Filter Kit.]

EDIT: I have just corrected a bug in a script on that page. The bottom should now say "Page created 09-Aug-2014 03:12:24."

For your purpose, you probably want to remove "-auto-level" in scripts. This will give you a genuine count (up to 65535).
snibgo's IM pages: im.snibgo.com
jmac698
Posts: 48
Joined: 2013-12-20T01:57:16-07:00
Authentication code: 6789

Re: Plotting a histogram (not what you think)

Post by jmac698 »

Hello,

I've decided that there won't be a quick solution along the lines of using either imagemagick or gnuplot for my needs. I was hoping to whip up a quick graph to investigate if a certain idea I had would work, but now it seems that I'll just have to do it the hard way. It's still too bad though, I really could use all the image manipulation features for other aspects of my project, now I'll have to recreate some simple things from scratch in code.

Anyhow, as it happens, your histogram matching is quite interesting to me for some other research I've always wanted to do, so I will write your 65536 histogram soonish, I hope :) It will be in C.

Meanwhile, there is a free tool for it which exists,
http://www.avisynth.nl/users/vcmohan/Hi ... djust.html
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Plotting a histogram (not what you think)

Post by fmw42 »

IM can generate a simple grayscale histogram. See http://www.imagemagick.org/Usage/files/#histogram
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Plotting a histogram (not what you think)

Post by snibgo »

The simple grayscale histogram can, of course, be negated then rescaled to give a Nx1 histogram image. But it is automatically scaled so the largest count is 1.0, and is limited resolution.
snibgo's IM pages: im.snibgo.com
Post Reply