OpenCV 常用函数

本文主要介绍:Opencv常用函数,如均值、最大最小、归一化、滤波、旋转、求连通域等函数。


一、基本函数


 
  1. //初始化
  2. Mat img = Mat::zeros(Height, Width, CV_8UC1);
  3. Mat img = Mat::ones(Height, Width, CV_8UC1);
  4. Mat img(Height, Width,CV_32FC1, Scalar(5));
  5. img.create(Height, Width, CV8UC1);
  6. //数据类型转化
  7. img.convertTo(dstImg, dataType);
  8. //读写图像
  9. imwrite(pathm, img);
  10. imread(path, flag); // 0 灰度图 1 原图
  11. //显示图像
  12. namedWindow( "name", 1); //1 大小和图像相同,窗口不可拉伸 0 窗口可拉伸
  13. imshow( "name", img); //可以直接用imshow
  14. waitKey( 0); //图像上点击Enter退出程序
  15. //矩阵元素访问
  16. img.at<类型>(i,j) //类型一定和img相同
  17. CV_8UC1 unsigned char
  18. CV_32FC1 float
  19. CV_64FC1 double
  20. // Mat* 元素访问方式
  21. bins为Mat *bins
  22. bins->ptr< float>(i)
  23. //判断读取数据为空
  24. IplImage* dst1 = cvLoadImage(path.c_str(), 1 ); //rgb图
  25. if(!src1)
  26. {
  27. printf( "读取图像 %s 失败\n", path.c_str());
  28. return false;
  29. }
  30. img = imread(tempPath, 1);
  31. if(!img.data)
  32. {
  33. printf( "序列图模板匹配时,读取 %s 模板失败!\n", tempPath.c_str());
  34. return false;
  35. }
  36. //求最大最小值
  37. double maxval, minval;
  38. minMaxIdx(inImg,&minval,&maxval);
  39. //求均值方差
  40. Mat avg1, std1;
  41. meanStdDev(inImg, avg1, std1);
  42. double mean = avg1.at< double>( 0, 0); //多波段,依次为(0,1),(0,2)...
  43. double std = std1.at< double>( 0, 0);
  44. //Mat矩阵求和
  45. Mat I;
  46. Scalar s = sum(I);
  47. Sum = s.val[ 0]; //多波段,则每个波段依次为 s.val[1]、s.val[2]...
  48. //Mat其他操作
  49. exp(I,I); //矩阵自然指数
  50. cartToPolar(X, Y, Grad, Angle); //由x y 方向变化量求梯度和角度
  51. normalize(img, img, 1.0, 0.0, CV_MINMAX); //归一化到0-1
  52. sqrt(img, img); //开矩阵平方 数据类型不变
  53. double fro = norm(img, NORM_L2); //F范数
  54. //卷积运算 BORDER_REFLECT_101对称扩展 图像大小不变
  55. float se[ 3] = { -1 , 0 , 1};
  56. Mat Kernel(1,3,CV_32FC1, se);
  57. filter2D(srcImg, dstImg, -1, Kernel, Point( -1, -1), 0, BORDER_REFLECT_101);
  58. //形态学运算
  59. int dilaw = 2;
  60. Mat element = getStructuringElement(MORPH_ELLIPSE, Size( 2*dilaw+ 1, 2*dilaw+ 1), Point(dilaw,dilaw)); //结构元素
  61. dilate(srcImg, dstImg, element); //膨胀
  62. morphologyEx(srcImg, dstImg, MORPH_OPEN, element ,Point( -1, -1), 1);
  63. //计算主轴方向
  64. Moments centmom = moments(img, 1);
  65. double axis = atan2( 2*centmom.mu11, centmom.mu20-centmom.mu02)/ 2;
  66. //图像归一化
  67. normalize(img,img, 0, 1, CV_MINMAX);
  68. //归一化方法
  69. CV_C - 归一化数组的C-范数(绝对值的最大值)
  70. CV_L1 - 归一化数组的L1-范数(绝对值的和)
  71. CV_L2 - 归一化数组的(欧几里德)L2-范数
  72. CV_MINMAX - 数组的数值被平移或缩放到一个指定的范围


二、从矩阵中截取一部分

1.利用Rect数据类型


 
  1. Rect(左上x, 左上y, 宽度, 高度)
  2. Rect rect(begx,begy,width,height); // (左上x, 左上y, 宽度, 高度)
  3. img(rect).copyTo(Img2) //拷贝矩形区域

2.利用Range


 
  1. img.copyTo(dstImg(Range(y1,y2),Range(x1,x2))); //起点从0开始,Range(y1,y2) 包含y1不包含y2 [y1,y2)
  2. //上式等价于:
  3. Rect rect(x1, y1, x2-x1, y2-y1);
  4. img.copyTo(dstImg(rect));
  5. Range::all() //所有行或列

三、连通域与图像填充

1.封闭区域填充


 
  1. //封闭区域填充
  2. Mat maskImg =Mat::zeros(img.rows,img.cols, CV_8UC1);
  3. circle(maskImg, pt, cvRound(radius), Scalar( 1), 1, 8, 0);
  4. vector< vector<Point>> contours;
  5. vector<Vec4i>hierarchy;
  6. findContours(maskImg,contours,hierarchy,CV_RETR_CCOMP,CV_CHAIN_APPROX_SIMPLE);
  7. drawContours(maskImg,contours, 0, Scalar( 1),CV_FILLED, 8 ); //填充
2.获取连通域信息


 
  1. Mat usctemp;
  2. img.convertTo(usctemp, CV_8UC1);
  3. int roiH = usctemp.rows;
  4. int roiW = usctemp.cols;
  5. Mat src = Mat::zeros(roiH+ 2, roiW+ 2,CV_8UC1 ); //寻找连通域
  6. usctemp.copyTo(src(Range( 1,roiH+ 1),Range( 1,roiW+ 1))); //对边界扩展
  7. vector< vector<Point>> contours; //求连通域边界坐标
  8. vector<Vec4i>hierarchy;
  9. findContours(src, contours, hierarchy, CV_RETR_EXTERNAL,CV_CHAIN_APPROX_NONE);
  10. Rect bound = boundingRect(contours[ 0]);
  11. //连通域相关特征提取函数
  12. boundingRect //外接矩形 Rect boundingRect(InputArray points)
  13. minAreaRect //旋转的外包络矩形 RotatedRect minAreaRect(InputArray points)
  14. contourArea // double contourArea(InputArray contour, bool oriented=false )
  15. convexHull // void convexHull(InputArray points, OutputArray hull, bool clockwise=false,
  16. //bool returnPoints=true)
  17. convexityDefects //void convexityDefects(InputArray contour, InputArray convexhull, OutputArray convexityDefects)
  18. ...
四、常用函数

1.获取运行时间


 
  1. //获取运行时间
  2. double t = ( double)getTickCount();
  3. t = (( double)getTickCount() - t)/cvGetTickFrequency() * 1e-6; //单位为s
  4. cout << "the time is :" << t << endl;
2.采样


 
  1. /***********************************************************************
  2. 函数名称:MatImgSample
  3. 函数功能:对IplImage类型的图像进行采样
  4. 函数参数:
  5. src :原图像
  6. dRatioX :列采样比率,0.5为2采样
  7. dRatioY :行采样比率,0.5为2采样
  8. nType :采样类型, 1 resize, 2 pyrDown, 3 pyrUp
  9. 返回值:采样后的图像
  10. 创建人 :pzh
  11. 创建时间:2016.3.1
  12. 备注:
  13. ***********************************************************************/
  14. bool MatImgSample(Mat &src, Mat &dst, double dRatioX, double dRatioY, int nType)
  15. {
  16. if(nType == 1) //直接降采样或上采样 上、下采样由dRatioX、dRatioY决定
  17. resize(src, dst, Size(), dRatioX, dRatioY);
  18. else if(nType == 2) //高斯降采样,即先高斯平滑,后采样
  19. pyrDown(src, dst, Size(src.cols*dRatioX, src.rows*dRatioX)); //2采样正确 4采样会出现错误
  20. else if(nType == 3)
  21. pyrUp(src, dst, Size(src.cols*dRatioX, src.rows*dRatioX));
  22. else
  23. {
  24. printf( "没有该采样类型。\n");
  25. return false;
  26. }
  27. return true;
  28. }
  29. /***********************************************************************
  30. 函数名称:IplImageSample
  31. 函数功能:对IplImage类型的图像进行采样
  32. 函数参数:
  33. src :原图像
  34. dRatioX :列采样比率,0.5为2采样
  35. dRatioY :行采样比率,0.5为2采样
  36. nType :采样类型, 1 cvResize, 2 cvPyrDown, 3 cvPyrUp
  37. 返回值:采样后的图像
  38. 创建人 :pzh
  39. 创建时间:2016.3.1
  40. 备注:
  41. ***********************************************************************/
  42. IplImage* IplImageSample(IplImage *src, double dRatioX, double dRatioY, int nType)
  43. {
  44. CvSize dstSize ;
  45. dstSize.width = src->width*dRatioX;
  46. dstSize.height = src->height*dRatioY;
  47. IplImage* dst = cvCreateImage(dstSize,src->depth,src->nChannels);
  48. if(nType == 1) //直接降采样或上采样 上、下采样由dRatioX、dRatioY决定
  49. cvResize(src,dst,CV_INTER_CUBIC);
  50. else if(nType == 2) //高斯降采样,即先高斯平滑,后采样
  51. cvPyrDown( src, dst, CV_GAUSSIAN_5x5 );
  52. else if(nType == 3)
  53. cvPyrUp( src, dst, CV_GAUSSIAN_5x5 );
  54. else
  55. {
  56. printf( "没有该采样类型。\n");
  57. return NULL;
  58. }
  59. return dst;
  60. }
3.旋转


 
  1. /***********************************************************************
  2. 函数名称:ImgRotate
  3. 函数功能:图像旋转
  4. 函数参数:
  5. inImg :输入图像矩阵
  6. rotateImg :旋转后图像
  7. theta :角度单位 度 大于0向逆时针 小于0向顺时针
  8. 创建人 :pzh
  9. 创建时间:2015.12.11
  10. 备注:
  11. ***********************************************************************/
  12. bool ImgRotate(const Mat &inImg, Mat &rotateImg, double theta )
  13. {
  14. int Height = inImg.rows;
  15. int Width = inImg.cols;
  16. //图像扩展,计算旋转中心和旋转矩阵
  17. int maxLength = int( sqrt( double(Height*Height + Width*Width)));
  18. Mat extImg = Mat::zeros(maxLength, maxLength, inImg.type());
  19. int roiX = maxLength/ 2 - Width/ 2; //ROI矩形左上角的x坐标
  20. int roiY = maxLength/ 2 - Height/ 2; //ROI矩形左上角的y坐标
  21. inImg.copyTo(extImg(Range(roiY, roiY+Height), Range(roiX, roiX+Width)));
  22. //旋转中心
  23. Point rotaCent;
  24. rotaCent.y = maxLength/ 2;
  25. rotaCent.x = maxLength/ 2;
  26. Mat rotaMat = getRotationMatrix2D(rotaCent, theta, 1); //
  27. //得到的旋转矩阵 [cos sin (1-cos)*c.x
  28. // -sin cos (1-sin)*c.y
  29. warpAffine(extImg, rotateImg, rotaMat,Size(maxLength,maxLength)); //,1,0,0);
  30. return true;
  31. }