• penCV isContinuous()连续存储的问题


    转置:(221条消息) OpenCV isContinuous()连续存储的问题_pan_jinquan的博客-CSDN博客

    OpenCV isContinuous()连续存储的问题

    pan_jinquan

    于 2017-11-23 20:15:19 发布

    10126
    收藏 18
    分类专栏: OpenCV 文章标签: isContinuous Mat图像连续存储 OpenCV isContinuous
    版权

    OpenCV
    专栏收录该内容
    33 篇文章28 订阅
    订阅专栏
    OpenCV isContinuous()连续存储的问题
    【尊重原创,转载请注明出处】http://blog.csdn.net/guyuealian/article/details/78614662
    一、OpenCV isContinuous()函数:
    定义:
    bool cv::Mat::isContinuous() const

    说明:
    报告矩阵是否连续。
    如果矩阵元素在每行末尾连续存储而没有间隙,则方法返回true。 否则,它返回false。 显然,对于1x1或1xN矩阵总是连续的。一般 用Mat :: create创建的矩阵总是连续的。 但是,如果使用Mat :: col,Mat :: diag等提取矩阵的一部分,或者为外部分配的数据构造矩阵头,则此类矩阵可能不再具有此属性。
    连续性标志存储在Mat :: flags字段中,并在构造矩阵标题时自动计算。 因此,连续性检查是一个非常快的操作,虽然理论上可以这样做:
    // alternative implementation of Mat::isContinuous()
    bool myCheckMatContinuity(const Mat& m)
    {
    //return (m.flags & Mat::CONTINUOUS_FLAG) != 0;
    return m.rows == 1 || m.step == m.cols*m.elemSize();//检测内存存储连续性
    }
    这个isContinuous方法在很多OpenCV函数中都有使用。 重点在于元素操作(例如算术和逻辑操作,数学函数,alpha 混合,颜色空间变换等)不依赖于图像几何。 因此,如果所有的输入和输出数组都是连续的,那么函数可以将它们处理为非常长的单行向量。 下面的例子说明了如何实现一个alpha混合(透明混合)函数:
    template<typename T>
    void alphaBlendRGBA(const Mat& src1, const Mat& src2, Mat& dst)
    {
    const float alpha_scale = (float)std::numeric_limits<T>::max(),
    inv_scale = 1.f/alpha_scale;
    CV_Assert( src1.type() == src2.type() &&
    src1.type() == CV_MAKETYPE(DataType<T>::depth, 4) &&
    src1.size() == src2.size());
    Size size = src1.size();
    dst.create(size, src1.type());
    // here is the idiom: check the arrays for continuity and,
    // if this is the case,
    // treat the arrays as 1D vectors
    if( src1.isContinuous() && src2.isContinuous() && dst.isContinuous() )
    {
    size.width *= size.height;
    size.height = 1;
    }
    size.width *= 4;
    for( int i = 0; i < size.height; i++ )
    {
    // when the arrays are continuous,
    // the outer loop is executed only once
    const T* ptr1 = src1.ptr<T>(i);
    const T* ptr2 = src2.ptr<T>(i);
    T* dptr = dst.ptr<T>(i);
    for( int j = 0; j < size.width; j += 4 )
    {
    float alpha = ptr1[j+3]*inv_scale, beta = ptr2[j+3]*inv_scale;
    dptr[j] = saturate_cast<T>(ptr1[j]*alpha + ptr2[j]*beta);
    dptr[j+1] = saturate_cast<T>(ptr1[j+1]*alpha + ptr2[j+1]*beta);
    dptr[j+2] = saturate_cast<T>(ptr1[j+2]*alpha + ptr2[j+2]*beta);
    dptr[j+3] = saturate_cast<T>((1 - (1-alpha)*(1-beta))*alpha_scale);
    }
    }
    }

    这种方法虽然非常简单,但是可以将简单元素操作的性能提高10-20%,特别是如果图像相当小并且操作非常简单。
    在这个函数中的另一个OpenCV习惯用法,调用目标数组的Mat :: create,除非它已经具有适当的大小和类型,否则分配目标数组。 而新分配的数组总是连续的,你仍然需要检查目标数组,因为Mat :: create并不总是分配一个新的矩阵。
    用Mat存储一幅图像时,若图像在内存中是连续存储的(Mat对象的isContinuous == true),则可以将图像的数据看成是一个一维数组,而data(uchar*)成员就是指向图像数据的第一个字节的,因此可以用data指针访问图像的数据,从而加速Mat图像的访问速度。
    一般经过裁剪的Mat图像,都不再连续了,如cv::Mat crop_img = src(rect);crop_img 是不连续的Mat图像,如果想转为连续的,最简单的方法,就是将不连续的crop_img 重新clone()一份给新的Mat就是连续的了,如:


    Mat src = imread("D:\\OpencvTest\\B1.jpg");//原始图像是200*200
    cv::imshow("src", src);
    printf("---src.isContinuous=%d", src.isContinuous()); printf("\n");//直接imread的Mat是连续的
    cv::Rect rect(1, 1, 100, 100);
    cv::Mat crop_img = src(rect);//裁剪后的图像是不连续的
    cv::imshow("crop_img", crop_img);
    printf("---crop_img.isContinuous=%d", crop_img.isContinuous()); printf("\n");
    cv::Mat crop_img2;
    //crop_img2.create(crop_img2.size(), crop_img2.type());
    crop_img2 = crop_img.clone();//重新clone()后的图像是连续的
    printf("---crop_img2.isContinuous=%d", crop_img2.isContinuous()); printf("\n");
    运行结果:显然,裁剪后的Mat图像不再连续,而重新clone()一份后又连续了.

    ————————————————
    版权声明:本文为CSDN博主「pan_jinquan」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/guyuealian/article/details/78614662

  • 相关阅读:
    编写 grunt 插件经验
    Sencha Touch 手机移动开发框架 HTML5 项目压缩方案;
    随笔 编辑推荐 上头条了, 贴出来做个记念!
    Javascript 俄罗斯方块 游戏代码解释!
    30天自制操作系统(NASM+GCC版)
    Logisim 打不开的解决方案(Windows10)
    Kali Linux 2020通过UEFI硬盘安装(免u盘)
    开源一个自制的ORM框架,基于Java原生JDBC(应该是全网首个吧)
    书单
    前端技术文章收集
  • 原文地址:https://www.cnblogs.com/MCSFX/p/15947209.html
Copyright © 2020-2023  润新知