• (十四)OpenCV中的自带颜色表操作cv::LUT


    欢迎访问个人网络日志🌹🌹知行空间🌹🌹


    1.介绍

    cv::LUTOpenCV中实现的自带颜色表操作,实现数组的查表变换。将输入数组src根据变换表lut变换得到dst。其实现作用过程如下图:

    在这里插入图片描述

    其应用主要是空间换时间,可以减少运算量,如对图像应用gamma校正时可以将0-255的计算结果存储在lut中,利用查表实现gamma变换。

    2.cv::LUT API

    void cv::LUT(InputArray src,
                 InputArray lut,
                 OutputArray dst );
    
    • 1
    • 2
    • 3

    cv::LUT API 在头文件#include

    值得注意的是,lut256个元素的数组,当src是单通道数组如CV_8UC1时,lut必须是单通道的,当src是多通道数组时如CV_8UC3,lut可以是单通道,也可以与src有同样的通道。与src同通道数时可以实现对src不同通道实现不同的查找表。其LUT源码如下:

    LUT8u_( const uchar* src, const T* lut, T* dst, int len, int cn, int lutcn )
    {
        if( lutcn == 1 )
        {
            for( int i = 0; i < len*cn; i++ )
                dst[i] = lut[src[i]];
        }
        else
        {
            for( int i = 0; i < len*cn; i += cn )
                for( int k = 0; k < cn; k++ )
                    dst[i+k] = lut[src[i+k]*cn+k];
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    3.应用实例

    void test_lut( void )
    {
        cv::Mat lut1(1, 256, CV_8UC1);
        cv::Mat lut3(1, 256, CV_8UC3);
        float gamma = 4.2;
        for(int i=0; i<256; i++) {
            unsigned char c = (unsigned char)(exp(log((float)i/255.)*gamma) * 255);
            lut1.at<unsigned char>(0, i) = c;
            lut3.at<cv::Vec3b>(i) = cv::Vec3b(c, c+1, c+2);
        }
        std::cout << "lut3: " << lut3 << std::endl;
        cv::Mat src = (cv::Mat3b(2,2) << cv::Vec3b(1,1,3), \
                                           cv::Vec3b(4,8,9), \
                                           cv::Vec3b(65,4,4), \
                                           cv::Vec3b(253,253,253));
        std::cout << "src:" << src << std::endl;
    
        cv::Mat dst;
        cv::LUT(src, lut1, dst);
        std::cout << "dst1: " << dst << std::endl;
       
        cv::LUT(src, lut3, dst);
        std::cout << "dst3: " << dst << std::endl;  
        /** output
         * lut1 在253处对应的值为246
         * lut3 在253处对应的CV——8UC3为 246,247,248
         * src:
            [  1,   1,   3,   4,   8,   9;
            65,   4,   4, 253, 253, 253]
        dst1: 
            [  0,   0,   0,   0,   0,   0;
            0,   0,   0, 246, 246, 246]
        dst3: 
            [  0,   1,   2,   0,   1,   2;
            0,   1,   2, 246, 247, 248]
        
        */   
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    此外,OpenCV中伪彩色变换也通过类似LUT的方式实现,如下代码通过createTrackBar回调实现不同类型的applyColorMap

    static void onTrackBarChanged(int value, void *userdata) 
    {
        const auto &data = *static_cast<UserData*>(userdata);
        cv::Mat mask_image = cv::Mat::zeros(data.image->size(), CV_8UC3);
        mask_image = cv::Scalar((uint8_t)value, (uint8_t)value, (uint8_t)value);
        cv::add(*data.image, mask_image, mask_image);
        cv::applyColorMap(*data.image, mask_image, value);
        cv::imshow("COLORMAP_LUT", mask_image);
    }
    
    void show() const
    {
        cv::Mat image = cv::imread(m_image_name);
        printf("Image %s\n", m_image_name);
        cv::Mat mask_image;
        if(image.empty())
            printf("%s is empty\n", m_image_name);
        int colormap = 1;
        cv::namedWindow("COLORMAP_LUT", cv::WINDOW_AUTOSIZE);
        char trackerBarName[50];
        sprintf(trackerBarName, "colormap %d", 1);
        UserData userData;
        userData.image = &image;
        cv::imshow("COLORMAP_LUT", image);
        cv::createTrackbar(trackerBarName, "COLORMAP_LUT", &colormap, \
                            11, onTrackBarChanged, &userData);
        cv::waitKey(0);
        cv::destroyAllWindows();    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    欢迎访问个人网络日志🌹🌹知行空间🌹🌹


    参考资料

  • 相关阅读:
    04在命令行中使用Maven命令创建Maven版的Web工程,并将工程部署到服务器的步骤
    语音信号的仿真原理
    leetcodeMysql练习记录(一)
    web3时事粥报
    00 vue部分补充
    高德地图系列(三):vue项目利用高德地图实现地址搜索功能
    [附源码]java毕业设计养老护理综合服务系统
    什么是PCB中的光学定位点,不加可不可以?
    DDR3 NATIVE接口
    计算机毕业设计Java高校设备采购审批管理系统(源码+系统+mysql数据库+Lw文档)
  • 原文地址:https://blog.csdn.net/lx_ros/article/details/127798053