• c++ 如何把RGB图像转换成HSV图像?


    CV_<bit_depth>(S|U|F)C<number_of_channels>
    
    1--bit_depth---比特数---代表8bite,16bites,32bites,64bites---举个例子吧--比如说,如
            如果你现在创建了一个存储--灰度图片的Mat对象,这个图像的大小为宽100,高100,那么,现在这张
            灰度图片中有10000个像素点,它每一个像素点在内存空间所占的空间大小是8bite,8位--所以它对
            应的就是CV_8
         2--S|U|F--S--代表---signed int---有符号整形
                   U--代表--unsigned int--无符号整形
                   F--代表--float---------单精度浮点型
         3--C<number_of_channels>----代表---一张图片的通道数,比如:
             1--灰度图片--grayImg---是--单通道图像
             2--RGB彩色图像---------是--3通道图像
             3--带Alph通道的RGB图像--是--4通道图像
    
    
    //【1】CV_8UC1---则可以创建----8位无符号的单通道---灰度图片------grayImg
    #define CV_8UC1 CV_MAKETYPE(CV_8U,1)
    #define CV_8UC2 CV_MAKETYPE(CV_8U,2)
    //【2】CV_8UC3---则可以创建----8位无符号的三通道---RGB彩色图像---colorImg 
    #define CV_8UC3 CV_MAKETYPE(CV_8U,3)
    //【3】CV_8UC4--则可以创建-----8位无符号的四通道---带透明色的RGB图像 
    #define CV_8UC4 CV_MAKETYPE(CV_8U,4)
    
    struct RGB2HSV_b
    {
        typedef uchar channel_type;
    
        RGB2HSV_b(int _srccn, int _blueIdx, int _hrange)
        : srccn(_srccn), blueIdx(_blueIdx), hrange(_hrange)
        {
            CV_Assert( hrange == 180 || hrange == 256 );
        }
    
        void operator()(const uchar* src, uchar* dst, int n) const
        {
            int i, bidx = blueIdx, scn = srccn;
            const int hsv_shift = 12;
    
            static int sdiv_table[256];
            static int hdiv_table180[256];
            static int hdiv_table256[256];
            static volatile bool initialized = false;
    
            int hr = hrange;
            const int* hdiv_table = hr == 180 ? hdiv_table180 : hdiv_table256;
            n *= 3;
    
            if( !initialized )
            {
                sdiv_table[0] = hdiv_table180[0] = hdiv_table256[0] = 0;
                for( i = 1; i < 256; i++ )
                {
                    sdiv_table[i] = saturate_cast<int>((255 << hsv_shift)/(1.*i));
                    hdiv_table180[i] = saturate_cast<int>((180 << hsv_shift)/(6.*i));
                    hdiv_table256[i] = saturate_cast<int>((256 << hsv_shift)/(6.*i));
                }
                initialized = true;
            }
    
            for( i = 0; i < n; i += 3, src += scn )
            {
                int b = src[bidx], g = src[1], r = src[bidx^2];
                int h, s, v = b;
                int vmin = b;
                int vr, vg;
    
                CV_CALC_MAX_8U( v, g );
                CV_CALC_MAX_8U( v, r );
                CV_CALC_MIN_8U( vmin, g );
                CV_CALC_MIN_8U( vmin, r );
    
                uchar diff = saturate_cast<uchar>(v - vmin);
                vr = v == r ? -1 : 0;
                vg = v == g ? -1 : 0;
    
                s = (diff * sdiv_table[v] + (1 << (hsv_shift-1))) >> hsv_shift;
                h = (vr & (g - b)) +
                    (~vr & ((vg & (b - r + 2 * diff)) + ((~vg) & (r - g + 4 * diff))));
                h = (h * hdiv_table[diff] + (1 << (hsv_shift-1))) >> hsv_shift;
                h += h < 0 ? hr : 0;
    
                dst[i] = saturate_cast<uchar>(h);
                dst[i+1] = (uchar)s;
                dst[i+2] = (uchar)v;
            }
        }
    
        int srccn, blueIdx, hrange;
    };
    
    struct RGB2HSV_f
    {
        typedef float channel_type;
    
        RGB2HSV_f(int _srccn, int _blueIdx, float _hrange)
        : srccn(_srccn), blueIdx(_blueIdx), hrange(_hrange) {}
    
        void operator()(const float* src, float* dst, int n) const
        {
            int i, bidx = blueIdx, scn = srccn;
            float hscale = hrange*(1.f/360.f);
            n *= 3;
    
            for( i = 0; i < n; i += 3, src += scn )
            {
                float b = src[bidx], g = src[1], r = src[bidx^2];
                float h, s, v;
    
                float vmin, diff;
    
                v = vmin = r;
                if( v < g ) v = g;
                if( v < b ) v = b;
                if( vmin > g ) vmin = g;
                if( vmin > b ) vmin = b;
    
                diff = v - vmin;
                s = diff/(float)(fabs(v) + FLT_EPSILON);
                diff = (float)(60./(diff + FLT_EPSILON));
                if( v == r )
                    h = (g - b)*diff;
                else if( v == g )
                    h = (b - r)*diff + 120.f;
                else
                    h = (r - g)*diff + 240.f;
    
                if( h < 0 ) h += 360.f;
    
                dst[i] = h*hscale;
                dst[i+1] = s;
                dst[i+2] = v;
            }
        }
    
        int srccn, blueIdx;
        float hrange;
    };
    
    #define FLT_EPSILON      1.192092896e-07F        // smallest such that 1.0+FLT_EPSILON != 1.0
    /* helper tables */
    extern const uchar icvSaturate8u_cv[];
    #define CV_FAST_CAST_8U(t)  ( (-256 <= (t) && (t) <= 512) ? icvSaturate8u_cv[(t)+256] : 0 )
    #define CV_CALC_MIN_8U(a,b) (a) -= CV_FAST_CAST_8U((a) - (b))
    #define CV_CALC_MAX_8U(a,b) (a) += CV_FAST_CAST_8U((b) - (a))
    
  • 相关阅读:
    DataGridView编辑后立即更新到数据库的两种方法
    Azure 意外重启, 丢失sql server master表和 filezilla
    欧洲美食精选-德国篇
    Azure 负载均衡和可用性集
    windows Azure 域名绑定
    Azure billing 分析(2)
    Azure billing 分析
    试用windows Azure
    Excel公式无法重算,暂无法解决
    iphone 语音备忘录 同步问题
  • 原文地址:https://www.cnblogs.com/cheungxiongwei/p/7658989.html
Copyright © 2020-2023  润新知