• 【opencv源码解析】 二、 cvtColor


    这里以CV_BGR2YUV_I420来讲

    1. opencv244

    core.cpp

    void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn )
    {
      ...
    case COLOR_RGB2YUV_YV12: case COLOR_BGR2YUV_YV12: case COLOR_RGBA2YUV_YV12: case COLOR_BGRA2YUV_YV12:
    case COLOR_RGB2YUV_IYUV: case COLOR_BGR2YUV_IYUV: case COLOR_RGBA2YUV_IYUV: case COLOR_BGRA2YUV_IYUV:
    if (dcn <= 0) dcn = 1;
    uidx = (code == COLOR_BGR2YUV_IYUV || code == COLOR_BGRA2YUV_IYUV || code == COLOR_RGB2YUV_IYUV || code == COLOR_RGBA2YUV_IYUV) ? 1 : 2;
    CV_Assert( (scn == 3 || scn == 4) && depth == CV_8U );
    CV_Assert( dcn == 1 );
    CV_Assert( sz.width % 2 == 0 && sz.height % 2 == 0 );
    _dst.create(Size(sz.width, sz.height / 2 * 3), CV_MAKETYPE(depth, dcn));
    dst = _dst.getMat();
    hal::cvtBGRtoThreePlaneYUV(src.data, src.step, dst.data, dst.step, src.cols, src.rows,
    scn, swapBlue(code), uidx);
    break;
    
      ...
    }

      

    color.cpp

    void cvtBGRtoThreePlaneYUV(const uchar * src_data, size_t src_step,
    uchar * dst_data, size_t dst_step,
    int width, int height,
    int scn, bool swapBlue, int uIdx)
    {
    CV_INSTRUMENT_REGION()
    
    CALL_HAL(cvtBGRtoThreePlaneYUV, cv_hal_cvtBGRtoThreePlaneYUV, src_data, src_step, dst_data, dst_step, width, height, scn, swapBlue, uIdx);
    uchar * uv_data = dst_data + dst_step * height;
    RGB888toYUV420pInvoker(src_data, src_step, dst_data, uv_data, dst_step, width, height, scn, swapBlue, uIdx == 2, false).convert();
    }
    
      

    color.cpp

    struct RGB888toYUV420pInvoker: public ParallelLoopBody
    {
    RGB888toYUV420pInvoker(const uchar * _src_data, size_t _src_step,
    uchar * _y_data, uchar * _uv_data, size_t _dst_step,
    int _src_width, int _src_height, int _scn, bool swapBlue_, bool swapUV_, bool interleaved_)
    : src_data(_src_data), src_step(_src_step),
    y_data(_y_data), uv_data(_uv_data), dst_step(_dst_step),
    src_width(_src_width), src_height(_src_height),
    scn(_scn), swapBlue(swapBlue_), swapUV(swapUV_), interleaved(interleaved_) { }
    
    void operator()(const Range& rowRange) const
    {
    const int w = src_width;
    const int h = src_height;
    const int cn = scn;
    for( int i = rowRange.start; i < rowRange.end; i++ )
    {
    const uchar* brow0 = src_data + src_step * (2 * i);
    const uchar* grow0 = brow0 + 1;
    const uchar* rrow0 = brow0 + 2;
    const uchar* brow1 = src_data + src_step * (2 * i + 1);
    const uchar* grow1 = brow1 + 1;
    const uchar* rrow1 = brow1 + 2;
    if (swapBlue)
    {
    std::swap(brow0, rrow0);
    std::swap(brow1, rrow1);
    }
    
    uchar* y = y_data + dst_step * (2*i);
    uchar* u;
    uchar* v;
    if (interleaved)
    {
    u = uv_data + dst_step * i;
    v = uv_data + dst_step * i + 1;
    }
    else
    {
    u = uv_data + dst_step * (i/2) + (i % 2) * (w/2);
    v = uv_data + dst_step * ((i + h/2)/2) + ((i + h/2) % 2) * (w/2);
    }
    
    if (swapUV)
    {
    std::swap(u, v);
    }
    
    for( int j = 0, k = 0; j < w * cn; j += 2 * cn, k++ )
    {
    int r00 = rrow0[j]; int g00 = grow0[j]; int b00 = brow0[j];
    int r01 = rrow0[cn + j]; int g01 = grow0[cn + j]; int b01 = brow0[cn + j];
    int r10 = rrow1[j]; int g10 = grow1[j]; int b10 = brow1[j];
    int r11 = rrow1[cn + j]; int g11 = grow1[cn + j]; int b11 = brow1[cn + j];
    
    const int shifted16 = (16 << ITUR_BT_601_SHIFT);
    const int halfShift = (1 << (ITUR_BT_601_SHIFT - 1));
    int y00 = ITUR_BT_601_CRY * r00 + ITUR_BT_601_CGY * g00 + ITUR_BT_601_CBY * b00 + halfShift + shifted16;
    int y01 = ITUR_BT_601_CRY * r01 + ITUR_BT_601_CGY * g01 + ITUR_BT_601_CBY * b01 + halfShift + shifted16;
    int y10 = ITUR_BT_601_CRY * r10 + ITUR_BT_601_CGY * g10 + ITUR_BT_601_CBY * b10 + halfShift + shifted16;
    int y11 = ITUR_BT_601_CRY * r11 + ITUR_BT_601_CGY * g11 + ITUR_BT_601_CBY * b11 + halfShift + shifted16;
    
    y[2*k + 0] = saturate_cast<uchar>(y00 >> ITUR_BT_601_SHIFT);
    y[2*k + 1] = saturate_cast<uchar>(y01 >> ITUR_BT_601_SHIFT);
    y[2*k + dst_step + 0] = saturate_cast<uchar>(y10 >> ITUR_BT_601_SHIFT);
    y[2*k + dst_step + 1] = saturate_cast<uchar>(y11 >> ITUR_BT_601_SHIFT);
    
    const int shifted128 = (128 << ITUR_BT_601_SHIFT);
    int u00 = ITUR_BT_601_CRU * r00 + ITUR_BT_601_CGU * g00 + ITUR_BT_601_CBU * b00 + halfShift + shifted128;
    int v00 = ITUR_BT_601_CBU * r00 + ITUR_BT_601_CGV * g00 + ITUR_BT_601_CBV * b00 + halfShift + shifted128;
    
    if (interleaved)
    {
    u[k*2] = saturate_cast<uchar>(u00 >> ITUR_BT_601_SHIFT);
    v[k*2] = saturate_cast<uchar>(v00 >> ITUR_BT_601_SHIFT);
    }
    else
    {
    u[k] = saturate_cast<uchar>(u00 >> ITUR_BT_601_SHIFT);
    v[k] = saturate_cast<uchar>(v00 >> ITUR_BT_601_SHIFT);
    }
    }
    }
    }
    
    void convert() const
    {
    if( src_width * src_height >= 320*240 )
    parallel_for_(Range(0, src_height/2), *this);
    else
    operator()(Range(0, src_height/2));
    }
    
    private:
    RGB888toYUV420pInvoker& operator=(const RGB888toYUV420pInvoker&);
    
    const uchar * src_data;
    size_t src_step;
    uchar *y_data, *uv_data;
    size_t dst_step;
    int src_width;
    int src_height;
    const int scn;
    bool swapBlue;
    bool swapUV;
    bool interleaved;
    };
    
      

    2.   opencv347   使用opencl

    bool oclCvtColorTwoPlaneYUV2BGR( InputArray _src, OutputArray _dst, int dcn, int bidx, int uidx )
    {
        OclHelper< Set<1>, Set<3, 4>, Set<CV_8U>, FROM_YUV > h(_src, _dst, dcn);
    
        if(!h.createKernel("YUV2RGB_NVx", ocl::imgproc::color_yuv_oclsrc,
                           format("-D dcn=%d -D bidx=%d -D uidx=%d", dcn, bidx, uidx)))
        {
            return false;
        }
    
        return h.run();
    }
  • 相关阅读:
    Kubernetes中Pod之间使用虚拟二层网络连接
    ResourceQuota和LimitRange实践指南
    Namespace集群环境的共享与隔离
    K8s生产架构
    K8s常用命令整理+名词解析
    K8s中的pv&&pvc
    Kubernetes保证集群内节点和网络安全
    Kubernetes中网络相关知识
    kubectl常用命令
    物理ceph集群+K8s
  • 原文地址:https://www.cnblogs.com/luoyinjie/p/9088967.html
Copyright © 2020-2023  润新知