ipp - 将浮点矩阵转换为 rgb

ipp - Converting float matrix to rgb

我编写了以下代码来让 IPP 调整矩阵的大小:

#include "ipp_mx.h"
#include "ipp.h"

#include "stdafx.h"
#define IPPCALL(name) name

int main()
{
    IppiSize srcSize = { 3,3 };
    float srcImage[9] =
    { 20, 40, 30,
      35, 55, 70,
      100, 30, 20 };
    float* src = new float[srcSize.width*srcSize.height];
    for (int i = 0; i < srcSize.width*srcSize.height; i++) {
        src[i] = srcImage[i];
    }
    double xFactor = 10; double yFactor = 10;

    int numChannels = 1;
    int bytesPerPixel = 4;
    int srcStep = srcSize.width*bytesPerPixel*numChannels;
    IppiRect srcRoi = { 0, 0, srcSize.width, srcSize.width };

    float* dest = new float[srcSize.width*srcSize.height*xFactor*yFactor];
    IppiSize destSize = { srcSize.width*xFactor, srcSize.height*yFactor };
    int destStep = destSize.width*bytesPerPixel*numChannels;
    IppiRect destRoi = { 0, 0, destSize.width, destSize.width };

    double xShift = 0; double yShift = 0;

    int interpolation = 1; //nearest neighbour

    int bufSize;
    IPPCALL(ippiResizeGetBufSize)(srcRoi, destRoi, 1, interpolation, &bufSize);
    unsigned char* buffer = new unsigned char[bufSize];

    IPPCALL(ippiResizeSqrPixel_32f_C1R)(src, srcSize, srcStep, srcRoi, dest, destStep, destRoi, xFactor, yFactor, xShift, yShift, interpolation, buffer);
    return 0;
}

是否有我可以使用的 IPP 函数,它现在可以将此浮点矩阵 dest 转换为 RGB24 格式,给定颜色图?

我知道我可以在 for 循环中手动完成,但我想要处理的原始矩阵要大得多,for 循环可能无法削减它。

我发现有效的技术包括 3 个步骤:

  1. Convert/truncate 浮点值到无符号字符 - 在我的例子中,输入值在 8 位范围内,我不关心十进制数。
  2. 将 unsigned char 值转换为 3 通道 RGB 灰度,这实际上将相同的输入值分配给所有 3 个通道。
  3. 构造一个调色板以将 3 个通道值映射到另外 3 个通道值。
  4. 将调色板和输入值传递给查找 table 函数。

这在下面的代码中进行了演示。请注意,我的调色板设置为为 30 以下的值分配绿色,为大于或等于 30 的值分配蓝色。

unsigned char** GeneratePalette()
{
    unsigned char red[256];
    unsigned char green[256];
    unsigned char blue[256];

    for(int value = 0; value < 256; value++)
    {
        if(value < 30)
        {
            red[value] = 0;
            green[value] = 255;
            blue[value] = 0;
        }
        else
        {
            red[value] = 0;
            green[value] = 0;
            blue[value] = 255;
        }
    }

    unsigned char* table[3] = { red, green, blue };
    return table;
}

void Test()
{
    unsigned char** palette = GeneratePalette();
    IppiSize srcSize = { 2,1 };
    float src[2] = { 54, 19 };
    unsigned char truncated[2];

    IPPCALL(ippiConvert_32f8u_C1R)(src, srcSize.width * sizeof(float), truncated, srcSize.width * sizeof(unsigned char), srcSize, ippRndZero);
    unsigned char copied[6] = {0};
    IPPCALL(ippiGrayToRGB_8u_C1C3R)(truncated, srcSize.width * sizeof(unsigned char), copied, srcSize.width * sizeof(unsigned char) * 3, srcSize);
    unsigned char dest[6];

    IPPCALL(ippiLUTPalette_8u_C3R)(copied, 6, dest, 6, srcSize, palette, 8);
}

int main()
{
    Test();
    return 0;
}

最后,这不是很有效,并且处理单个 for 循环更快。