16 bit 的灰度圖如何在QT中顯示

用Mat構造的 16 bit 灰度圖 無法直接顯示,需要轉換成 8 bit 的灰度圖在QT中顯示,

使用OpenCV自帶的最大最小值歸一法,

cv::normalize(inMat, inMat2, 0., 255., cv::NORM_MINMAX, CV_8UC1)

將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); }