16位垫子的查找表高效方式?

Posted

技术标签:

【中文标题】16位垫子的查找表高效方式?【英文标题】:LookUp Table for 16-Bit Mat Efficient way? 【发布时间】:2014-11-24 06:10:49 【问题描述】:

我想使用 opencv 减少 16 位 Mat。我尝试使用 opencv LUT 函数来减少这个垫子。但它似乎不支持 16-Bit Mat。使用 opencv c++ 减少 16 位 Mat 的有效方法是什么?任何帮助表示赞赏!

例如,我想scan & reduce 10 个灰度级的所有像素!我想实现 16 位 Mat 的 opencv 文档中给出的相同示例。

如何通过Pointers访问Mat的各个元素?

【问题讨论】:

你能在这里详细介绍一下“减少”的意思吗? @blackball 我已经更新了我的问题 您可以使用 int 类型的 Mat 构建自己的查找表。 是的,我们可以!但是如何使用指针访问它?你能详细说明你的答案吗? 【参考方案1】:

LUT的源代码在这个文件中:https://github.com/Itseez/opencv/blob/fd59551ff0648d33568d7fc63164bf86c5d3ccb6/modules/core/src/convert.cpp

OpenCV 可以使用多种方法来高效地执行查找表转换:它可以使用英特尔 IPP 库(IppLUTParallelBody_LUTCN 类,用于 3 或 4 通道图像)。如果有Intel IPP,可以直接复制这个类的代码,用ippiLUTPalette_16u_C3R代替ippiLUTPalette_8u_C3R+fix初始化)。

另一种可能的方式是 OpenCL 库(用于 GPU),它是从 ocl_LUT 调用的(抱歉,没有经验,所以我无法提供任何建议)。

或者它使用LUTParallelBody/IppLUTParallelBody_LUTCN 类(对应于单通道和多通道图像)。这些类使用LUT8u_ 模板函数。这里没有火箭科学:它只是迭代图像并替换值。所以你可以简单地复制和粘贴IppLUTParallelBody 并在循环中使用稍微不同的函数。 ParallelLoopBody 基类使用 OpenMP 或 Intel TBB 等库在多个线程中运行循环。我想,您不必修改其中的任何内容即可使其与新功能一起使用。

【讨论】:

【参考方案2】:

感谢您帮助我解决了这个问题! 这是我的基于 16 位查找表的缩减代码。希望这可能对某人有用!

main()

    Size Img_Size(320,240);
    Mat Img_Source_16(Size(320,240),CV_16UC1,Scalar::all(0));
    Mat Img_Destination_16(Size(320,240),CV_16UC1,Scalar::all(0));

    unsigned short LookupTable[4096];
    for (int i = 0; i < 4096; i++)
    
        LookupTable[i]= 4096-i;
    

    int i=0;
    for (int Row = 0; Row < Img_Size.height; Row++)
    
        for (int Col = 0; Col < Img_Size.width; Col++)
        
            Img_Source_16.at<short>(Row,Col)= i;
            i++;
            if(i>=4095)
                i=0;
        
    

    imshow("Img_Source",Img_Source_16);

    t1.start();
    Img_Destination_16= ScanImageAndReduceC_16UC1(Img_Source_16.clone(),LookupTable);

    imshow("Img_Destination",Img_Destination_16);
    t1.stop();


Mat& ScanImageAndReduceC_16UC1(Mat& I, const unsigned short* const table)

    // accept only char type matrices
    CV_Assert(I.depth() != sizeof(uchar));

    int channels = I.channels();

    int nRows = I.rows;
    int nCols = I.cols * channels;

    if (I.isContinuous())
    
        nCols *= nRows;
        nRows = 1;
    

    int i,j;
    unsigned short* p = (unsigned short*)I.data;
    for( unsigned int i =0; i < nCols*nRows; ++i)
        *p++ = table[*p];

    return I;

【讨论】:

以上是关于16位垫子的查找表高效方式?的主要内容,如果未能解决你的问题,请参考以下文章

高效交换半字

高效查询 - 查询表 A 中的特定 ID 组时,如何检查表 B 中的条件以查找表 A 中的选定 ID?

查找所有连接对之和的高效算法

在 Hive/Spark 中高效查找大数据表的所有相关子范围

高效查找最近 k 天内未更新的记录

C 语言高效编程与代码优化