Re: Displaying a Pixmap




On Feb 25, 2007, at 2:52 PM, Scott White wrote:

I am writing an application that reads medical imaging files (CT, MRI, etc in DICOM format) and simply displays them. However, I am having trouble using Gtk2::Gdk::Pixmap. I must use a pixmap since DICOM images are usually 16-bit, and almost always grayscale.
[...]
Unfortunately, I cannot make use of the much simpler pixbuf, since it only supports 8-bit pixels.

Stop right there. GdkPixmap's option for 16 on the bits-per-pixel has nothing to do with what you're doing here.

GdkPixmap is a wrapper for XPixmap, which is a server-side resource. The pixel data is at the server's resolution and bitdepth. When you think of a 16-bit pixmap, you are usually talking about packed 16-bit RGB data, or possibly 16-bit indexed color. This is very, very different from a 16-bit grayscale image.

A 16-bit grayscale image contains grayscale data with 64k possible shades -- 256 times as much information as 8-bit data. You monitor can't show you this much detail, and your video card deals only with 8 bits per channel (8 x 3 = 24, sometimes with an unused padding byte for 32), so in order to display this image, you *must* mangle it to 8- bits-per-channel somehow. The art it is how you choose to compress the dynamic range to make it visible.

The very simplest thing you can do is just show the most significant byte of each pixel. That is:

       foreach pixel
               output = input >> 8

or

       $data = pack "C*", map { $_ >> 8 } unpack "S*", $raw;

(To display this in a native GdkPixbuf, you'd have to explode that to 24-bit by replicating each pixel three times, which rather sucks, memory-wise. The method draw_gray_image() on Gtk2::Gdk::Drawable would allow you not to have to expand your memory usage like this, but would require you to write your own image display widget.)

If the image uses its full dynamic range, you'll be able to see *something*.

However, it's often the case that 16-bit images don't use the full spectrum. If you get a histogram, you may see hotspots in different parts of the spectrum. You might also be losing the detail that you really need to see. So, to be really fancy, you'd use different algorithms to map the 16-bit data to 8-bit. That's where the fun comes in... gamma curves, sliders for the top and bottom of the selected portion of the dynamic range, etc, etc.


Here's a quick, very crappy example of a few different ways you can mangle the data. Anything truly good will require more finesse than i was willing to put into 130 lines of code. :-)


Attachment: map16.pl
Description: Text Data




--
It's all very complicated and would take a scientist to explain it.
  -- MST3K




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]