【问题标题】:Convert 16bit QImage to 8bit unsigned char in QT在 QT 中将 16 位 QImage 转换为 8 位无符号字符
【发布时间】:2011-06-11 04:07:44
【问题描述】:

我想弄清楚如何将图像从 uint16 转换为 uint8。我基本上必须以浮点数读取图像,并且需要以无符号字符显示它。

我有以下几点:

   float two_eight =  pow(2.0,8);
   float two_sixteen = pow(2.0,16);
    QImage *qi = new QImage(imwidth, imheight, QImage::Format_RGB32);
        for (int i = 0 ; i < imheight ; i++)
        {
             for (int j = 0 ; j < imwidth ; j++)
             {
                    floatData[i*imwidth+j] = (two_eight* floatData[i*imwidth+j])/two_sixteen;
                    qi->setPixel(j,i,qRgb((unsigned char)floatData[i*imwidth+j],(unsigned char)floatData[i*imwidth+j],(unsigned char)floatData[i*imwidth+j]));


             }
         }

在 Qt 中是否有更好的方法来执行此操作?

【问题讨论】:

    标签: c++ image qt image-processing


    【解决方案1】:

    如果我正确理解您的问题,您会得到一个 RGB 格式的图像,其中每个颜色分量都是 16 位,并且您想使用 QImage 加载它。

    你可以这样做:

    std::vector< unsigned short int > inData;
    // load the data into a vector
    std::vector< unsigned char > outData( inData.size(), 0 );
    std::transfrorm( inData.begin(), inData.end(), outData.begin(), Convert );
    // create the image object
    QImage image( &outData[0],imwidth, imheight, QImage::Format_RGB32 );
    

    Convert 函数的定义如下:

    unsigned char Convert( const unsigned short int v )
    {
      return v >> 8;
    }
    

    【讨论】:

    • QImage 不支持每通道 16 位图像 :)
    • @vines 我知道,这就是为什么我首先将 16 位数据(存储在 inData 向量中)转换为 8 位数据(outData 向量),然后再使用 8 位创建 QImage数据。
    • +1 是一个不错的答案,但是,事实证明我的实际问题是每个像素使用的实际位数是 11。虽然它是在 16 位结构中分配的,所以这很烦人.
    【解决方案2】:

    imdata 是你的 16 位图像缓冲区

    #include <cstdint>    
    uint16_t *imdata;
    
        for (int i = 0 ; i < imheight ; ++i)
                {
                     //preincrement, is faster than post
                     for (int j = 0 ; j < imwidth ; ++j)
                     {
                            //imdata[i*imwidth+j]>>8 removes least significant 8bits
                            //imdata has one added to adjust for components
                            qi->setPixel(j,i,qRgb((uint8_t)(imdata[i*imwidth+j]>>8),(uint8_t)(imdata[i*imwidth+j+1]>>8),(uint8_t)(imdata[i*imwidth+j+2]>>8)));
    
    
                     }
                 }
    

    【讨论】:

    • preincrement 比 post 快?!当然——如果编译器无权做一些简单的优化。对于生产代码,在普通编译器上编译,二进制没有区别。
    • 我也认为它看起来更好,所以我下意识地这样做了;)除此之外,我们不知道正在使用什么编译器。我注意到这个微小的变化对 LLVM 和 GCC 编译器产生了可证明的差异,并且它不像预增量那样会更慢。
    • 肯定会比问题中发布的内容更快。但是您仍然在 2 个 for 循环中设置每个像素的像素。这也是这种方法的坏处
    • 即使使用-OS-O2?如果速度真的很重要:常规for-loops 中的i &lt; imheight 可以与i != imheight 交换。因此,您通常会在汇编程序级别上进行一次减法。
    猜你喜欢
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    • 2016-04-12
    • 1970-01-01
    • 2013-03-18
    • 2020-07-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多