fast window/level - DICOM
This is a discussion on fast window/level - DICOM ; hello all,
I've been trying to improve the window/leveling speed in my DICOM
viewing application. It was suggested to me that using a lookup table
could improve performance, but even using LUTs my interaction
responsiveness when the images are about ...
-
fast window/level
hello all,
I've been trying to improve the window/leveling speed in my DICOM
viewing application. It was suggested to me that using a lookup table
could improve performance, but even using LUTs my interaction
responsiveness when the images are about 100x1000 pixels and greater
becomes sluggish.
I found this website, which does a 'type' of window/leveling, very
fast. I was wondering if anyone had any opinions on it:
http://homepages.borland.com/efg2lab...ngPalettes.htm
Thanks
-
Re: fast window/level
After reading the article some more, it seems the author knows that a
range of only 256 colors can be displayed on the monitor at any time,
so the bitmap that is drawn to screen uses a lookup table of 256
colors.
Do you think this is ok to do? Calculate the 256 possible grey values
that will be used after the user changes window/level in the palette
LUT, and that is it? It would be very fast.
-
Re: fast window/level
Depending on the platform and system configuration you're designing for, you
may be able to perform the operation in video hardware. It can be
implemented as a fragment/pixel shader for good performance and quality. If
you'd rather avoid DirectX/OpenGL, you'll need to use a different approach.
Ben Carruthers
"markww" wrote in message
news:1127940321.004717.213440@g49g2000cwa.googlegr oups.com...
> hello all,
>
> I've been trying to improve the window/leveling speed in my DICOM
> viewing application. It was suggested to me that using a lookup table
> could improve performance, but even using LUTs my interaction
> responsiveness when the images are about 100x1000 pixels and greater
> becomes sluggish.
>
> I found this website, which does a 'type' of window/leveling, very
> fast. I was wondering if anyone had any opinions on it:
>
> http://homepages.borland.com/efg2lab...ngPalettes.htm
>
>
> Thanks
>
-
Re: fast window/level
Yeah I tried taking the opengl route which was running fine, but I was
plagued by different users' not having up to date drivers, incompatible
graphics boards, etc etc. It was a real nightmare. So I'm trying to
rewrite sans 3d hardware support. Fast window leveling is the last
piece I need to reimplement.
After investigating some more last night, I'm wondering, how does one
perform window/leveling on a color image? The formula for the operation
on a greyscale image is straightforward - in color images, do we just
perform the window/level on each individual color channel per pixel?
Thanks
Ben Carruthers wrote:
> Depending on the platform and system configuration you're designing for, you
> may be able to perform the operation in video hardware. It can be
> implemented as a fragment/pixel shader for good performance and quality. If
> you'd rather avoid DirectX/OpenGL, you'll need to use a different approach.
>
> Ben Carruthers
>
>
>
>
> "markww" wrote in message
> news:1127940321.004717.213440@g49g2000cwa.googlegr oups.com...
> > hello all,
> >
> > I've been trying to improve the window/leveling speed in my DICOM
> > viewing application. It was suggested to me that using a lookup table
> > could improve performance, but even using LUTs my interaction
> > responsiveness when the images are about 100x1000 pixels and greater
> > becomes sluggish.
> >
> > I found this website, which does a 'type' of window/leveling, very
> > fast. I was wondering if anyone had any opinions on it:
> >
> > http://homepages.borland.com/efg2lab...ngPalettes.htm
> >
> >
> > Thanks
> >
-
Re: fast window/level
Correct.
R value->WL_LUT(0-255)->R screen
G value->WL_LUT(0-256)->G screen
B value->WL_LUT(0-255)->B screen
> After investigating some more last night, I'm wondering, how does one
> perform window/leveling on a color image? The formula for the operation
> on a greyscale image is straightforward - in color images, do we just
> perform the window/level on each individual color channel per pixel?
-
Re: fast window/level
Hi Somchai,
You had recommended to me in an earlier post to use lookup tables to
speed up window leveling. This did give me a boost up until about
1000x1000 pixels, then it starts getting slow again. Do you do any
other tricks to keep the window/leveling fluid? I'm not sure whatever
tricks are left! I was thinking about taking advantage of Intel's MMX
to possibly do the window level equation or setting multiple pixels at
a time in parallel.
Thanks!
-
Re: fast window/level
Have you identifed where the performance bottle neck is?
Computing display value of 1000x1000 pixels may not be
the slower part in the display chain. I don't know how you
put the pixels on the screen, but I would look deeper into that.
I am not sure if MMX is going to help much. The time to
pack and unpack pixels into MMX registers before you
can process them in parallel is significant. This, of course,
depends on the data structure.
> You had recommended to me in an earlier post to use lookup tables to
> speed up window leveling. This did give me a boost up until about
> 1000x1000 pixels, then it starts getting slow again. Do you do any
> other tricks to keep the window/leveling fluid? I'm not sure whatever
> tricks are left! I was thinking about taking advantage of Intel's MMX
> to possibly do the window level equation or setting multiple pixels at
> a time in parallel.
-
Re: fast window/level
Hmm good point on the MMX. My method for setting the pixels should be
haldway decent, I'm modifying the direct pixel bits of a DIB. I'll look
if I can find bottlenecks in that. What kind of performance do you have
with your method? At what image size do you start to notice a slow down?
-
Re: fast window/level
I just tried adjusting win/lev on a 16-bit CR image of 2010x1670
at 100% without any noticible slow down.
The display mode was 1800 x 1440 (max resolution on system)
with 32-bit color, so the image was slighly clipped aroung the corner.
I do the same by putting directly into a DIB.
"markww" wrote in message
news:1128024363.948203.30870@g49g2000cwa.googlegro ups.com...
> Hmm good point on the MMX. My method for setting the pixels should be
> haldway decent, I'm modifying the direct pixel bits of a DIB. I'll look
> if I can find bottlenecks in that. What kind of performance do you have
> with your method? At what image size do you start to notice a slow down?
>
-
Re: fast window/level
Hi Somchai,
For my window level operation, I've been doing the calculation off the
source image like:
img_src = // unchanging pixel buffer, original image data.
img_dst = // destination DIB, gets its pixels modified due to
window/level.
img_lut = // 256 or 65536 entry LUT for speedup.
void OnWindowLevelChange()
{
// calculate LUT.
for (int i = 0; i < 65536; i++) {
img_lut[i] = ...;
}
// Now map each pixel in the image through the LUT.
for (int i = 0; i < num_pixels; i++) {
img_dst[i] = img_lut[img_src[i]];
}
}
Now I just read another post in which the author says they do the
operations off the display image itself! If I try that, it goes very
fast but of course the window leveling looks all messed up because the
errors are compounding. Is the model above what you do too? Then at
least I will know the bottleneck is truly in the DIB write operations.
Thanks so much
Somchai K wrote:
> I just tried adjusting win/lev on a 16-bit CR image of 2010x1670
> at 100% without any noticible slow down.
> The display mode was 1800 x 1440 (max resolution on system)
> with 32-bit color, so the image was slighly clipped aroung the corner.
>
> I do the same by putting directly into a DIB.
>
> "markww" wrote in message
> news:1128024363.948203.30870@g49g2000cwa.googlegro ups.com...
> > Hmm good point on the MMX. My method for setting the pixels should be
> > haldway decent, I'm modifying the direct pixel bits of a DIB. I'll look
> > if I can find bottlenecks in that. What kind of performance do you have
> > with your method? At what image size do you start to notice a slow down?
> >
-
Re: fast window/level
Have you tried using pointers? It might help.
blah *psrc = img_src;
blah *pdst = img_dst;
for (int i = 0; i < num_pixels; i++) {
*(pdst++) = img_lut[*(psrc++)];
}
"markww" wrote in message
news:1128038961.840717.260710@g14g2000cwa.googlegr oups.com...
> Hi Somchai,
>
> For my window level operation, I've been doing the calculation off the
> source image like:
>
> img_src = // unchanging pixel buffer, original image data.
> img_dst = // destination DIB, gets its pixels modified due to
> window/level.
> img_lut = // 256 or 65536 entry LUT for speedup.
>
> void OnWindowLevelChange()
> {
> // calculate LUT.
> for (int i = 0; i < 65536; i++) {
> img_lut[i] = ...;
> }
>
> // Now map each pixel in the image through the LUT.
> for (int i = 0; i < num_pixels; i++) {
> img_dst[i] = img_lut[img_src[i]];
> }
> }
>
> Now I just read another post in which the author says they do the
> operations off the display image itself! If I try that, it goes very
> fast but of course the window leveling looks all messed up because the
> errors are compounding. Is the model above what you do too? Then at
> least I will know the bottleneck is truly in the DIB write operations.
>
> Thanks so much
>
> Somchai K wrote:
> > I just tried adjusting win/lev on a 16-bit CR image of 2010x1670
> > at 100% without any noticible slow down.
> > The display mode was 1800 x 1440 (max resolution on system)
> > with 32-bit color, so the image was slighly clipped aroung the corner.
> >
> > I do the same by putting directly into a DIB.
> >
> > "markww" wrote in message
> > news:1128024363.948203.30870@g49g2000cwa.googlegro ups.com...
> > > Hmm good point on the MMX. My method for setting the pixels should be
> > > haldway decent, I'm modifying the direct pixel bits of a DIB. I'll
look
> > > if I can find bottlenecks in that. What kind of performance do you
have
> > > with your method? At what image size do you start to notice a slow
down?
> > >
>
-
Re: fast window/level
Ahh that's it. That made all the difference actually. Previously I was
calculating the index and all that
something that looks like this:
for (int y = 0; y < 256; y++) {
for (int x = 0; x < 256; x++) {
int nPixIdx = y * 256 + x;
pDst[nPixIdx] = pSrc[nPixIdx];
}
}
Just doing the ++ on the bits pointers makes it extremely fluid even at
these large image sizes.
Thanks for helping me through all this Somchai, I really appreciate it.
Mark