Where did you get those ushort* from? Ask the author what they containBut it should still be uchar*, because ushort can be 16 bits long and uchar is always 8bits.
Where did you get those ushort* from? Ask the author what they containBut it should still be uchar*, because ushort can be 16 bits long and uchar is always 8bits.
Hi....Originally Posted by wysota
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
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:
// data - the souce 16bit raster // dest - the destination 8bit raster // len - raster length (width * height) template<typename T> bool conv16to8bit(const T * const data, unsigned char * const dest, unsigned len) { if ( !data || !dest || !len ) return false; size_t type_size = sizeof(T); if ( type_size != 2 ) return false; bool isSigned = ( typeid(T) == typeid(signed short) ); T minValue = ( isSigned ? static_cast<T>(::pow(2, type_size * 8 - 1)/2)-1 : static_cast<T>(::pow(2, type_size * 8 - 1)) ); T maxValue = ( isSigned ? static_cast<T>(::pow(2, type_size * 8 - 1)/2) * (-1) : 0 ); for (const T * pix = data; pix < data+len; pix++) { if ( *pix < minValue ) minValue = *pix; if ( *pix > maxValue ) maxValue = *pix; } const char VBLACK = 16; float K = (4096.f * ( 256 - VBLACK )) / ( maxValue - minValue ); float B = minValue * K / 4096.f - VBLACK; unsigned char * dst = dest; for (const T * pix = data; pix < data+len; pix++) { int c = static_cast<int>( 0.5f + (::abs(*pix) * K / 4096 - B)); if ( c < 0 ) c = 0; if ( c > 255 ) c = 255; *dst++ = static_cast<unsigned char>(c); } return true; };To copy to clipboard, switch view to plain text mode
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
Originally Posted by Mad Max
Try to set to zero a value of the variable VBLACK.
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 ) );
Hi the image looks fine now. I just swap i and j at setPixel.Originally Posted by spawnwj
So far so good.
Thanks for all the help
Originally Posted by spawnwj
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:
template<typename T> bool conv16to8bit(const T * const data, unsigned char * const dest, unsigned len) { if ( !data || !dest || !len ) return false; size_t type_size = sizeof(T); if ( type_size != 2 ) return false; bool isSigned = ( typeid(T) == typeid(signed short) ); T maxValue = ( isSigned ? static_cast<T>(::pow(2, type_size * 8 - 1)/2)-1 : static_cast<T>(::pow(2, type_size * 8 - 1)) ); unsigned char * dst = dest; for (const T * pix = data; pix < data+len; pix++) { int c = static_cast<int>( 0.5f + (::abs(*pix) / maxValue * 255)); if ( c < 0 ) c = 0; if ( c > 255 ) c = 255; *dst++ = static_cast<unsigned char>(c); } return true; };To copy to clipboard, switch view to plain text mode
I didn't check this code. May be it has a couple errors.![]()
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);
}
Originally Posted by Mad Max
Yes, I think this is normal behaviour for this function. I never used it in such way.Originally Posted by spawnwj
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.
you might want to check out TiffIO as well.
Thanks... I got that in my system.Originally Posted by jrideout
But my source is already converted to ushort*. I can only start working for there.
Bookmarks