天天看點

opencv3.0 Mat元素求和

找了很久,沒找到可以直接求元素和的函數。

但找到了 對圖像資料元素進行操作的三個方式:

方法一:指針通路:C操作符[];

方法二:疊代器iterator;

方法三:動态計算。

方法一:指針通路方式

void sumMat(Mat& inputImg, double sum, double mean)
{
	sum = 0.0;
	int rowNumber = inputImg.rows;
	int colNumber = inputImg.cols * inputImg.channels();
	for (int i = 0; i < rowNumber;i++)
	{
		uchar* data = inputImg.ptr<uchar>(i);
		for (int j = 0; j < colNumber; j++)
		{
			sum = data[j] + sum;
		}
	}
	mean = sum / rowNumber * inputImg.cols;
}
           

下面是一篇關于各種 opencv矩陣運算的 轉載文章:

一、矩陣

Mat I,img,I1,I2,dst,A,B;

double k,alpha;

Scalar s;

1.加法

I=I1+I2;//等同add(I1,I2,I);

add(I1,I2,dst,mask,dtype);

scaleAdd(I1,scale,I2,dst);//dst=scale*I1+I2;

2.減法

absdiff(I1,I2,I);//I=|I1-I2|;

A-B;A-s;s-A;-A;

subtract(I1,I2,dst);

3.乘法

I=I.mul(I);//點乘,I.mul(I,3);-->I=3*I.^2

Mat C=A.mul(5/B);//==divide(A,B,C,5);

A*B;矩陣相乘

I=alpha*I;

Mat::cross(Mat);//三維向量(或矩陣)的叉乘,A.cross(B)

double Mat::dot(Mat);//2個向量(或矩陣)的點乘的結果,A.dot(B)

mul-------multiply

pow(src,double p,dst);//如果p是整數dst(I)=src(I)^p;其他|src(I)|^p

4.除法

divide(I1,I2,dst,scale,int dtype=-1);//dst=saturate_cast(I1*scale/I2);

A/B;alpha/A;都是點除

5.轉換

I.convertTo(I1,CV_32F);//類型轉換

A.t();//轉置

flip(I,dst,int flipCode);//flipCode=0是上下翻轉,>0時左右翻轉,<0時一起來

sqrt(I,dst);

cvtColor(I,dst,int code,int dstCn=0);

resize:對圖像進行形變

--------------------------------------------------------------------------

6.其他

Scalar s=sum(I);各通道求和

norm,countNonZero,trace,determinant,repeat都是傳回Mat或者Scalar

countNonZero:用來統計非零的向量個數.(rows*cols個)

Scalar m=mean(I);//各通道求平均

Mat RowClone=C.row(1).clone();//複制第2行

addWeight(I1,alpha,I2,beta,gamma,dst,int dtype=-1);//dst=saturate(alpha*I1+beta*I2+gamma);dtype是dst的深度

----------------------------------------------------------------------------

7.運算符

log10()

exp(I,dst);//dst=exp(I);計算每個數組元素的指數

log(I,dst);//如果Iij!=0;則dstij=log(|Iij|)

randu(I,Scalar::all(0),Scalar::all(255));

Mat::t()轉置

Mat::inv(int method=DECOMP_LU)求逆。method=DECOMP_CHOLESKY(專門用于對稱,速度是LU的2倍),DECOMP_SVD//A.inv();A.inv()*B;

invert(I1,dst,int method=DECOMP_LU);//用法同上

MatExpr abs(Mat)//求絕對值

A cmpop B;A compop alpha;alpha cmpop A;這裡cmpop表示>,>=,==,!=,<=,<等,結果是CV_8UC1的mask的0或255

按位運算:A logicop B;A logicop s;s logicop A;~A;這裡logicop代表&,|,^

bitwise_not(I,dst,mask);//inverts所有的隊列

還有bitwise_and,bitwise_or,bitwise_xor,

min(A,B);min(A,alpha);max(A,B);max(A,alpha);都傳回MatExpr,傳回的dst和A的類型一樣

double determinant(Mat);//行列式

bool eigen(I1,dst,int lowindex=-1,int highindex=-1);//

bool eigen(I1,dst,I,int...);//得到特征值向量dst和對應特征值的特征向量

minMaxLoc(I1,&minVal,&maxVal,Point *minLoc=0,Point* MaxLoc=0,mask);

//minLoc是2D時距原點最小的點(未考證)

------------------------------------------------------------------------------

8.初始化

Mat I(img,Rect(10,10,100,100));//用一塊地方初始化。

Mat I=img(Range:all(),Range(1,3));//所有行,1~3列

Mat I=img.clone();//完全複制

img.copyTo(I);//傳遞矩陣頭

Mat I(2,2,CV_8UC3,Scalar(0,0,255));//I=[0,0,255,0,0,255;0,0,255,0,0,255];

Mat E=Mat::eye(4,4,CV_64F);//對角矩陣

Mat O=Mat::ones(2,2,CV_32F);//全一矩陣

Mat Z=Mat::zeros(3,3,CV_8UC1);//全零矩陣

Mat C=(Mat_<double>(2,2)<<0,-1,2,3);//如果是簡單矩陣的初始化

Mat::row(i);Mat::row(j);Mat::rowRange(start,end);Mat::colRange(start,end);都隻是建立個頭

Mat::diag(int d);d=0是是主對角線,d=1是比主低的對角線,d=-1....

static Mat Mat::diag(const Mat& matD)

Mat::setTo(Scalar &s);以s初始化矩陣

Mat::push_back(Mat);在原來的Mat的最後一行後再加幾行

Mat::pop_back(size_t nelems=1);//移出最下面幾行

-------------------------------------------------------------------------------

9.矩陣讀取和修改

(1)1個通道:

for(int i=0;i<I.rows;++i)

for(int j=0;j<I.cols;++j)

I.at<uchar>(i,j)=k;

(2)3個通道:

Mat_<Vec3b> _I=I;//他沒有4個通道寸,隻有3個通道!

for(int i=0;i<I.rows;++i)

for(int j=0;j<I.cols;++j)

{

_I(i,j)[0]=b;

_I(i,j)[1]=g;

_I(i,j)[2]=r;

}

I=_I;

------------------------------------------------------------

或者直接用I.at<Vec3b>(i,j)[0]....

-------------------------------------------------

float *s;

for(i=0;i<dealImg.rows;i++)

{s=proImg.ptr<float>(i);

for(j=0;j<dealImg.cols;j++)

{a1=s[3*j+1]-m1;

a2=s[3*j+2]-m2;}}

-------------------------------------------------------------------------

(3)其他機制

I.rows(0).setTo(Scalar(0));//把第一行清零

saturate_cast<uchar>(...);//可以確定内容為0~255的整數

Mat::total();傳回一共的元素數量

size_t Mat::elemSize();傳回元素的大小:CV_16SC3-->3*sizeof(short)-->6

size_t Mat::elemSize1();傳回元素一個通道的大小CV_16SC3-->sizeof(short)-->2

int Mat::type()傳回他的類型CV_16SC3之類

int Mat::depth()傳回深度:CV_16SC3-->CV_16S

int Mat::channels()傳回通道數

size_t Mat:step1()傳回一個被elemSize1()除以過的step

Size Mat::size()傳回Size(cols,rows);如果大于2維,則傳回(-1,-1),都是先寬再高的

bool Mat::empty()如果沒有元素傳回1,即Mat::total()==0或者Mat::data==NULL

uchar *Mat::ptr(int i=0)指向第i行

Mat::at(int i)(int i,int j)(Point pt)(int i,int j,int k)

RNG随機類:next,float RNG::uniform(float a,float b);..

double RNG::gaussian(double sigma);

RNG::fill(I,int distType,Mat low,Mat up);//用随機數填充

randu(I,low,high);

randn(I,Mat mean,Mat stddev);

reduce(I,dst,int dim,int reduceOp,int dtype=-1);//可以統計每行或每列的最大、最小、平均值、和

setIdentity(dst,Scalar &value=Scalar(1));//把對角線替換為value

//效果等同:Mat A=Mat::eye(4,3,CV_32F)*5;

--------------------------------------------------------------

10.較複雜運算

gemm(I1,I2,alpha,I3,beta,dst,int flags=0);//I1至少是浮點型,I2同I1,flags用來轉置

//gemm(I1,I2,alpha,I3,beta,dst,GEMM_1_T,GEMM_3_T);-->dst=alpha*I1.t()*I2+beta*I3.t();可用此完全代替此函數

mulTransposed(I,dst,bool aTa,Mat delta=noArray(),double scale=1,int rtype=-1);

//I是1通道的,和gemm不同,他可用于任何類型。

//如果aTa=flase時,dst=scale*(I-delta).t()*(I-delta);

//如果是true,dst=scale*(I-delta)(I-delta).t();

calcCovarMatrix(Mat,int,Mat,Mat,int,int=);calcCovarMatrix(Mat I,Mat covar,Mat mean,int flags,int=);

cartToPolar//轉到極坐标

compare(I1,I2,dst,cmpop);cmpop=CMP_EQ,CMP_GT,CMP_GE,CMP_LT,CMP_LE,COM_NE

completeSymm(M,bool lowerToUpper=false);當lowerToUpper=true時Mij=Mji(i<j);當為flase時,Mij=Mji(i>j)

變成可顯示圖像:convertScaleAbs(I,dst,alpha,beta);dst=saturate_cast<uchar>(|alpha*I+beta|);

dct(I,dst,int flags=0);//DCT變換,1維、2維的矩陣;flags=DCT_INVERSE,DCT_ROWS

idct,dft,idft

inRange(I1,I_low,I_up,dst);//dst是CV_8UC1,在2者之間就是255

Mahalanobis(vec1,vec2,covar);

merge(vector<Mat>,Mat);//把多個Mat組合成一個和split相反

double norm(...):當src2木有時,norm可以計算出最長向量、向量距離和、向量距離和的算術平方根

solveCubic解3次方程,solvePoly解n次方程

排列:sort,sortIdx

mixChannels();對某個通道進行各種傳遞

-----------------------------------------------------------------

11.未懂的函數

getConvertElem,extractImageCOI,LUT

magnitude(x,y,dst);//I1,I2都是1維向量,dst=sqrt(x(I)^2+y(I)^2);

meanStdDev,

MulSpectrums(I1,I2,dst,flags);傅裡葉

normalize(I,dst,alpha,beta,int normType=NORM_L2,int rtype=-1,mask);//歸一化

PCA,SVD,solve,transform,transpose

二、其他資料結構

Point2f P(5,1);

Point3f P3f(2,6,7);

vector<float> v;v.push_back((float)CV_PI);v.push_back(2);v.push_back(3.01f);//不斷入

vector<Point2f> vPoints(20);//一次定義20個

三、常用方法

Mat mask=src<0;這樣很快建立一個mask了

四、以後可能用到的函數

randShuffle,repeat