16 bit 的灰度图如何在QT中显示
用Mat构造的 16 bit 灰度图 无法直接显示,需要转换成 8 bit 的灰度图在QT中显示,
使用OpenCV自带的最大最小值归一法,
将16 bit的值map到8 bit,但是会有memory access violation 的错误,想了一想,应该还是Mat中存放像素数据的内存空间,前后不一致了,从16 bit(ushort) 变成了 8 bit(uchar),所以内存访问出现错误。
以下函数其实和上面的函数是一样的功能
void normalizeMat(const cv::Mat& source, cv::Mat& dest, quint8 minv, quint8 maxv) { int cols = source.cols; int rows = source.rows; for (int k = 0; k < rows; k++) { const ushort* matRowPtr = source.ptr<ushort>(k); quint8* destMatRowPtr = dest.ptr<quint8>(k); for (int j = 0; j < cols; j++) { quint8 pixData = static_cast<quint8>((*matRowPtr++ - minv) / (maxv - minv) * 255); *destMatRowPtr++ = pixData; } } }想要正确显示,先构造RGB888的image, 把16 bit的像素值采用最大最小化方法映射到8 bit,填满三个通道(三个通道值是一样的)。
QPixmap convert8to16uc1(const cv::Mat& source) { double minv = 0, maxv = 0; Point minLoc(0, 0), maxLoc(0, 0); cv::minMaxLoc(source, &minv, &maxv, &minLoc, &maxLoc); quint16* pSource = (quint16*)source.data; int pixelCounts = source.cols * source.rows; QImage dest(source.cols, source.rows, QImage::Format_RGB888); quint8* pDest = (quint8*)dest.bits(); for (int i = 0; i < pixelCounts; i++) { //quint8 value = (quint8)((*(pSource)) >> 8); //quint8 value = static_cast<quint8>((*pSource - minv) / (maxv - minv) * 255); quint8 value = static_cast<quint8>(floor(((*pSource - minv) / (maxv - minv) * 255))); *(pDest++) = value; // B *(pDest++) = value; // G *(pDest++) = value; // R pSource++; } return QPixmap::fromImage(dest); }