参考手册
Mat
Mat::isContinuous()
说明:
报告矩阵是否连续。
如果矩阵元素在每行末尾连续存储而没有间隙,则方法返回true。 否则,它返回false。 显然,对于1x1或1xN矩阵总是连续的。一般 用Mat :: create创建的矩阵总是连续的。 但是,如果使用Mat :: col,Mat :: diag等提取矩阵的一部分,或者为外部分配的数据构造矩阵头,则此类矩阵可能不再具有此属性。
OpenCV isContinuous()连续存储的问题_pan_jinquan的博客-CSDN博客
Mat(int rows, int cols, int type, void* data, size_t step=AUTO_STEP);
Mat::Mat(int _rows, int _cols, int _type, void* _data, size_t _step) : flags(MAGIC_VAL + (_type & TYPE_MASK)), dims(2), rows(_rows), cols(_cols), data((uchar*)_data), datastart((uchar*)_data), dataend(0), datalimit(0), allocator(0), u(0), size(&rows) { CV_Assert(total() == 0 || data != NULL); size_t esz = CV_ELEM_SIZE(_type), esz1 = CV_ELEM_SIZE1(_type); size_t minstep = cols * esz; if( _step == AUTO_STEP ) { _step = minstep; } else { CV_Assert( _step >= minstep ); if (_step % esz1 != 0) { CV_Error(Error::BadStep, "Step must be a multiple of esz1"); } } step[0] = _step; step[1] = esz; datalimit = datastart + _step * rows; dataend = datalimit - _step + minstep; updateContinuityFlag(); } inline const size_t& MatStep::operator[](int i) const CV_NOEXCEPT { return p[i]; } template<typename _Tp> _Tp& at(int row, int col) { return ((_Tp*)(data + step.p[0] * i0))[i1]; }
由上面可见,step[0]指向step.p[0],即p[0]为每行占据的字节数,p[1]为每个像素占据的字节数。
depth 和channels
CV_8UC4 CV_MAKETYPE(CV_8U,4),其中4为channels()(通道数), CV_8U为 depth()
inline int Mat::depth() const { // ((flags) & CV_MAT_DEPTH_MASK) => // (flags & (CV_DEPTH_MAX - 1)) return CV_MAT_DEPTH(flags); } inline int Mat::channels() const { // ((((flags) & CV_MAT_CN_MASK) >> CV_CN_SHIFT) + 1) => // ((((flags) & ((CV_CN_MAX - 1) << CV_CN_SHIFT)) >> CV_CN_SHIFT) + 1) => // (((flags & (511 << CV_CN_SHIFT)) >> CV_CN_SHIFT) + 1) // CV_8UC4 => (CV_MAT_DEPTH(0) + (((4)-1) << CV_CN_SHIFT)) // => (((0) & CV_MAT_DEPTH_MASK) + (((4)-1) << CV_CN_SHIFT)) // => ((0 & CV_MAT_DEPTH_MASK) + (3 << CV_CN_SHIFT)) // 从上可以看出CV_8UC4 CV_MAKETYPE(CV_8U,4),其中4为通道数, CV_8U为 depth() return CV_MAT_CN(flags); } #define CV_CN_MAX 512 #define CV_CN_SHIFT 3 #define CV_DEPTH_MAX (1 << CV_CN_SHIFT) #define CV_MAT_CN_MASK ((CV_CN_MAX - 1) << CV_CN_SHIFT) #define CV_MAT_CN(flags) ((((flags) & CV_MAT_CN_MASK) >> CV_CN_SHIFT) + 1) #define CV_MAT_CN(flags) ((((flags) & CV_MAT_CN_MASK) >> CV_CN_SHIFT) + 1) #define CV_MAT_DEPTH_MASK (CV_DEPTH_MAX - 1) #define CV_MAT_DEPTH(flags) ((flags) & CV_MAT_DEPTH_MASK) #define CV_8U 0 #define CV_8S 1 #define CV_16U 2 #define CV_16S 3 #define CV_32S 4 #define CV_32F 5 #define CV_64F 6 #define CV_16F 7 #define CV_MAKETYPE(depth,cn) (CV_MAT_DEPTH(depth) + (((cn)-1) << CV_CN_SHIFT)) #define CV_8UC3 CV_MAKETYPE(CV_8U,3) #define CV_8UC4 CV_MAKETYPE(CV_8U,4)
从上可知:
0-2位代表depth即数据类型(如CV_8U),OpenCV的数据类型共7类,故只需3位即可全部表示。
3-11位代表通道数channels,因为OpenCV默认最大通道数为512,故只需要9位即可全部表示,可参照下面求通道数的部分。
0-11位共同代表type即通道数和数据类型(如CV_8UC3)
12-13位暂没发现用处,也许是留着后用,待发现了再补上。
14位代表Mat的内存是否连续,一般由creat创建的mat均是连续的,如果是连续,将加快对数据的访问。
15位代表该Mat是否为某一个Mat的submatrix,一般通过ROI以及row()、col()、rowRange()、colRange()等得到的mat均为submatrix。
16-31代表magic signature,暂理解为用来区分Mat的类型,如果Mat和SparseMat
【OpenCV】从Mat的flags中可以读到的信息,以及相关宏定义_YiYueHuan的博客-CSDN博客
cv::Mat属性 step, size, step1, elemSize, elemSize1_AI_潜行者的博客-CSDN博客_cv::mat size
elemSize():每个元素大小,单位字节 (CV_8UC3中值为3,RGB三个字节?)
elemSize1():每个通道大小,单位字节 (CV_8UC3中值为1,?)
矩阵操作
cv::normalize
OPENCV函数介绍:normalize()_page190017的博客-CSDN博客_cv::normalize
opencv函数介绍(1)——normalize_cosmispower的博客-CSDN博客_cv::normalize
OpenCV-矩阵归一化cv::normalize_翟天保Steven的博客-CSDN博客_cv::normalize
void normalize( InputArray src, OutputArray dst, double alpha = 1, double beta = 0, int norm_type = NORM_L2, int dtype = -1, InputArray mask = noArray()); /* 参数说明 InputArray类型的src,输入图像,如Mat类型。 OutputArray类型的dst,输出图像。 double类型的alpha,归一化相关的数值。 double类型的beta,归一化相关的数值。 int类型的norm_type,归一化类型。 int类型的dtype,默认值-1,与输出矩阵的类型和通道相关。 InputArray类型的mask,掩膜。 */
针对第三个参数alpha和第四个参数beta,在不同归一化类型时,作用不一样:
- NORM_MINMAX :alpha和beta的最大值是归一化的最大值,两者的最小值是归一化的最小值,alpha为1,beta为0,同alpha为0,beta为1,是一致的。
- NORM_INF:beta值无用;输出矩阵的数值为,原始矩阵数值除以矩阵最大值的结果,alpha可以控制倍数。
- NORM_L1:beta值无用;输出矩阵的数值为,原始矩阵数值除以矩阵数据绝对值和的结果,alpha可以控制倍数。
- NORM_L2:beta值无用;输出矩阵的数值为,原始矩阵数值除以矩阵数据平方和再开根号的结果,alpha可以控制倍数。
Mat::reshape()
知识学习:OpenCV3学习 Mat::reshape()的用法_鲜花儿的博客-CSDN博客_cv mat reshape
OpenCV中的Resize函数和Reshape函数 - 程序员大本营
cv::warpAffine
【OpenCV3】图像旋转与平移——cv::warpAffine()详解_PHILOS_THU的博客-CSDN博客_opencv 平移
opencv边界扩充_ab0902cd的博客-CSDN博客_opencv边界扩展
【CV学习笔记】图像预处理warpaffine-pudn.com
2.cv2.BORDER_REPLICATE(边界补零复制操作)... - python我的最爱 - 博客园
cv2.BORDER_REPLICATE: 进行复制的补零操作, 只对边缘的点进行复制,然后该列上的点都是这些
cv2.BORDER_REFLECT: 进行翻转的补零操作,举例只对当前对应的边缘 gfedcba|abcdefgh|hgfedcb
cv2.BORDER_REFLECT_101: 进行翻转的补零操作, gfedcb|abcdefgh|gfedcb
cv2.BORDER_WRAP: 进行上下边缘调换的外包复制操作 bcdegh|abcdefgh|abcdefg
用cv::Scalar来设置opencv中图片的颜色 - PhoenixTree(梧桐树) - 博客园
cv::solve
OpenCV最小二乘法:cv::solve函数_热血青年--Boy的博客-CSDN博客_opencv solve
22_OpenCV中求解方程的一系列cv::solve...()函数_小地瓜重新去华容道工作的博客-CSDN博客_opencv solve
插值
图像插值-最近邻插值(nearest)_cartes1us的博客-CSDN博客_nearest插值