OpenCV 2.4.3 Cheat Sheet学习

来源:互联网 发布:删除存储过程 sql 编辑:程序博客网 时间:2024/06/05 19:56

一、矩阵基础操作:
Mat image(240, 320, CV8UC3);
第一个参数是rows,该矩阵的行数;第二个参数是cols,该矩阵的列数;第三个参数是该矩阵元素的类型。这句话表示创建一个大小为240×320的矩阵,里面的元素为8unsigned型,通道数(channel)3个。

image.create(480, 640, CV8UC3);
分配(或重新分配)image矩阵,把大小设为480×640,类型设为CV8UC3

Mat A33(3, 3, CV_32F, Scalar(5));
定义并初始化一个3×332bit浮点数矩阵,每个元素都设为5

Mat B33(3, 3, CV_32F);
B33 = Scalar(5);
和上面的作用一样。

Mat C33 = Mat::ones(3, 3, CV32F)*5.;
ones
函数很像MATLAB里的语句吧。这句的意思是先定义一个3×332bit浮点数矩阵,元素全为1,所有元素再乘以5.0

Mat D33 = Mat::zeros(3, 3, CV32F) + 5.;
和上面类似,先定义个3×332bit浮点数矩阵,元素全为0,再将所有元素加上5.0

double a = CV_PI/3;
Mat A22 = (Mat_(2, 2) << cos(a), -sin(a), sin(a), cos(a));
CV_PI
就是少年派的那个派。第二句这个写法很牛x的样子,我也没见过,不过看样子是创建一个2×2float矩阵,把后面四个三角函数值分别赋给4个元素。

float B22data[] = {cos(a), -sin(a), sin(a), cos(a)};
Mat B22 = Mat(2, 2, CV32F, B22data).clone();
第一句创建一个普通数组B22data,第二句创建一个2×232bit浮点数矩阵,并使用用B22data数组里的值初始化,然后克隆一下赋给B22矩阵。
为什么这里还要克隆一下,不是多此一举吗?不是的,用一个数组去初始化一个矩阵的话,你会发现这个矩阵引用了数组的内存地址。不克隆的话,上面例程的后果是B22data数组、Mat(2,2...)这个临时变量矩阵、B22矩阵这三把勺子都插在同一个碗里。

randu(image, Scalar(0), Scalar(256));
image弄成一个符合正太分布的随机数矩阵,rand表示randomu表示uniform;第二个参数是随机数下限,方括号哦;第三个参数是随机数上限,圆括号。

randn(image, Scalar(128), Scalar(10));
高斯分布的随机数矩阵;第二个参数是均值,第三个参数是标差。

Mat image_alias = image;
没有拷贝里面的数据。

float* Idata=new float[480*640*3];
Mat I(480, 640, CV32FC3, Idata);
第一句定义一个480×640×3×sizeof(float)字节这么大的数组;第二句创建一个矩阵I,引用的是Idata的地址。

vector iptvec(10);
Mat iP(iptvec);
还能和STL一起用啊,以前真不知道。第一句话创建了一个有10Point的向量,注意Point有两个int型元素。第二句创建了一个矩阵,元素类型根据就自动设为CV_32SC2,表示32bit signed int2channel

IplImage* oldC0 = cvCreateImage(cvSize(320,240),16,1);
Mat newC = cvarrToMat(oldC0);
IplImage oldC1 = newC;
CvMat oldC2 = newC;
这是为了把经典的OpenCV图像导成矩阵,第一句创建一个320×240的图像;第二句话把IplImage转成Mat;第三句话把Mat转成IplImage;第四句把Mat转成CvMat

Mat newC2 = cvarrToMat(oldC0).clone();
转换后克隆一下赋值。

vector ptvec = Mat(iP);
Mat又转成vector

(转来转去真复杂对吧)

A33.at(i,j) = A33.at(j,i)+1;
操作A33矩阵在rowicolj处的元素。需要显式指定A33里的元素类型,本例是float

Mat dyImage(image.size(), image.type());
for(int y = 1; y < image.rows-1; y++)
{
  Vec3b* prevRow = image.ptr(y-1);
  Vec3b* nextRow = image.ptr(y+1);
  for(int x = 0; y < image.cols; x++)
    for(int c = 0; c < 3; c++)
      dyImage.at(y,x)[c]

= saturate_cast(nextRow[x][c] - prevRow[x][c]);
}
第一句话创建一个和image大小、类型都一样的矩阵。
Vec3b
是一个预定义的类型,三个无符号字符组成的向量:
typedef Vec Vec3b;
saturate_cast
是一个强制类型转换,把圆括号里的东西转换为尖括号里的类型。
for
循环里的语句是把矩阵dyImage里的元素都赋值为后一行的值减去前一行的值,注意这个矩阵里的值是个具有三个元素的向量,理解为数组就行了,所以用方括号访问。

Mat::iterator it = image.begin(), itEnd = image.end();
for(; it != itEnd; ++it)
  (*it)[1] ^= 255;
用过STL里的迭代器吗?用过的话就不解释了,没用过的还是先看看STL吧。
image每个值(Vec3b向量)的第一个元素和0xFF做异或。


二、矩阵操作(拷贝、洗牌、局部访问):

 

src.copyTo(dst)

src矩阵中的数据拷贝到dst

 

src.convertTo(dst, type, scale, shift)

缩放并转换到另外一种数据类型:

dst:目的矩阵

type:需要的输出矩阵类型,或者更明确的,是输出矩阵的深度,如果是负值(常用-1)则输出矩阵和输入矩阵类型相同

scaleshift:缩放参数,也可以写为alphabeta

这个命令也等价于下面的转换公式:

m(x,y) = saturate_cast(α(*this)(x,y)+β)

 

m.clone()

深度拷贝(啥意思?看《C++ Primer》吧)

 

m.reshape(nch,nrows)

重设矩阵的通道数和行数,不拷贝数据。

nch:新的通道数,若为0则不变

nrows:新的行数,若为0则不变

 

m.row(i), m.col(i)

创建一个矩阵头,指向m矩阵的第i/列,O(1)复杂度,不拷贝数据,新的矩阵头所代表的矩阵和m矩阵的第i/列共享数据。

 

m.rowRange(Range(i1,i2))

m.colRange(Range(j1,j2))

创建一个矩阵头,指向m矩阵的第i1i2行或者第j1j2列,O(1)复杂度,不拷贝数据。

 

m.diag(i)

创建一个矩阵头,指向m矩阵的对角线,生成的是一个单列矩阵,O(1)复杂度,不拷贝数据。i=0时表示主对角线,i>0表示下半边的对角线,i<0表示上半边的对角线。

 

m(Range(i1,i2),Range(j1,j2))

从矩阵m中的第i1行到第i2行以及第j1列到第j2列所划定的范围提取一个小矩阵。

 

m.repeat(ny,nx)

m矩阵贴马赛克,获取一个大矩阵,在y方向上重复ny次,在x方向上重复nx次。

 

flip(src,dst,dir)

翻转矩阵,dir是翻转方向,0表示沿x轴翻转,1表示沿y轴翻转,-1表示沿x轴和y轴都进行翻转。

 

split(...)

把一个多通道矩阵分解为几个单通道矩阵,操作RGB图像之类的最常用了。

 

merge(...)

和上面的操作相反。

 

mixChannels(...)

上面两个函数的一般形式。

 

randShuffle(...)

把矩阵中的元素随机重排

 

 

示例1

Mat imgroi = image(Rect(10, 20, 100, 100));

GaussianBlur(imgroi, imgroi, Size(5, 5), 1.2, 1.2);

第一句话取image的一个区域,第二句话对这个区域进行高斯平滑。

 

示例2

m.row(i) += m.row(j)*alpha;

m矩阵的第j行乘以alpha后加到第i行中。

另外,在Mat::row的介绍中提到,在目前的实现中

A.row(i) = A.row(j);

这样的语句是不行的,改成

A.row(i) = A.row(j) + 0;

或者这样就可以了:

A.row(j).copyTo(A.row(i));

比较神奇~

 

示例3

Rect r(1, 1, 10, 20);

Mat dstroi = dst(Rect(0,10,r.width,r.height));

src(r).convertTo(dstroi, dstroi.type(), 1, 0);

第一句定义一个矩形范围,第二句从dst矩阵中扣出一个ROI区域,第三句把src矩阵中由r定义的范围转换到dstroi中。

 

 

 

三、简单矩阵操作

 

add(), subtract(), multiply(), divide(), absdiff(), bitwiseand(), bitwiseor(), bitwisexor(), max(), min(), compare()

分别是加减乘除、按位与或异或、最大最小之类的。

 

sum(), mean(), meanStdDev(), norm(), countNonZero(), minMaxLoc()

求和、均值、均值方差、矩阵范数、非零个数、最大最小值。

 

exp(), log(), pow(), sqrt(), cartToPolar(), polarToCart()

指数、对数、乘方、开放、极坐标转换。

 

scaleAdd(), transpose(), gemm(), invert(), solve(), determinant(), trace(), eigen(), SVD

线性组合、转置、广义矩阵乘法、矩阵求逆、解线性系统或最小二乘问题、计算行列式、矩阵的迹、计算对称矩阵的特征值和特征向量、奇异值分解

 

dft(), idft(), dct(), idct()

离散傅立叶变换、离散余弦变换


0 0
原创粉丝点击