Display RGB HALCON image as QImage
-
Hello,
I am currenty trying to display an RGB HImage as a QImage on my QWidget applications. I have followed the Matching example (\MVTec\halcon-21.11-progress\examples\CPP\Qt\Matching) and I am facing an issue: when I display the image, it zooms into the upper left corner and does not display all the image. Grayscale images display correctly.
Here is what I and doing on the paintEvent, when a grayscale and/or a processed image is signalled:void QHalconWindow::paintEvent(QPaintEvent* ev) { Q_UNUSED(ev); /* What if we change it to a QImage? This has to be made in the new custom widget */ if(_currentHImage.IsInitialized()) { HalconCpp::HString type; Hlong width, height; if(_currentHImage.CountChannels() == 3) { HalconCpp::HImage interleavedImg = _currentHImage.InterleaveChannels("argb", "match", 0); // Only if the image is RGB unsigned char* imgRawPtr = (unsigned char*)interleavedImg.GetImagePointer1(&type, &width, &height); QImage qimage(imgRawPtr, width / 4, height, QImage::Format_RGB32); QPainter painter(this); painter.drawImage(QPoint(0, 0), qimage); } else { unsigned char* imgRawPtr = (unsigned char*)_currentHImage.GetImagePointer1(&type, &width, &height); QImage qimage(imgRawPtr, width, height, QImage::Format_RGB32); QPainter painter(this); painter.drawImage(QPoint(0, 0), qimage); } } }
Halcon does some processing on a 2056x1542 grayscale image by adding a red rectangle on point 10,10 and extending it to point 100,100:
gen_rectangle1(Rectangle, 10, 10, 100, 100) paint_region(...)
Here is the output:
Both QWidget windows are 400x300. On the image we can see that the processed image is zoomed while the original one is not. The only difference is the RGB property of the processing.
Does someone know how to make the processed image the same size as the original one?Thanks,
Rui -
Looks like I was using the wrong format and not scaling the image correctly.
This is the fix:if(_currentHImage.CountChannels().I() == 3) { HalconCpp::HImage interleavedImg = _currentHImage.InterleaveChannels("argb", "match", 0); // Only if the image is RGB unsigned char* imgRawPtr = (unsigned char *)interleavedImg.GetImagePointer1(&type, &width, &height); QImage qimage(imgRawPtr, width / 4, height, width, QImage::Format_RGB32); QImage newqimage = qimage.scaled(400, 300, Qt::KeepAspectRatio); QPainter painter(this); painter.drawImage(QPoint(0, 0), newqimage); } else { unsigned char* imgRawPtr = (unsigned char*)_currentHImage.GetImagePointer1(&type, &width, &height); QImage qimage(imgRawPtr, width, height, QImage::Format_Grayscale8); QImage newqimage = qimage.scaled(400, 300, Qt::KeepAspectRatio); QPainter painter(this); painter.drawImage(QPoint(0, 0), newqimage); } }
Thanks for all your help!
-
Hi and welcome to devnet,
From the looks of it, the type of image changes once you draw on it. When exactly are you drawing that rectangle ? Did you check whether the number of channels is updated after you do that ?
-
Did you check all the values of the modified image ?
-
Compare the CountChannels values, the width and height values.
-
@SGaist I can answer the Width and Height question. When I use the InterleaveChannels method, the width is 4x larger than the original image, while the height stays the same. I tried to divide by 4 when constructing the QImage as shown in the matching example, but no luck.
-
What do you get if using the sizes returned by your interleaved image ?
-
Are you also sure that you choose the correct image format for QImage ?
-
@SGaist said in Display RGB HALCON image as QImage:
What do you get if using the sizes returned by your interleaved image ?
While showing the interleaved image, it is "wider" compared with the screen shot image. I think is due to the fact that the width is 4x higher.
-
This is because instead of an image that contains 3 channels each one containing only R or G or B values, you now have one image that have only 1 channel containing RGBA values. When you get the image pointer you have width*4 that is correct. "width" is not really the image width, is the "bytes per line" in this case.
What happens if you use this QImage contructor?
QImage qimage(imgRawPtr, width / 4, height, width, QImage::Format_RGB32);
-
This is because instead of an image that contains 3 channels each one containing only R or G or B values, you now have one image that have only 1 channel containing RGBA values. When you get the image pointer you have width*4 that is correct. "width" is not really the image width, is the "bytes per line" in this case.
What happens if you use this QImage contructor?
QImage qimage(imgRawPtr, width / 4, height, width, QImage::Format_RGB32);
@ollarch said in Display RGB HALCON image as QImage:
This is because instead of an image that contains 3 channels each one containing only R or G or B values, you now have one image that have only 1 channel containing RGBA values. When you get the image pointer you have width*4 that is correct. "width" is not really the image width, is the "bytes per line" in this case.
What happens if you use this QImage contructor?
QImage qimage(imgRawPtr, width / 4, height, width, QImage::Format_RGB32);
The image is exactly the same as the one on the screenshot, nothing changed.
-
@ollarch said in Display RGB HALCON image as QImage:
Could you try to save the processed image to disk and check it?
I have saved the images using the following code:
_currentHImage.WriteImage("png", 0, "images/himage"); HalconCpp::HImage interleavedImg = _currentHImage.InterleaveChannels("argb", "match", 0); // Only if the image is RGB unsigned char* imgRawPtr = (unsigned char *)interleavedImg.GetImagePointer1(&type, &width, &height); QImage qimage(imgRawPtr, width / 4, height, width, QImage::Format_RGB32); qimage.save("images/qimage.png");
The images are equal! The only problem is showing them on the paint.drawImage....
-
Looks like I was using the wrong format and not scaling the image correctly.
This is the fix:if(_currentHImage.CountChannels().I() == 3) { HalconCpp::HImage interleavedImg = _currentHImage.InterleaveChannels("argb", "match", 0); // Only if the image is RGB unsigned char* imgRawPtr = (unsigned char *)interleavedImg.GetImagePointer1(&type, &width, &height); QImage qimage(imgRawPtr, width / 4, height, width, QImage::Format_RGB32); QImage newqimage = qimage.scaled(400, 300, Qt::KeepAspectRatio); QPainter painter(this); painter.drawImage(QPoint(0, 0), newqimage); } else { unsigned char* imgRawPtr = (unsigned char*)_currentHImage.GetImagePointer1(&type, &width, &height); QImage qimage(imgRawPtr, width, height, QImage::Format_Grayscale8); QImage newqimage = qimage.scaled(400, 300, Qt::KeepAspectRatio); QPainter painter(this); painter.drawImage(QPoint(0, 0), newqimage); } }
Thanks for all your help!
-
Nice !
Since you have it working now, please mark the thread as solved so other forum members may know a solution has been found :-)