16 bit 的灰度图如何在QT中显示

16 bit 的灰度图如何在QT中显示

用Mat构造的 16 bit 灰度图 无法直接显示,需要转换成8 bit的灰度图在QT中显示(QT 5.12 version中Image没有Gray16的格式,QT 5.15+ 有,但是没有试过)
使用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);

}
posted @ 2021-09-03 18:14  青蛙Frog1228  阅读(1224)  评论(0编辑  收藏  举报