OpenCV 常用函式(一)
阿新 • • 發佈:2019-01-07
本文主要介紹:Opencv常用函式,如均值、最大最小、歸一化、濾波、旋轉、求連通域等函式。
一、基本函式
//初始化 Mat img = Mat::zeros(Height, Width, CV_8UC1); Mat img = Mat::ones(Height, Width, CV_8UC1); Mat img(Height, Width,CV_32FC1, Scalar(5)); img.create(Height, Width, CV8UC1); //資料型別轉化 img.convertTo(dstImg, dataType); //讀寫影象 imwrite(pathm, img); imread(path, flag); // 0 灰度圖 1 原圖 //顯示影象 namedWindow("name",1); //1 大小和影象相同,視窗不可拉伸 0 視窗可拉伸 imshow("name", img); //可以直接用imshow waitKey(0); //影象上點選Enter退出程式 //矩陣元素訪問 img.at<型別>(i,j) //型別一定和img相同 CV_8UC1 unsigned char CV_32FC1 float CV_64FC1 double // Mat* 元素訪問方式 bins為Mat *bins bins->ptr<float>(i) //判斷讀取資料為空 IplImage* dst1 = cvLoadImage(path.c_str(), 1 ); //rgb圖 if(!src1) { printf("讀取影象 %s 失敗\n", path.c_str()); return false; } img = imread(tempPath, 1); if(!img.data) { printf("序列圖模板匹配時,讀取 %s 模板失敗!\n", tempPath.c_str()); return false; } //求最大最小值 double maxval, minval; minMaxIdx(inImg,&minval,&maxval); //求均值方差 Mat avg1, std1; meanStdDev(inImg, avg1, std1); double mean = avg1.at<double>(0,0); //多波段,依次為(0,1),(0,2)... double std = std1.at<double>(0,0); //Mat矩陣求和 Mat I; Scalar s = sum(I); Sum = s.val[0]; //多波段,則每個波段依次為 s.val[1]、s.val[2]... //Mat其他操作 exp(I,I); //矩陣自然指數 cartToPolar(X, Y, Grad, Angle); //由x y 方向變化量求梯度和角度 normalize(img, img, 1.0, 0.0, CV_MINMAX);//歸一化到0-1 sqrt(img, img); //開矩陣平方 資料型別不變 double fro = norm(img, NORM_L2); //F範數 //卷積運算 BORDER_REFLECT_101對稱擴充套件 影象大小不變 float se[3] = {-1 ,0 ,1}; Mat Kernel(1,3,CV_32FC1, se); filter2D(srcImg, dstImg, -1, Kernel, Point(-1,-1), 0, BORDER_REFLECT_101); //形態學運算 int dilaw = 2; Mat element = getStructuringElement(MORPH_ELLIPSE, Size(2*dilaw+1,2*dilaw+1), Point(dilaw,dilaw)); //結構元素 dilate(srcImg, dstImg, element); //膨脹 morphologyEx(srcImg, dstImg, MORPH_OPEN, element ,Point(-1,-1),1); //計算主軸方向 Moments centmom = moments(img, 1); double axis = atan2(2*centmom.mu11, centmom.mu20-centmom.mu02)/2; //影象歸一化 normalize(img,img,0,1, CV_MINMAX); //歸一化方法 CV_C - 歸一化陣列的C-範數(絕對值的最大值) CV_L1 - 歸一化陣列的L1-範數(絕對值的和) CV_L2 - 歸一化陣列的(歐幾里德)L2-範數 CV_MINMAX - 陣列的數值被平移或縮放到一個指定的範圍
二、從矩陣中擷取一部分
1.利用Rect資料型別
Rect(左上x, 左上y, 寬度, 高度)
Rect rect(begx,begy,width,height); // (左上x, 左上y, 寬度, 高度)
img(rect).copyTo(Img2) //拷貝矩形區域
2.利用Range
img.copyTo(dstImg(Range(y1,y2),Range(x1,x2)));//起點從0開始,Range(y1,y2) 包含y1不包含y2 [y1,y2) //上式等價於: Rect rect(x1, y1, x2-x1, y2-y1); img.copyTo(dstImg(rect)); Range::all() //所有行或列
三、連通域與影象填充
1.封閉區域填充
2.獲取連通域資訊//封閉區域填充 Mat maskImg =Mat::zeros(img.rows,img.cols, CV_8UC1); circle(maskImg, pt, cvRound(radius), Scalar(1), 1, 8, 0); vector<vector<Point>> contours; vector<Vec4i>hierarchy; findContours(maskImg,contours,hierarchy,CV_RETR_CCOMP,CV_CHAIN_APPROX_SIMPLE); drawContours(maskImg,contours,0, Scalar(1),CV_FILLED, 8 ); //填充
Mat usctemp;
img.convertTo(usctemp, CV_8UC1);
int roiH = usctemp.rows;
int roiW = usctemp.cols;
Mat src = Mat::zeros(roiH+2, roiW+2,CV_8UC1 ); //尋找連通域
usctemp.copyTo(src(Range(1,roiH+1),Range(1,roiW+1))); //對邊界擴充套件
vector<vector<Point>> contours; //求連通域邊界座標
vector<Vec4i>hierarchy;
findContours(src, contours, hierarchy, CV_RETR_EXTERNAL,CV_CHAIN_APPROX_NONE);
Rect bound = boundingRect(contours[0]);
//連通域相關特徵提取函式
boundingRect //外接矩形 Rect boundingRect(InputArray points)
minAreaRect //旋轉的外包絡矩形 RotatedRect minAreaRect(InputArray points)
contourArea // double contourArea(InputArray contour, bool oriented=false )
convexHull // void convexHull(InputArray points, OutputArray hull, bool clockwise=false,
//bool returnPoints=true)
convexityDefects //void convexityDefects(InputArray contour, InputArray convexhull, OutputArray convexityDefects)
...
四、常用函式
1.獲取執行時間
//獲取執行時間
double t = (double)getTickCount();
t = ((double)getTickCount() - t)/cvGetTickFrequency() * 1e-6; //單位為s
cout << "the time is :" << t << endl;
2.取樣
/***********************************************************************
函式名稱:MatImgSample
函式功能:對IplImage型別的影象進行取樣
函式引數:
src :原影象
dRatioX :列取樣比率,0.5為2取樣
dRatioY :行取樣比率,0.5為2取樣
nType :取樣型別, 1 resize, 2 pyrDown, 3 pyrUp
返回值:取樣後的影象
建立人 :pzh
建立時間:2016.3.1
備註:
***********************************************************************/
bool MatImgSample(Mat &src, Mat &dst, double dRatioX, double dRatioY, int nType)
{
if(nType == 1) //直接降取樣或上取樣 上、下采樣由dRatioX、dRatioY決定
resize(src, dst, Size(), dRatioX, dRatioY);
else if(nType == 2) //高斯降取樣,即先高斯平滑,後取樣
pyrDown(src, dst, Size(src.cols*dRatioX, src.rows*dRatioX)); //2取樣正確 4取樣會出現錯誤
else if(nType == 3)
pyrUp(src, dst, Size(src.cols*dRatioX, src.rows*dRatioX));
else
{
printf("沒有該取樣型別。\n");
return false;
}
return true;
}
/***********************************************************************
函式名稱:IplImageSample
函式功能:對IplImage型別的影象進行取樣
函式引數:
src :原影象
dRatioX :列取樣比率,0.5為2取樣
dRatioY :行取樣比率,0.5為2取樣
nType :取樣型別, 1 cvResize, 2 cvPyrDown, 3 cvPyrUp
返回值:取樣後的影象
建立人 :pzh
建立時間:2016.3.1
備註:
***********************************************************************/
IplImage* IplImageSample(IplImage *src, double dRatioX, double dRatioY, int nType)
{
CvSize dstSize ;
dstSize.width = src->width*dRatioX;
dstSize.height = src->height*dRatioY;
IplImage* dst = cvCreateImage(dstSize,src->depth,src->nChannels);
if(nType == 1) //直接降取樣或上取樣 上、下采樣由dRatioX、dRatioY決定
cvResize(src,dst,CV_INTER_CUBIC);
else if(nType == 2) //高斯降取樣,即先高斯平滑,後取樣
cvPyrDown( src, dst, CV_GAUSSIAN_5x5 );
else if(nType == 3)
cvPyrUp( src, dst, CV_GAUSSIAN_5x5 );
else
{
printf("沒有該取樣型別。\n");
return NULL;
}
return dst;
}
3.旋轉
/***********************************************************************
函式名稱:ImgRotate
函式功能:影象旋轉
函式引數:
inImg :輸入影象矩陣
rotateImg :旋轉後圖像
theta :角度單位 度 大於0向逆時針 小於0向順時針
建立人 :pzh
建立時間:2015.12.11
備註:
***********************************************************************/
bool ImgRotate(const Mat &inImg, Mat &rotateImg, double theta )
{
int Height = inImg.rows;
int Width = inImg.cols;
//影象擴充套件,計算旋轉中心和旋轉矩陣
int maxLength = int(sqrt(double(Height*Height + Width*Width)));
Mat extImg = Mat::zeros(maxLength, maxLength, inImg.type());
int roiX = maxLength/2 - Width/2;//ROI矩形左上角的x座標
int roiY = maxLength/2 - Height/2;//ROI矩形左上角的y座標
inImg.copyTo(extImg(Range(roiY, roiY+Height), Range(roiX, roiX+Width)));
//旋轉中心
Point rotaCent;
rotaCent.y = maxLength/2;
rotaCent.x = maxLength/2;
Mat rotaMat = getRotationMatrix2D(rotaCent, theta, 1); //
//得到的旋轉矩陣 [cos sin (1-cos)*c.x
// -sin cos (1-sin)*c.y
warpAffine(extImg, rotateImg, rotaMat,Size(maxLength,maxLength));//,1,0,0);
return true;
}