OpenCV -- 常用函数

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

 

一、基本函数

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
//初始化
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数据类型

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

  

2.采样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/***********************************************************************
    函数名称: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.旋转

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/***********************************************************************
    函数名称: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;
  
}

  

posted @   手磨咖啡  阅读(172)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示