Retro-Histo: making an image fit your histogram!
So David over at Ironic Sans recently rolled out a neat trick: starting with a histogram and working backwards, as it were, to create an image that fit it.
Wonderful idea. And he does it; but he doesn’t take it far enough, dammit. His output works—its histogram, when viewed, is indeed the NYC skyline—but the image itself is just a spiffed-up greyscale gradient.
What about being able to create an arbitrary image—or, more to the point, being able to modify an existing image—so that you come away with something that looks like something and fits your target histogram?
Sure! I’ve been working out the idea for the last few days (not that it’s a days-long problem, difficulty-wise, but I’ve been coming at it slowly here and there), and I’ve got a perl script that will take a histogram and a source image and spit out a new image that is undeniably the “original”, but modified in its brightness levels to make it fit the target histogram.
Example time! Here’s a source image: a picture I took a while back of a firehand in Portland.

And here is that image’s original histogram:

Now, that’s a fine histogram and all, but what I really want is an image that has this histogram—the skyline of Miami. (Why Miami? I’ll get there in a minute, don’t worry.)

So, okay: I run this through my histogramization script (basically some straightforward Perl using Image::Magick for image-reading and -writing routines), and what I get out is this:

Hey, it’s the original image, but kind more dark and grainy. And with a histogram that looks like the Miami skyline.
Hell yes. Of course, you’ll have to check it in photoshop or whatever to actually see the proof, but if you’re reading this you’re probably the sort who would do that. Go crazy!

Here’s that image’s histogram, for reference:

Here’s that Miami skyline-histogram from above again: I made it by painting the city black and the sky white in Photoshop.

And, shucked through the Perl script, here’s what came out the other side:

Again, you’ll have to check the histogram in your viewer of choice to be sure, but that right there is a picture of the Miami skyline with a self-similar histogram. Hot damn.
So! It can be done. There are a lot of wrinkles, of course—for one, this method produces stranger results for very eccentric histograms; for another, it’s only greyscale, color being a bit more complicated of an issue (though not necessarily fundamentally so, depending on how you handle it). The way one histogram viewer or another displays a given image will also affect the quality of the histogram-viewing experience, so what looks good to in the histograms this script itself generates won’t necessarily look great in photoshop or the GIMP or whatever—the shape should be right, but it might be a bit jaggy or have the wrong aspect ratio. Some of that is probably solvable, but I’m not going to try at this point.More images, histograms, and the perl itself can be found in the working directory.
Suggestions, comments, questions &c are welcome, as are custom histograms if you’d like me to see what they do to images. If you want to send me a histogram, it needs to fit these parameters:
- 256*100 pixels
- black and white, black on the bottom
- at least one black pixel for each level (this is fragile alpha software)
Nerd fun is the best goddam fun there is.
Late Update! Here’s what happens if I give this a shot with the original NYC skyline shot that David used for his experiment.
Original (cropped down to histo-size to improve the self-similarity results):

Histogram of original:

Target NYC histogram

And the output, with target histogram:

Cool! It’s kind of ugly, though; I mentioned above that one caveat of this technique is that more eccentric histograms will produce odder results, and this is a decent example. The original image has a great big spike of dark tones (the skyline silhouette is a wash of black (or something close to black, really) and the target histogram has a somewhat well-distributed range of tones, which means that by mathematical necessity that skyline will have several varied tones filling out the even dark space of the original.
It’s also jpeg artifact theater, hoo boy.
So, lesson learned: a good range of tones in the original will improve output in the final image, generally speaking. Compare with the self-similar Miami output above—that photo had a pretty rich palette to begin with, so it came out looking more over-processed than ugly.



secretariat Said,
October 4, 2007 @ 6:45 pm
So wait, that’s called a “firehand”?
Hairy Potter Said,
October 4, 2007 @ 8:28 pm
So, this firehand, it vibrates?
RoJ Said,
October 5, 2007 @ 7:11 am
This is easily the coolest thing you’ve done in years.
Blues name generator excepted.
Josh Millard Said,
October 5, 2007 @ 8:16 am
Here, by the way, is the Metafilter thread about David’s original post, with intense dorkery inside, including this excellent volley wherein PuGZ presents a proof-of-concept for per-channel color histogram-fitting hijinks. The initial results weren’t particularly smooth, but the process was clearly there.
Josh Millard Said,
October 5, 2007 @ 8:22 am
And I missed this at first, but Nick Fisher built (before I ever got my experiment working) this histogram toy that creates a greyscale gradient based on an input histogram—see more explanation in his blog post about it.
Josh Millard Said,
October 5, 2007 @ 8:39 am
A couple more things:
- David has made a new post over at Ironic Sans discussing this. I’m not sure “Josh is a genius.” isn’t overstating it, but I’m not gonna complain. Thank, David!
- A quick summary on Flickr; I think that there are more people who watch my flickr stream than there are people who read this blog. Heh.
Josh Millard Said,
October 5, 2007 @ 11:55 am
Histogram fitting links:
- Check out page 76 or so of Tony Jebara’s 1995 thesis, 3D Pose Estimation and Normalization for Face Recognition, for some hot histogram-fitting equations.
- This paper, Perfectly Flat Histogram Equalization, sounds pretty fascinating, but the Internet doesn’t seem to have a copy. Li’l help?
- And, bingo? A fast, non-iterative and exact histogram matching algorithm, Morovic, Shaw, Sun. The abstract:
A fast, non-iterative algorithm is presented for transforming an image so as to give it exactly a given target histogram. This is achieved for any original and target histogram combinations and examples of results are given in addition to a comparison with applying the earth mover’s distance (EMD) method to this task.
Again, I don’t have access to the actual paper, but it sounds like that might be exactly what’s going on here.
- Getting a bit more general: a paper on histogram enhancement for xray visibility, a coursework page discussing histogram matching, and some completely badass wonkery on secure image steganography vs. histogram comparison.
box Said,
October 5, 2007 @ 12:41 pm
‘Firehand’ would be a good nickname for a blues musician.
Josh Millard Said,
October 5, 2007 @ 2:03 pm
Histogrammatic ‘Firehand’ Nixon.
Josh Millard Said,
October 5, 2007 @ 2:36 pm
I have to say, ‘histogramas esteganográficos autorreferentes’ has a nice ring to it.
Josh Millard Said,
October 5, 2007 @ 2:53 pm
Oh my crappin’ pants, JWZ noticed this. Hiya, Jamie.
twentynine Said,
October 5, 2007 @ 3:01 pm
more like Adolf Millard
Josh Millard Said,
October 5, 2007 @ 3:05 pm
more like twentynein amirite
gbritton Said,
October 5, 2007 @ 5:54 pm
This is pretty cool, but that photo isn’t the Miami skyline, it’s the
Boston skyline.
nickf Said,
October 5, 2007 @ 7:11 pm
Hey thanks for the props there Josh, but I think yours beats mine hands down. I saw the title of today’s article on Ironic Sans and was like “he’s talking about me!” but when I saw yours, I was like “daaaaamn”. Great work.
Josh Millard Said,
October 5, 2007 @ 9:26 pm
Boston? Seriously? I’m so firing my fact checker. Thanks for the heads up, gbritton.
Nick: thanks. It’s worth noting that I did what you did as a first step—I was producing gradients as a sanity check before I worked out the alter-in-place routine to keep the photo looking right.
Dennis Said,
October 6, 2007 @ 6:33 pm
Both perl scripts in the working directory are returning
{ Error 404 }
Page Not Found
when viewed or downloaded.
Josh Millard Said,
October 6, 2007 @ 7:43 pm
Yeah, I’ve got something kind of fucked in my .htaccess config, I think. The __code* items in the directory are copies of the respective scripts, for easy perusin’.
Josh Millard Said,
October 7, 2007 @ 9:58 am
Huh. Interesting notion from greatbiggary over on JWZ’s livejournal post: use same-intensity, different-hue pixels to paint a visible picture that would completely lack histogram variance: b&w intensity histogram would just be a single spike, with all the visual information spread out across the separate RGB (or CMYK or whatever you prefer) channels.
Hmm.
Josh Millard Said,
October 7, 2007 @ 10:01 am
And as toy steganography goes, that could be fun and slightly subtle: encode the true information in your image in the hue-varying pixels of a given intensity x, and fill in the rest of the picture with a plausible range of other intensities. Isolating that one level would give you the reveal, but otherwise the information wouldn’t be obvious.
Making that work from an arbitrary starting point could be interesting.
digi dude Said,
October 8, 2007 @ 10:24 pm
Very creatve, i’d say. The histogram looks good, and the image is not bad as well
Ahruman Said,
October 9, 2007 @ 5:58 am
I demand that this technique be named “steganobargraphy”.
Histograma subliminar at 100nexos Said,
October 9, 2007 @ 5:23 pm
[…] Josh Millard levou a idéia adiante e criou a imagem abaixo: O histograma dessa imagem revela o mesmo perfil da cidade! […]
schmartin Said,
October 10, 2007 @ 4:51 am
Hi,
as written above, it is not possible to download the perlscript :-(
Could you send them by e-mail?
Thanks
schmartin
Josh Millard Said,
October 10, 2007 @ 10:14 am
To be clear, you can grab the perlscript here.
Jim Bumgardner Said,
October 12, 2007 @ 3:15 pm
Hey Josh,
Thought you might like this image, which contains the complete text of “Moby Dick”.
http://www.flickr.com/photos/krazydad/257804202/
Chronillogical » Blog Archive » Cool Stuff Said,
October 12, 2007 @ 6:48 pm
[…] 1) Embedding images in histograms. […]
Josh Millard Said,
October 12, 2007 @ 8:24 pm
That’s really great, Jim.
Entdecke das versteckte Bild | Sonstiges Said,
October 15, 2007 @ 12:30 pm
[…] Josh Millard hat das Thema aufgegriffen und übertrumpft das Original. Das folgende Bild ist nicht die […]
The AV Club Blog » Blog Archive » What Is This A Picture Of? Said,
October 26, 2007 @ 10:41 am
[…] wuss. IF you figure it out, or cheat and look at the back of the book for the answers, then go here to see how Josh Millard has taken this idea to the next level. Image manipulation like this is […]
Hidden image « Fish Piper Said,
October 27, 2007 @ 6:48 am
[…] more takes on a similar idea, check out the work of Josh Millard, who’s taken the idea and raised […]
links for 2007-10-26 at toshism Said,
November 14, 2007 @ 4:32 pm
[…] Josh Millard Speaks! :: Retro-Histo: making an image fit your histogram! (tags: histogram photoshop images photography perl technology cool hack image processing programming) […]
stitch » blown highlights Said,
November 23, 2007 @ 4:29 pm
[…] fun with histograms […]
Share… » Histogram as Image Said,
November 24, 2007 @ 9:13 am
[…] Josh Millar took the idea further and created this one, which has the same skyline […]
Josh Millard Speaks! :: Hex, leet, and constrained alphabets - for me3dia Said,
March 1, 2008 @ 10:38 am
[…] simple stuff, in the end — it’s no histogram steganography, certainly — but a fun little Saturday morning project. Thanks for the fun, Mr. […]