OpenCV isContinuous()连续存储的问题

标签: isContinuous Mat图像连续存储 OpenCV isContinuous
573人阅读 评论(0) 收藏 举报
分类:

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()一份后又连续了.




      
查看评论

OpenCV

-
  • 1970年01月01日 08:00

使用OpenCV时的小技巧(待续)

1、  图像的遍历 OpenCV图像遍历最高效的方法是指针遍历方法。因为图像在OpenCV里的存储机制问题,行与行之间可能有空白单元(一般是补够4的倍数或8的倍数,有些地方也称作“位对齐”,目前我用到...
  • kaka_36
  • kaka_36
  • 2014-01-20 14:24:38
  • 4527

【OpenCV】访问Mat中每个像素的值(新)

在《OpenCV 2 Computer Vision Application Programming Cookbook》看到的例子,非常不错,算是对之前的文章的回顾和补充。Color Reduce还是...
  • xiaowei_cqu
  • xiaowei_cqu
  • 2014-02-24 21:02:45
  • 109757

OpenCV参考手册之Mat类详解(三)

Mat::eye 返回一个恒等指定大小和类型矩阵。 C++: static MatExpr Mat::eye(int rows, int cols, inttype) C++: static MatE...
  • giantchen547792075
  • giantchen547792075
  • 2013-06-16 20:31:33
  • 85242

isContinuous 反色处理

cv::Mat inverseColor5(cv::Mat srcImage) { int row = srcImage.rows; int col = srcImage.cols; cv::M...
  • Gone_HuiLin
  • Gone_HuiLin
  • 2016-11-18 20:11:39
  • 311

OpenCV中Mat的data成员解析

OpenCV 自2.x版本以来,处理图像的主要数据结构从CvMat变成了Mat,下面是OpenCV官方文档对Mat的描述: class CV_EXPORTS Mat { public: // ... ...
  • zy122121cs
  • zy122121cs
  • 2015-07-24 17:43:57
  • 14341

OpenCV isContinuous()连续存储的问题

OpenCV isContinuous()连续存储的问题 如果矩阵元素在每行末尾连续存储而没有间隙,则方法返回true。 否则,它返回false。 显然,对于1x1或1xN矩阵总是连续的。一般...
  • guyuealian
  • guyuealian
  • 2017-11-23 20:15:19
  • 573

Background Modeling and Foreground Detection -- SOBS

Paper A Self-Organizing Approach to Background Subtraction for Visual Surveillance Applications The ...
  • ZengDong_1991
  • ZengDong_1991
  • 2016-06-12 16:15:04
  • 785

(转载)车牌识别EasyPR--开发详解

非常详细的讲解车牌识别 转载自:http://www.cnblogs.com/subconscious/p/3979988.html               http://www.cnblogs...
  • liuuze5
  • liuuze5
  • 2015-05-31 18:17:10
  • 19587

opencv异常提示之 (channels() == CV_MAT_CN(dtype)) in copyTo (暂未解决,提供源码)

OpenCV Error: Assertion failed (channels() == CV_MAT_CN(dtype)) in copyTo, file /home/tau/opencv/ope...
  • traumland
  • traumland
  • 2016-05-01 23:11:12
  • 4714
    个人资料
    专栏达人 持之以恒
    等级:
    访问量: 68万+
    积分: 6908
    排名: 4206
    博客专栏
    最新评论