美文网首页
OpenCV源码浅析——MatExpr到Mat是怎么赋值的?

OpenCV源码浅析——MatExpr到Mat是怎么赋值的?

作者: BetterCV | 来源:发表于2020-04-16 21:54 被阅读0次

    在公司里做视觉AI落地,少不了参考和移植OpenCV的源码。譬如最常见的Mat类对象,做一个减均值的操作,用起来一句话,底层实现其实一堆,调试下来真的是冰山一角的感觉。今天就来说说非SIMD优化情况下的MatExpr到Mat的赋值是怎么实现的。

    用的是OpenCV 3.4.9版本,基本上和最新(4.3.0)版本的实现一致。基于VS2017,VSCode,Git,GitBash等工具。

    0. HighLevel的函数调用:

    Mat a(3, 3, CV_64FC1, Scalar::all(1));
    Mat b = a - 1.5;
    

    看,是不是很简单?一个3x3的double类型的矩阵,元素取值都是1;所有元素都减去1.5(也就是Python中所谓的broadcast广播,Matlab中也有类似的原生支持功能)。

    实际上断点调试一下就发现没那么简单。1.5是double双精度浮点数,会被转换为Scalar对象;Mat对象和Scalar对象相减,结果是MatExpr类型,是做了转换才得到Mat类型的。等价于:

    Mat a(3, 3, CV_64FC1, Scalar::all(1));
    Scalar c = 1.5;
    MatExpr d = a - c;
    Mat e = d;
    

    只关注Mat e=d这一步,看似无聊没用,但如果是移植OpenCV为自己的产品所用,发现这其中还不是简单的调试断点就能搞清楚的。

    先尝试了最简单的断点调试(需要OpenCV源码debug模式编译),关键几个调用:


    image.png image.png image.png image.png
    其中getAddTab()的一个trick是,函数内用static变量作为返回值,由于存储在静态存储区并且用编译阶段确定的函数名来赋值,因此我们调试进来的时候就晚了(没赶在初始化之前设定断点),于是我稍微修改后得以停留。不过并没有什么用,cv::hal::add64f并不能跳转到定义。

    接下来就贴一下,add64f是怎么被定义和调用的(简单说来,它是用宏trick来定义函数的,个人觉得比较hack)。

    1. getAddTab()返回的是函数指针数组,为什么它返回的时候我没法设断点?

    因为是static局部变量,并且用已经存在的函数初始化的。程序一旦运行,这个局部变量的值就确定了,也就是被初始化过了,当然没法设断点了。搞他!

        //static BinaryFuncC addTab[] =
     //{
     //    (BinaryFuncC)GET_OPTIMIZED(cv::hal::add8u), (BinaryFuncC)GET_OPTIMIZED(cv::hal::add8s),
     //    (BinaryFuncC)GET_OPTIMIZED(cv::hal::add16u), (BinaryFuncC)GET_OPTIMIZED(cv::hal::add16s),
     //    (BinaryFuncC)GET_OPTIMIZED(cv::hal::add32s),
     //    (BinaryFuncC)GET_OPTIMIZED(cv::hal::add32f), (BinaryFuncC)cv::hal::add64f,
     //    0
     //};
     BinaryFuncC a[8];
     a[0] = (BinaryFuncC)GET_OPTIMIZED(cv::hal::add8u);
     a[1] = (BinaryFuncC)GET_OPTIMIZED(cv::hal::add8s);
     a[2] = (BinaryFuncC)GET_OPTIMIZED(cv::hal::add16u);
     a[3] = (BinaryFuncC)GET_OPTIMIZED(cv::hal::add16s);
     a[4] = (BinaryFuncC)GET_OPTIMIZED(cv::hal::add32s);
     a[5] = (BinaryFuncC)GET_OPTIMIZED(cv::hal::add32f);
     a[6] = (BinaryFuncC)cv::hal::add64f;
     a[7] = 0;
    
     static BinaryFuncC addTab[] = {
         a[0], a[1], a[2], a[3], a[4], a[5], a[6],a[7]
     };
    

    2. 后续其它函数中,发现调用的是函数指针表中的索引为6的,也就是cv::hal::add64f函数。

    这个函数在哪里实现的?

    能够断点到这个宏:

    DEFINE_SIMD_ALL(add, op_add)
    

    接着断点到如下模板函数:(arithm.simd.hpp)

    #if !CV_SIMD_64F
    template<template<typename T1, typename Tvec> class OP, typename T1, typename Tvec>
    static void bin_loop_nosimd(const T1* src1, size_t step1, const T1* src2, size_t step2, T1* dst, size_t step, int width, int height)
    {
        typedef OP<T1, Tvec/*dummy*/> op;
    
        step1 /= sizeof(T1);
        step2 /= sizeof(T1);
        step  /= sizeof(T1);
    
        for (; height--; src1 += step1, src2 += step2, dst += step)
        {
            int x = 0;
    
            for (; x <= width - 4; x += 4)
            {
                T1 t0 = op::r(src1[x], src2[x]);
                T1 t1 = op::r(src1[x + 1], src2[x + 1]);
                dst[x] = t0; dst[x + 1] = t1;
    
                t0 = op::r(src1[x + 2], src2[x + 2]);
                t1 = op::r(src1[x + 3], src2[x + 3]);
                dst[x + 2] = t0; dst[x + 3] = t1;
            }
    
            for (; x < width; x++)
                dst[x] = op::r(src1[x], src2[x]);
        }
    }
    

    为啥会运行到这个函数呢?

    3. 调用堆栈:为了搞清楚为啥来这里执行,看看call stack:

    arithm_hal_debug_call_stack1.png

    字太小了,只看函数名吧:


    arithm_hal_debug_call_stack2.png

    发现栈顶的两次调用,都是cv::hal::cpu_baseline命名空间(namespace)下的函数。咋没见到这个namespace的定义呢?
    其实是有的,但是写成宏定义了。(很垃圾的编码风格。为什么不写namespace而要用宏呢?)

    其中,栈顶函数bin_loop_nosimd()就是刚刚贴出来的naive实现的函数(模板函数);栈顶之下紧接着的函数cv::hal::cpu_baseline::add64f()就是前面贴出来的宏DEFINE_SIMD_ALL(add, op_add)

    4. VS不给做静态语法解析了

    那就手动解析:

    DEFINE_SIMD_ALL(add, op_add)
    

    第一次展开为:

    DEFINE_SIMD_SAT(add, op_add)  \
    DEFINE_SIMD_NSAT(add, op_add)
    

    第二次展开为:

    DEFINE_SIMD_U8(add, op_add)   \
    DEFINE_SIMD_S8(add, op_add)   \
    DEFINE_SIMD_U16(add, op_add)  \
    DEFINE_SIMD_S16(add, op_add)  \
    DEFINE_SIMD_S32(add, op_add)  \
    DEFINE_SIMD_F32(add, op_add)  \
    DEFINE_SIMD_F64(add, op_add)
    

    DEFINE_SIMD_U8入手,第一次展开为:

    DEFINE_SIMD(__CV_CAT(add, 8u), uchar, v_uint8, op_add)
    

    其中__CV_CAT是做字符串拼接(##连接符实现),因而第二次展开为:

    DEFINE_SIMD(add8u, uchar, v_uint8, op_add)
    
    arithm_hal_debug_call_stack4.png

    实际上,arithm.cpp中的函数,naive的实现和SIMD的实现的切换,恐怕就是DEFINE_SIMD宏了。

    现在我更感兴趣的是,任意的op函数的宏跳转DEFINE_SIMD_ALL(fun, ...)展开。目前展开为

    DEFINE_SIMD(__CV_CAT(fun, 8u), uchar, v_uint8, __VA_ARGS__) \
    DEFINE_SIMD(__CV_CAT(fun, 8s), schar, v_int8,  __VA_ARGS__) \
    DEFINE_SIMD(__CV_CAT(fun, 16u), ushort, v_uint16, __VA_ARGS__) \
    DEFINE_SIMD(__CV_CAT(fun, 16s), short, v_int16,  __VA_ARGS__) \
    DEFINE_SIMD(__CV_CAT(fun, 32s), int, v_int32,  __VA_ARGS__) \
    DEFINE_SIMD(__CV_CAT(fun, 32f), float, v_float32, __VA_ARGS__) \
    DEFINE_NOSIMD(__CV_CAT(fun, 64f), double, __VA_ARGS__)
    

    好吧,fun还是换成具体的函数名字比较直观。

    DEFINE_SIMD_U8(add, op_add)进一步展开为:

    DECLARE_SIMD_FUN(fun_name, uchar) \
    DEFINE_SIMD_FUN(fun_name, uchar, v_uint8, op_add)
    

    意思是先声明一个函数,再定义这个函数。呃,用宏定义来实现函数声明和定义,看起来是反射,但是这也太蛋疼了。

    大概看一下DEFINE_SIMD_FUN怎么定义的函数?

    #define DEFINE_SIMD_FUN(fun, _T1, _Tvec, _OP)     \
        void fun(BIN_ARGS(_T1))                       \
        {                                             \
            CV_INSTRUMENT_REGION();                   \
            bin_loop<_OP, _T1, _Tvec>(BIN_ARGS_PASS); \
        }
    

    哦对了,如果是double类型的数据,那么有时候(我这里关掉所有优化,就是这种情况),调用的是这个:

    #define DEFINE_NOSIMD_FUN(fun, _T1, _OP)                     \
        void fun(BIN_ARGS(_T1))                                  \
        {                                                        \
            CV_INSTRUMENT_REGION();                              \
            bin_loop_nosimd<_OP, _T1, v_float64>(BIN_ARGS_PASS); \
        }
    

    至此,终于串起来了前面断点中的函数调用栈的栈顶和次栈顶,以及栈中其它函数。


    实际上,MatExpr到Mat的转换,会执行计算。也即是,Mat和Scalar之间的计算,被转换为MatExpr对象,此对象并不立即做计算(MatExpr意思其实就是Math/Matrix Expression),而是到了MatExpr转为Mat的时候再计算。

    前面写到的无法跳转的函数add8uadd64f等函数,完整的展开是:

    DEFINE_SIMD_ALL(add, op_add)
    
    =>
    
    DEFINE_SIMD_U8(add, op_add)   \
    DEFINE_SIMD_S8(add, op_add)   \
    DEFINE_SIMD_U16(add, op_add)  \
    DEFINE_SIMD_S16(add, op_add)  \
    DEFINE_SIMD_S32(add, op_add)  \
    DEFINE_SIMD_F32(add, op_add)  \
    DEFINE_SIMD_F64(add, op_add)
    
    =>
    
    DEFINE_SIMD(__CV_CAT(add, 8u), uchar, v_uint8, op_add) \
    DEFINE_SIMD(__CV_CAT(add, 8s), schar, v_int8,  op_add) \
    DEFINE_SIMD(__CV_CAT(add, 16u), ushort, v_uint16, op_add) \
    DEFINE_SIMD(__CV_CAT(add, 16s), short, v_int16,  op_add) \
    DEFINE_SIMD(__CV_CAT(add, 32s), int, v_int32,  op_add) \
    DEFINE_SIMD(__CV_CAT(add, 32f), float, v_float32, op_add) \
    DEFINE_NOSIMD(__CV_CAT(add, 64f), double, op_add)
    
    =>
    
    DEFINE_SIMD(add8u, uchar, v_uint8, op_add) \
    DEFINE_SIMD(add8s, schar, v_int8,  op_add) \
    DEFINE_SIMD(add16u, ushort, v_uint16, op_add) \
    DEFINE_SIMD(add16s, short, v_int16,  op_add) \
    DEFINE_SIMD(add32s, int, v_int32,  op_add) \
    DEFINE_SIMD(add32f, float, v_float32, op_add) \
    DEFINE_NOSIMD(add64f, double, op_add)
    
    =>
    
    DECLARE_SIMD_FUN(add8u, uchar) \
    DEFINE_SIMD_FUN(add8u, uchar, v_uint8, op_add) \
    DECLARE_SIMD_FUN(add8s, schar) \
    DEFINE_SIMD_FUN(add8s, schar, v_int8, op_add) \
    DECLARE_SIMD_FUN(add16u, ushort) \
    DEFINE_SIMD_FUN(add16u, ushort, v_uint16, op_add) \
    DECLARE_SIMD_FUN(add16s, short) \
    DEFINE_SIMD_FUN(add16s, short, v_int16, op_add) \
    DECLARE_SIMD_FUN(add32s, int) \
    DEFINE_SIMD_FUN(add32s, int, v_int32, op_add) \
    DECLARE_SIMD_FUN(add32f, float) \
    DEFINE_SIMD_FUN(add32f, float, v_float32, op_add) \
    DECLARE_SIMD_FUN(add64f, double) \
    DEFINE_NOSIMD_FUN(add64f, double, op_add)
    
    

    在Visual Studio里勾选“生成预编译文件”以及“包括注释”


    image.png

    然后,可以看到add8u等函数的定义(arithm.dispatch.i)

    void add8u(const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height); void add8u(const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn539 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn539 = { &(__cv_trace_location_extra_fn539),   __FUNCSIG__   , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 539, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn539);;; bin_loop<op_add, uchar, v_uint8>(src1, step1, src2, step2, dst, step, width, height); } void add8s(const schar* src1, size_t step1, const schar* src2, size_t step2, schar* dst, size_t step, int width, int height); void add8s(const schar* src1, size_t step1, const schar* src2, size_t step2, schar* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn539 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn539 = { &(__cv_trace_location_extra_fn539),   __FUNCSIG__   , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 539, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn539);;; bin_loop<op_add, schar, v_int8>(src1, step1, src2, step2, dst, step, width, height); } void add16u(const ushort* src1, size_t step1, const ushort* src2, size_t step2, ushort* dst, size_t step, int width, int height); void add16u(const ushort* src1, size_t step1, const ushort* src2, size_t step2, ushort* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn539 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn539 = { &(__cv_trace_location_extra_fn539),   __FUNCSIG__   , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 539, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn539);;; bin_loop<op_add, ushort, v_uint16>(src1, step1, src2, step2, dst, step, width, height); } void add16s(const short* src1, size_t step1, const short* src2, size_t step2, short* dst, size_t step, int width, int height); void add16s(const short* src1, size_t step1, const short* src2, size_t step2, short* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn539 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn539 = { &(__cv_trace_location_extra_fn539),   __FUNCSIG__   , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 539, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn539);;; bin_loop<op_add, short, v_int16>(src1, step1, src2, step2, dst, step, width, height); } void add32s(const int* src1, size_t step1, const int* src2, size_t step2, int* dst, size_t step, int width, int height); void add32s(const int* src1, size_t step1, const int* src2, size_t step2, int* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn539 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn539 = { &(__cv_trace_location_extra_fn539),   __FUNCSIG__   , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 539, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn539);;; bin_loop<op_add, int, v_int32>(src1, step1, src2, step2, dst, step, width, height); } void add32f(const float* src1, size_t step1, const float* src2, size_t step2, float* dst, size_t step, int width, int height); void add32f(const float* src1, size_t step1, const float* src2, size_t step2, float* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn539 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn539 = { &(__cv_trace_location_extra_fn539),   __FUNCSIG__   , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 539, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn539);;; bin_loop<op_add, float, v_float32>(src1, step1, src2, step2, dst, step, width, height); } void add64f(const double* src1, size_t step1, const double* src2, size_t step2, double* dst, size_t step, int width, int height); void add64f(const double* src1, size_t step1, const double* src2, size_t step2, double* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn539 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn539 = { &(__cv_trace_location_extra_fn539),   __FUNCSIG__   , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 539, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn539);;; bin_loop_nosimd<op_add, double, v_float64>(src1, step1, src2, step2, dst, step, width, height); }
    void sub8u(const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height); void sub8u(const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn540 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn540 = { &(__cv_trace_location_extra_fn540),   __FUNCSIG__   , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 540, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn540);;; bin_loop<op_sub, uchar, v_uint8>(src1, step1, src2, step2, dst, step, width, height); } void sub8s(const schar* src1, size_t step1, const schar* src2, size_t step2, schar* dst, size_t step, int width, int height); void sub8s(const schar* src1, size_t step1, const schar* src2, size_t step2, schar* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn540 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn540 = { &(__cv_trace_location_extra_fn540),   __FUNCSIG__   , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 540, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn540);;; bin_loop<op_sub, schar, v_int8>(src1, step1, src2, step2, dst, step, width, height); } void sub16u(const ushort* src1, size_t step1, const ushort* src2, size_t step2, ushort* dst, size_t step, int width, int height); void sub16u(const ushort* src1, size_t step1, const ushort* src2, size_t step2, ushort* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn540 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn540 = { &(__cv_trace_location_extra_fn540),   __FUNCSIG__   , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 540, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn540);;; bin_loop<op_sub, ushort, v_uint16>(src1, step1, src2, step2, dst, step, width, height); } void sub16s(const short* src1, size_t step1, const short* src2, size_t step2, short* dst, size_t step, int width, int height); void sub16s(const short* src1, size_t step1, const short* src2, size_t step2, short* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn540 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn540 = { &(__cv_trace_location_extra_fn540),   __FUNCSIG__   , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 540, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn540);;; bin_loop<op_sub, short, v_int16>(src1, step1, src2, step2, dst, step, width, height); } void sub32s(const int* src1, size_t step1, const int* src2, size_t step2, int* dst, size_t step, int width, int height); void sub32s(const int* src1, size_t step1, const int* src2, size_t step2, int* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn540 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn540 = { &(__cv_trace_location_extra_fn540),   __FUNCSIG__   , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 540, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn540);;; bin_loop<op_sub, int, v_int32>(src1, step1, src2, step2, dst, step, width, height); } void sub32f(const float* src1, size_t step1, const float* src2, size_t step2, float* dst, size_t step, int width, int height); void sub32f(const float* src1, size_t step1, const float* src2, size_t step2, float* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn540 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn540 = { &(__cv_trace_location_extra_fn540),   __FUNCSIG__   , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 540, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn540);;; bin_loop<op_sub, float, v_float32>(src1, step1, src2, step2, dst, step, width, height); } void sub64f(const double* src1, size_t step1, const double* src2, size_t step2, double* dst, size_t step, int width, int height); void sub64f(const double* src1, size_t step1, const double* src2, size_t step2, double* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn540 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn540 = { &(__cv_trace_location_extra_fn540),   __FUNCSIG__   , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 540, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn540);;; bin_loop_nosimd<op_sub, double, v_float64>(src1, step1, src2, step2, dst, step, width, height); }
    
    void min8u(const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height); void min8u(const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn542 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn542 = { &(__cv_trace_location_extra_fn542),   __FUNCSIG__   , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 542, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn542);;; bin_loop<op_min, uchar, v_uint8>(src1, step1, src2, step2, dst, step, width, height); } void min8s(const schar* src1, size_t step1, const schar* src2, size_t step2, schar* dst, size_t step, int width, int height); void min8s(const schar* src1, size_t step1, const schar* src2, size_t step2, schar* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn542 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn542 = { &(__cv_trace_location_extra_fn542),   __FUNCSIG__   , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 542, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn542);;; bin_loop<op_min, schar, v_int8>(src1, step1, src2, step2, dst, step, width, height); } void min16u(const ushort* src1, size_t step1, const ushort* src2, size_t step2, ushort* dst, size_t step, int width, int height); void min16u(const ushort* src1, size_t step1, const ushort* src2, size_t step2, ushort* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn542 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn542 = { &(__cv_trace_location_extra_fn542),   __FUNCSIG__   , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 542, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn542);;; bin_loop<op_min, ushort, v_uint16>(src1, step1, src2, step2, dst, step, width, height); } void min16s(const short* src1, size_t step1, const short* src2, size_t step2, short* dst, size_t step, int width, int height); void min16s(const short* src1, size_t step1, const short* src2, size_t step2, short* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn542 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn542 = { &(__cv_trace_location_extra_fn542),   __FUNCSIG__   , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 542, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn542);;; bin_loop<op_min, short, v_int16>(src1, step1, src2, step2, dst, step, width, height); } void min32s(const int* src1, size_t step1, const int* src2, size_t step2, int* dst, size_t step, int width, int height); void min32s(const int* src1, size_t step1, const int* src2, size_t step2, int* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn542 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn542 = { &(__cv_trace_location_extra_fn542),   __FUNCSIG__   , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 542, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn542);;; bin_loop<op_min, int, v_int32>(src1, step1, src2, step2, dst, step, width, height); } void min32f(const float* src1, size_t step1, const float* src2, size_t step2, float* dst, size_t step, int width, int height); void min32f(const float* src1, size_t step1, const float* src2, size_t step2, float* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn542 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn542 = { &(__cv_trace_location_extra_fn542),   __FUNCSIG__   , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 542, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn542);;; bin_loop<op_min, float, v_float32>(src1, step1, src2, step2, dst, step, width, height); } void min64f(const double* src1, size_t step1, const double* src2, size_t step2, double* dst, size_t step, int width, int height); void min64f(const double* src1, size_t step1, const double* src2, size_t step2, double* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn542 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn542 = { &(__cv_trace_location_extra_fn542),   __FUNCSIG__   , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 542, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn542);;; bin_loop_nosimd<op_min, double, v_float64>(src1, step1, src2, step2, dst, step, width, height); }
    void max8u(const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height); void max8u(const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn543 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn543 = { &(__cv_trace_location_extra_fn543),   __FUNCSIG__   , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 543, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn543);;; bin_loop<op_max, uchar, v_uint8>(src1, step1, src2, step2, dst, step, width, height); } void max8s(const schar* src1, size_t step1, const schar* src2, size_t step2, schar* dst, size_t step, int width, int height); void max8s(const schar* src1, size_t step1, const schar* src2, size_t step2, schar* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn543 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn543 = { &(__cv_trace_location_extra_fn543),   __FUNCSIG__   , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 543, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn543);;; bin_loop<op_max, schar, v_int8>(src1, step1, src2, step2, dst, step, width, height); } void max16u(const ushort* src1, size_t step1, const ushort* src2, size_t step2, ushort* dst, size_t step, int width, int height); void max16u(const ushort* src1, size_t step1, const ushort* src2, size_t step2, ushort* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn543 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn543 = { &(__cv_trace_location_extra_fn543),   __FUNCSIG__   , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 543, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn543);;; bin_loop<op_max, ushort, v_uint16>(src1, step1, src2, step2, dst, step, width, height); } void max16s(const short* src1, size_t step1, const short* src2, size_t step2, short* dst, size_t step, int width, int height); void max16s(const short* src1, size_t step1, const short* src2, size_t step2, short* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn543 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn543 = { &(__cv_trace_location_extra_fn543),   __FUNCSIG__   , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 543, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn543);;; bin_loop<op_max, short, v_int16>(src1, step1, src2, step2, dst, step, width, height); } void max32s(const int* src1, size_t step1, const int* src2, size_t step2, int* dst, size_t step, int width, int height); void max32s(const int* src1, size_t step1, const int* src2, size_t step2, int* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn543 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn543 = { &(__cv_trace_location_extra_fn543),   __FUNCSIG__   , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 543, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn543);;; bin_loop<op_max, int, v_int32>(src1, step1, src2, step2, dst, step, width, height); } void max32f(const float* src1, size_t step1, const float* src2, size_t step2, float* dst, size_t step, int width, int height); void max32f(const float* src1, size_t step1, const float* src2, size_t step2, float* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn543 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn543 = { &(__cv_trace_location_extra_fn543),   __FUNCSIG__   , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 543, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn543);;; bin_loop<op_max, float, v_float32>(src1, step1, src2, step2, dst, step, width, height); } void max64f(const double* src1, size_t step1, const double* src2, size_t step2, double* dst, size_t step, int width, int height); void max64f(const double* src1, size_t step1, const double* src2, size_t step2, double* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn543 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn543 = { &(__cv_trace_location_extra_fn543),   __FUNCSIG__   , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 543, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn543);;; bin_loop_nosimd<op_max, double, v_float64>(src1, step1, src2, step2, dst, step, width, height); }
    
    void absdiff8u(const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height); void absdiff8u(const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn545 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn545 = { &(__cv_trace_location_extra_fn545),   __FUNCSIG__   , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 545, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn545);;; bin_loop<op_absdiff, uchar, v_uint8>(src1, step1, src2, step2, dst, step, width, height); } void absdiff8s(const schar* src1, size_t step1, const schar* src2, size_t step2, schar* dst, size_t step, int width, int height); void absdiff8s(const schar* src1, size_t step1, const schar* src2, size_t step2, schar* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn545 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn545 = { &(__cv_trace_location_extra_fn545),   __FUNCSIG__   , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 545, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn545);;; bin_loop<op_absdiff, schar, v_int8>(src1, step1, src2, step2, dst, step, width, height); } void absdiff16u(const ushort* src1, size_t step1, const ushort* src2, size_t step2, ushort* dst, size_t step, int width, int height); void absdiff16u(const ushort* src1, size_t step1, const ushort* src2, size_t step2, ushort* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn545 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn545 = { &(__cv_trace_location_extra_fn545),   __FUNCSIG__   , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 545, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn545);;; bin_loop<op_absdiff, ushort, v_uint16>(src1, step1, src2, step2, dst, step, width, height); } void absdiff16s(const short* src1, size_t step1, const short* src2, size_t step2, short* dst, size_t step, int width, int height); void absdiff16s(const short* src1, size_t step1, const short* src2, size_t step2, short* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn545 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn545 = { &(__cv_trace_location_extra_fn545),   __FUNCSIG__   , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 545, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn545);;; bin_loop<op_absdiff, short, v_int16>(src1, step1, src2, step2, dst, step, width, height); } void absdiff32s(const int* src1, size_t step1, const int* src2, size_t step2, int* dst, size_t step, int width, int height); void absdiff32s(const int* src1, size_t step1, const int* src2, size_t step2, int* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn545 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn545 = { &(__cv_trace_location_extra_fn545),   __FUNCSIG__   , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 545, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn545);;; bin_loop<op_absdiff, int, v_int32>(src1, step1, src2, step2, dst, step, width, height); } void absdiff32f(const float* src1, size_t step1, const float* src2, size_t step2, float* dst, size_t step, int width, int height); void absdiff32f(const float* src1, size_t step1, const float* src2, size_t step2, float* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn545 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn545 = { &(__cv_trace_location_extra_fn545),   __FUNCSIG__   , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 545, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn545);;; bin_loop<op_absdiff, float, v_float32>(src1, step1, src2, step2, dst, step, width, height); } void absdiff64f(const double* src1, size_t step1, const double* src2, size_t step2, double* dst, size_t step, int width, int height); void absdiff64f(const double* src1, size_t step1, const double* src2, size_t step2, double* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn545 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn545 = { &(__cv_trace_location_extra_fn545),   __FUNCSIG__   , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 545, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn545);;; bin_loop_nosimd<op_absdiff, double, v_float64>(src1, step1, src2, step2, dst, step, width, height); }
    
    void or8u(const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height); void or8u(const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn547 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn547 = { &(__cv_trace_location_extra_fn547),   __FUNCSIG__   , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 547, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn547);;; bin_loop<op_or, uchar, v_uint8>(src1, step1, src2, step2, dst, step, width, height); }
    void xor8u(const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height); void xor8u(const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn548 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn548 = { &(__cv_trace_location_extra_fn548),   __FUNCSIG__   , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 548, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn548);;; bin_loop<op_xor, uchar, v_uint8>(src1, step1, src2, step2, dst, step, width, height); }
    void and8u(const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height); void and8u(const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn549 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn549 = { &(__cv_trace_location_extra_fn549),   __FUNCSIG__   , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 549, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn549);;; bin_loop<op_and, uchar, v_uint8>(src1, step1, src2, step2, dst, step, width, height); }
    

    相关文章

      网友评论

          本文标题:OpenCV源码浅析——MatExpr到Mat是怎么赋值的?

          本文链接:https://www.haomeiwen.com/subject/iqljvhtx.html