学习笔记——基于opencv的图像处理

2022.5.23

一、基本的图像容器矩阵类Mat

#include <iostream>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;

int main()
{
    Mat A,C;//建立头文件
    A=imread("C://Users//asus//Pictures//Saved Pictures//timg.jpg");//imread()函数读取图像,并为矩阵A分配内存,括号内是读取图片路径及名称
    Mat B(A);//拷贝构造函数argv[1],CV_LOAD_IMAGE_COLOR
    C=A;
    imshow("C",C);//输出图像
    Mat D(A,Rect(100,100,200,200));//选择矩形,访问A中感兴趣的底层数据,其中(100,100)表起始点,(200,200)表终止点
    imshow("D",D);
    Mat E=A(Range::all(),Range(50,150));//,选择x轴上位置,访问A中感兴趣的部分,50为X轴上的起点,150为x轴上的终点
    imshow("E",E);
//以上为拷贝对象头文件
    Mat F=A.clone();
    Mat G;
    A.copyTo(G);
    imshow("F",F);
    imshow("G",G);
//以上为完全拷贝,拷贝底层数据,此时对F、G进行修改,不会影响原始数据
    waitKey(0);
    return 0;
}

1、对于以上所示对象,所有对象最后都指向同一个单独的数据矩阵(访问共有的底层数据),其中任意一个修改,都会影响别的对象

2、可以创建特殊的头文件,只访问底层数据中感兴趣的部分

3、用于输出图像内存分配的opencv是自动的,在此学习中不用考虑内存管理

4、分配操作符和拷贝构造符仅仅只是拷贝头文件

5、clone.()、copy.()函数可拷贝图像底层数据,修改后,不会影响其它对象

2022.5.25

简单Mat矩阵的构建

    Mat M(2,3,CV_8UC3,Scalar(120,80,100,50));//二维多通道图像CV_8UC3(CV_[每个基元分量的比特数8][有符号S或无符号U](前为类型前缀)[C通道][通道数3]),Scalar(蓝,绿,红,透明度)
    imshow("M",M);//输出图像矩阵色彩和三基色形式
    cout<<"M="<<endl<<M<<endl;//输出矩阵形式
    Mat I=(Mat_<int>(4,4)<<1,1,2,2,
           3,3,4,4,
           5,5,6,6,
           7,7,8,8);//初始化
    I.create(4,4,CV_8UC(4));
    cout<<"I ="<<endl<<" "<<I<<endl<<endl;//create()构造器不能初始化矩阵值,如果新的矩阵尺寸与旧的不一致,它只是重新分配矩阵数据的内存。
    Mat RowClone = I.row(1).clone();
    cout<<"RowClone ="<<endl<<""<<RowClone<<endl<<endl;//为已经存在的Mat对象创建新的头文件,并通过clone()or copyTo()为其赋值
    Mat J=Mat(3,2,CV_8UC3);
    randu(J,Scalar::all(0),Scalar::all(255));//随机函数randu(),填充矩阵值。我们可以将这个随机值限定在某两个数之间;也可以三通道设置:Scalar(10,20,30),Scalar(100,150,200)
    cout<<"J ="<<endl<<""<<J<<endl;

1、构建矩阵可以有Mat()构造器、Create()我没搞明白它的意思、对小矩阵直接逗号分隔初始化、对已有的矩阵创造新的头文件并clone()或copyTo、随机函数填充矩阵。(除了create()构造器,还有用数组对Mat()初始化以及为已存的lpllmage(opencv2.4.9之前)指针创建一个头文件还完全不能理解)

2、Matlab初始化函数:zeros()全0,ones()全1,eyes()对角矩阵

2022.5.27

Mat类成员变量

    Mat I=(Mat_<int>(4,4)<<1,1,2,2,
           3,3,4,4,
           5,5,6,6,
           7,7,8,8);
//Mat类成员rows()、cols()、row()、col()
    cout<<"I ="<<endl<<" "<<I<<endl<<endl;
    cout<<"I rows="<<I.rows<<endl;//读取I的行数,并显示到屏幕
    cout<<"I cols="<<I.cols<<endl; //读取I的列数,并显示到屏幕
    cout<<I.row(1)<<endl;//读取I的第2行数据,并显示到屏幕
    cout<<I.col(1)<<endl;//读取I的第2列数据,并显示到屏幕

其它常用基本成员变量和函数

1、data:Mat对象中的一个指针,指向内存中存放矩阵数据的一块内存 (uchar* data);

2、dims:Mat所代表的矩阵的维度,如 3 * 4 的矩阵为 2 维, 3 * 4 * 5 的为3维;

3、channels:通道,矩阵中的每一个矩阵元素拥有的值的个数,比如说 3 * 4 矩阵中一共 12 个元素,如果每个元素有三个值,那么就说这个矩阵是 3 通道的,即 channels = 3;

4、depth:深度,即每一个像素的位数(bits),在opencv的Mat.depth()中得到的是一个 0 – 6 的数字,分别代表不同的位数:enum { CV_8U=0, CV_8S=1, CV_16U=2, CV_16S=3, CV_32S=4, CV_32F=5, CV_64F=6 }; 可见 0和1都代表8位, 2和3都代表16位,4和5代表32位,6代表64位;

5、elemSize : 矩阵中每一个元素(像素)的数据大小所占内存字节数,如果Mat中的数据类型是 CV_8U 那么 elemSize =1,CV_8UC3 那么 elemSize = 3,CV_16UC2 那么 elemSize = 4;记住另外有个 elemSize1 表示的是矩阵中数据类型的大小,即 elemSize / channels 的大小;

5、step:是一个数组,定义了矩阵的布局,step[0]第一维度的单位长度数据大小,step[1]第一维度下第二维度的单位长度数据大小,另外注意 step1 (step / elemSize1),M.step[m-1] 总是等于 elemSize,M.step1(m-1)总是等于 channels;

6、type():Mat的成员函数,返回矩阵的类型,与depth相似,含有数据类型信息和通道信息

Mat数据地址的计算

(其中 m = M.dims,即 M的维度)         在此处要重新回顾一下指针,不熟

    int i=1,j=1;
    uchar *pa=I.data+I.step[0]*i+I.step[1]*j;
    float *pDij= (float*)pa;//注意此处的data返回的数据类型,是uchar型,所以指针pa也需要是uchar*型在cout时,要转换成float*型指针,然后再访问该处地址的数据值。
    cout<<pDij[0]<<endl;

2022.5.31

矩阵初始化

    Mat J(3,5,CV_32FC1,1);//J为3*5的矩阵,float型的单通道,把每个点都初始化为1
    Mat K(3,5,CV_32FC1,Scalar(1));//Scalar初始化
    //cout<<J<<endl<<K<<endl<<J.elemSize()<<endl<<J.elemSize1();
    float *data = new float[15];//从已有的数据源初始化,但是运行时,结果中出现与预期结果不同的小数点后多位的情况,不知道是什么原因
    for (int i=0;i<15;i++)
    {
       data[i]=2.2+i;
    }
    Mat L(3,5,CV_32FC1,data);
    //cout<<"L"<<L;
    delete[]data;//删掉数据源后,L出现乱码,说明该方法只是浅拷贝了一下
    //cout<<L;
    Mat M=imread("C://Users//asus//Pictures//Saved Pictures//timg.jpg",CV_LOAD_IMAGE_GRAYSCALE);//图片初始化,还可以矩形选择感兴趣的区域初始化
    //cout<<M;
    Mat N=M(Range::all(),Range(1,3));//选择部分行初始化
    //cout<<N;

矩阵初始化除了以上,还有clone、copyto等方法;

diag(int d)d=0主对角线,d=1是比主对角线低的对角线....

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

Mat::push_back(Mat)在原来的Mat上在加几行

Mat::pop_back(size_t nelems=1)移除最下边几行(但是这几种都没试过)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值