Results 1 to 15 of 15

Thread: Tiff in unsigned short

  1. #1
    Join Date
    Apr 2006
    Posts
    14
    Qt products
    Qt4
    Platforms
    Windows

    Default Tiff in unsigned short

    Hi,

    I got a tiff image already converted to unsigned short*.
    How can I display the image from the unsigned short* in QT?
    I am using QT4.1.

    Thank you....

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Tiff in unsigned short

    Quote Originally Posted by spawnwj
    Hi,

    I got a tiff image already converted to unsigned short*.
    Why not unsigned char*?

    How can I display the image from the unsigned short* in QT?
    What does the bitmap contain? Only the pixell data? If so, then you can use QImage::bits() to access QImage pixell storage and copy the data there.

  3. #3
    Join Date
    Apr 2006
    Posts
    14
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Tiff in unsigned short

    Quote Originally Posted by wysota
    Why not unsigned char*?


    What does the bitmap contain? Only the pixell data? If so, then you can use QImage::bits() to access QImage pixell storage and copy the data there.
    The image comes in unsigned short*. I can't do anything about that.
    I think if it is in unsigned char* we can load it directly into QPixel or QImage right?


    Hm... I have to check if the bitmap only contain pixel data.
    Any hints on how to do this?

    I am new to image processing so I do not really know how to proceed from here.

    Thanks

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Tiff in unsigned short

    Where did you get those ushort* from? Ask the author what they contain But it should still be uchar*, because ushort can be 16 bits long and uchar is always 8bits.

  5. #5
    Join Date
    Apr 2006
    Posts
    14
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Tiff in unsigned short

    Quote Originally Posted by wysota
    Where did you get those ushort* from? Ask the author what they contain But it should still be uchar*, because ushort can be 16 bits long and uchar is always 8bits.
    Hi....

    The images I am getting is 16 bit greyscale image converted from tiff. It is more for image processing. But I just need to display it in QT. Can anyone tell me how I can go about doing it?
    The images comes in ushort*. Therefore I do not know how I can display it.

    Thanks

  6. #6
    Join Date
    Jan 2006
    Location
    Russia
    Posts
    50
    Thanked 2 Times in 2 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Tiff in unsigned short

    You should convert a 16bit raster to the 8bit raster. After that you will be able to show this image through Qt's classes.
    Here is a simple function for converting 16 to 8 bit.
    Qt Code:
    1. // data - the souce 16bit raster
    2. // dest - the destination 8bit raster
    3. // len - raster length (width * height)
    4. template<typename T>
    5. bool conv16to8bit(const T * const data, unsigned char * const dest, unsigned len)
    6. {
    7. if ( !data || !dest || !len ) return false;
    8.  
    9. size_t type_size = sizeof(T);
    10. if ( type_size != 2 ) return false;
    11.  
    12. bool isSigned = ( typeid(T) == typeid(signed short) );
    13.  
    14. T minValue = ( isSigned ?
    15. static_cast<T>(::pow(2, type_size * 8 - 1)/2)-1 :
    16. static_cast<T>(::pow(2, type_size * 8 - 1)) );
    17. T maxValue = ( isSigned ? static_cast<T>(::pow(2, type_size * 8 - 1)/2) * (-1) : 0 );
    18.  
    19. for (const T * pix = data; pix < data+len; pix++)
    20. {
    21. if ( *pix < minValue ) minValue = *pix;
    22. if ( *pix > maxValue ) maxValue = *pix;
    23. }
    24.  
    25. const char VBLACK = 16;
    26. float K = (4096.f * ( 256 - VBLACK )) / ( maxValue - minValue );
    27. float B = minValue * K / 4096.f - VBLACK;
    28.  
    29. unsigned char * dst = dest;
    30. for (const T * pix = data; pix < data+len; pix++)
    31. {
    32. int c = static_cast<int>( 0.5f + (::abs(*pix) * K / 4096 - B));
    33. if ( c < 0 ) c = 0;
    34. if ( c > 255 ) c = 255;
    35. *dst++ = static_cast<unsigned char>(c);
    36. }
    37.  
    38. return true;
    39. };
    To copy to clipboard, switch view to plain text mode 

  7. #7
    Join Date
    Apr 2006
    Posts
    14
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Tiff in unsigned short

    void CMMMGui::setImageInGUI(ushort* image, int page)
    {

    uchar* finalImage = new uchar[300 * 300];
    _conv16to8bit(image, finalImage, 90000);

    QImage img = QImage(finalImage,300,300,QImage::Format_ARGB32);

    QPixmap pix = QPixmap(300,300);
    ui.label_Photo->setPixmap( QPixmap::fromImage( img ) );
    }

    Thanks for the code.
    I have tried to call your function to convert it to 8bit. The image is looking slightly better. But still not the same image yet
    Anything I do wrong here?

    I think there is something wrong with the format define in the QImage. I cant seem to get a right one for it.
    QImage img = QImage(finalImage,300,300,QImage::Format_ARGB32);

    Thanks



    Quote Originally Posted by Mad Max
    You should convert a 16bit raster to the 8bit raster. After that you will be able to show this image through Qt's classes.
    Here is a simple function for converting 16 to 8 bit.
    Qt Code:
    1. // data - the souce 16bit raster
    2. // dest - the destination 8bit raster
    3. // len - raster length (width * height)
    4. template<typename T>
    5. bool conv16to8bit(const T * const data, unsigned char * const dest, unsigned len)
    6. {
    7. if ( !data || !dest || !len ) return false;
    8.  
    9. size_t type_size = sizeof(T);
    10. if ( type_size != 2 ) return false;
    11.  
    12. bool isSigned = ( typeid(T) == typeid(signed short) );
    13.  
    14. T minValue = ( isSigned ?
    15. static_cast<T>(::pow(2, type_size * 8 - 1)/2)-1 :
    16. static_cast<T>(::pow(2, type_size * 8 - 1)) );
    17. T maxValue = ( isSigned ? static_cast<T>(::pow(2, type_size * 8 - 1)/2) * (-1) : 0 );
    18.  
    19. for (const T * pix = data; pix < data+len; pix++)
    20. {
    21. if ( *pix < minValue ) minValue = *pix;
    22. if ( *pix > maxValue ) maxValue = *pix;
    23. }
    24.  
    25. const char VBLACK = 16;
    26. float K = (4096.f * ( 256 - VBLACK )) / ( maxValue - minValue );
    27. float B = minValue * K / 4096.f - VBLACK;
    28.  
    29. unsigned char * dst = dest;
    30. for (const T * pix = data; pix < data+len; pix++)
    31. {
    32. int c = static_cast<int>( 0.5f + (::abs(*pix) * K / 4096 - B));
    33. if ( c < 0 ) c = 0;
    34. if ( c > 255 ) c = 255;
    35. *dst++ = static_cast<unsigned char>(c);
    36. }
    37.  
    38. return true;
    39. };
    To copy to clipboard, switch view to plain text mode 

  8. #8
    Join Date
    Jan 2006
    Location
    Russia
    Posts
    50
    Thanked 2 Times in 2 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Tiff in unsigned short

    Try to set to zero a value of the variable VBLACK.

  9. #9
    Join Date
    Apr 2006
    Posts
    14
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Tiff in unsigned short

    I have updated the code as shown below...
    I can see the full image now but it is rotated anticlockwise 90 degree....
    Any idea why?

    Thanks


    uchar* finalImage = new uchar[300*300];
    _conv16to8bit(image, finalImage, 90000);

    QImage img(300, 300,QImage::Format_Indexed8);
    img.setNumColors(256);
    for(int i = 0; i <= 255; i++)
    {
    int myColor = qRgb(i, i, i);
    img.setColor(i, myColor);
    }

    for(int i = 0; i<300; i++)
    for(int j = 0; j<300; ++j)
    img.setPixel(i, j, finalImage[(i*300)+j]);

    ui.label_Photo->setPixmap( QPixmap::fromImage( img ) );

  10. #10
    Join Date
    Apr 2006
    Posts
    14
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Tiff in unsigned short

    Quote Originally Posted by spawnwj
    for(int i = 0; i<300; i++)
    for(int j = 0; j<300; ++j)
    img.setPixel(i, j, finalImage[(i*300)+j]);
    Hi the image looks fine now. I just swap i and j at setPixel.
    So far so good.
    Thanks for all the help

  11. #11
    Join Date
    Jan 2006
    Location
    Russia
    Posts
    50
    Thanked 2 Times in 2 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Tiff in unsigned short

    Quote Originally Posted by spawnwj
    I have updated the code as shown below...
    I can see the full image now but it is rotated anticlockwise 90 degree....
    Any idea why?
    I'm surprised with this behaviour. Do you sure that it happened because of the function of convert?

    I want to explain a bit. This function was made only for display of images, not for processing. This algorithm does scale 16bit values to the 8bit range and considers min and max values of pixels at the same time. If you will processing 8bit image and you need to keep the source image as far as possible you should change the algorithm of convert. It should be such as:
    Qt Code:
    1. template<typename T>
    2. bool conv16to8bit(const T * const data, unsigned char * const dest, unsigned len)
    3. {
    4. if ( !data || !dest || !len ) return false;
    5.  
    6. size_t type_size = sizeof(T);
    7. if ( type_size != 2 ) return false;
    8.  
    9. bool isSigned = ( typeid(T) == typeid(signed short) );
    10.  
    11. T maxValue = ( isSigned ?
    12. static_cast<T>(::pow(2, type_size * 8 - 1)/2)-1 :
    13. static_cast<T>(::pow(2, type_size * 8 - 1)) );
    14.  
    15. unsigned char * dst = dest;
    16. for (const T * pix = data; pix < data+len; pix++)
    17. {
    18. int c = static_cast<int>( 0.5f + (::abs(*pix) / maxValue * 255));
    19. if ( c < 0 ) c = 0;
    20. if ( c > 255 ) c = 255;
    21. *dst++ = static_cast<unsigned char>(c);
    22. }
    23.  
    24. return true;
    25. };
    To copy to clipboard, switch view to plain text mode 

    I didn't check this code. May be it has a couple errors.

  12. #12
    Join Date
    Apr 2006
    Posts
    14
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Tiff in unsigned short

    I have further reduce the code to the one below.
    It looks ok without the rotation issue.

    However I got one question...
    If the source is 16 bit, I got a full image with the right size.
    If the source is 8bit, I got a image that is 1/4 of the size and repeat 2 times.
    For example... The actual full image size is defined below.
    1 2
    3 4
    It will have 2 repeating image on 1 and 2 while 3 and 4 is empty.
    Is this normal?




    uchar* finalImage = new uchar[imageSize.width()*imageSize.height()];
    _conv16to8bit(imageData, finalImage, imageSize.width()*imageSize.height());

    QImage img(finalImage, imageSize.width(), imageSize.height(),QImage::Format_Indexed8);
    img.setNumColors(256);
    for(int i = 0; i <= 255; i++)
    {
    int myColor = qRgb(i, i, i);
    img.setColor(i, myColor);
    }

    Quote Originally Posted by Mad Max
    I'm surprised with this behaviour. Do you sure that it happened because of the function of convert?

    I want to explain a bit. This function was made only for display of images, not for processing. This algorithm does scale 16bit values to the 8bit range and considers min and max values of pixels at the same time. If you will processing 8bit image and you need to keep the source image as far as possible you should change the algorithm of convert. It should be such as:
    Qt Code:
    1. template<typename T>
    2. bool conv16to8bit(const T * const data, unsigned char * const dest, unsigned len)
    3. {
    4. if ( !data || !dest || !len ) return false;
    5.  
    6. size_t type_size = sizeof(T);
    7. if ( type_size != 2 ) return false;
    8.  
    9. bool isSigned = ( typeid(T) == typeid(signed short) );
    10.  
    11. T maxValue = ( isSigned ?
    12. static_cast<T>(::pow(2, type_size * 8 - 1)/2)-1 :
    13. static_cast<T>(::pow(2, type_size * 8 - 1)) );
    14.  
    15. unsigned char * dst = dest;
    16. for (const T * pix = data; pix < data+len; pix++)
    17. {
    18. int c = static_cast<int>( 0.5f + (::abs(*pix) / maxValue * 255));
    19. if ( c < 0 ) c = 0;
    20. if ( c > 255 ) c = 255;
    21. *dst++ = static_cast<unsigned char>(c);
    22. }
    23.  
    24. return true;
    25. };
    To copy to clipboard, switch view to plain text mode 

    I didn't check this code. May be it has a couple errors.

  13. #13
    Join Date
    Jan 2006
    Location
    Russia
    Posts
    50
    Thanked 2 Times in 2 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Tiff in unsigned short

    Quote Originally Posted by spawnwj
    Is this normal?
    Yes, I think this is normal behaviour for this function. I never used it in such way. It seems you've too much oversimplified my function. In original it checks the dimension of source type. Just don't use this function for 8bit images.

  14. #14
    Join Date
    Feb 2006
    Location
    Boulder, Colorado, USA
    Posts
    63
    Thanked 8 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Tiff in unsigned short

    you might want to check out TiffIO as well.

  15. #15
    Join Date
    Apr 2006
    Posts
    14
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Tiff in unsigned short

    Quote Originally Posted by jrideout
    you might want to check out TiffIO as well.
    Thanks... I got that in my system.
    But my source is already converted to ushort*. I can only start working for there.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.