本文主要介绍: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.封闭区域填充
-
//封闭区域填充
-
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 );
//填充
2.获取连通域信息
-
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;
-
-
}