[OpenCV][C++编程] cv::mat的定义与赋值

0.在pro文件中添加opencv的库

0.1 INCLUDEPATH

可以通过在/目录下直接搜索opencv,确定opencv所在的目录:

INCLUDEPATH += \

 /usr/include/opencv4

0.2 LIBS

LIBS += \
 -lopencv_core -lopencv_highgui -lopencv_imgproc -lopencv_ml
  • lopencv_core 是opencv的核心,
  • -lopencv_highgui包含读取图像和显示图像的函数
  • -lopencv_imgproc包含图像处理函数(非机器学习方法),例如线性滤波,边缘检测、膨胀腐蚀、检测直线、仿射变换等等。
  • -lopencv_ml包含机器学习算法(贝叶斯分类、k-近邻分类器、SVM、决策树、EM算法等待)

1. cv::Mat的创建

1.1 默认的构造函数

可以直接采用下面的形式:cv::Mat mat(sizeRow,sizeCol,type)定义mat变量的尺寸和类型。

type可选项有CV_8UC1、CV_8SC1等等。它的数据含义是:
CV_数据类型_数据的通道数量

  • cv的类型编号定义:

#define CV_8U 0

#define CV_8S 1

#define CV_16U 2

#define CV_16S 3

#define CV_32S 4

#define CV_32F 5

#define CV_64F 6

#define CV_16F 7

通过mat.type()可以输出mat变量的类型

C1,C2,C3,C4代表数据通道数:

  • C1:灰度图像,单个数字
  • C2:每一个可以表示一个二维向量
  • C3:RGB图像
  • C4:PNG格式图像除了RGB,还有一个透明度通道。
  

#include <QCoreApplication>

#include<opencv/cv.h>

#include<QDebug>

#include<iostream>

int main(int argc, char *argv[])

{

 //QCoreApplication a(argc, argv);

  

// cv::Mat mat1 = cv::Mat_<float>(3,3);

// std::cout<<"mat1 size is " << mat1.size<<std::endl;

// std::cout<<"mat1 type is " << mat1.type()<<std::endl;

  

 cv::Mat mat2(4,4,CV_8UC1);

 std::cout<<"mat2 size is " << mat2.size<<std::endl;

 std::cout<<"mat2 type is " << mat2.type()<<std::endl;

  

 return 0;

}

输出结果为:

  
mat2 size is 4 x 4

mat2 type is 0

1.2使用mat_<变量类型>(变量尺寸)函数进行创建(推荐使用)

cv::Mat_<类型>(sizeRow,sizeCol)

例如下面的代码是创建了一个3*3的Mat变量,变量的类型都是float


#include <QCoreApplication>

#include<opencv/cv.h>

#include<QDebug>

#include<iostream>

int main(int argc, char *argv[])

{

 //QCoreApplication a(argc, argv);

 cv::Mat mat1 = cv::Mat_<float>(3,3);


 //std::cout<< "mat1:"<mat1<<std::endl ;

 std::cout<<"mat1 size is " << mat1.size<<std::endl;


 return 0;

}

输出的结果为:

  
mat1 size is 3 x 3

mat1 type is 5

1.3 构造一些特殊矩阵

生成零矩阵、全1矩阵、单位矩阵、对角矩阵。

  • cv::Mat::zeros()
  • cv::Mat::ones()
  • cv::Mat::eye()
  • cv::Mat::diag();
 cv::Mat mat2;

 mat2= cv::Mat::zeros(3,3,CV_16U);

 std::cout<<mat2<<std::endl;

 mat2= cv::Mat::ones(3,3,CV_16U);

 std::cout<<mat2<<std::endl;

 mat2= cv::Mat::eye(3,3,CV_16U);

 std::cout<<mat2<<std::endl;

结果:

  

[0, 0, 0;

0, 0, 0;

0, 0, 0]


[1, 1, 1;

1, 1, 1;

1, 1, 1]


[1, 0, 0;

0, 1, 0;

0, 0, 1]

1.4 克隆其他矩阵

同尺寸克隆,直接通过 mat.clone( )指令就可以了。被克隆的


 //从其他矩阵克隆

 cv::Mat mat2;

 mat2= cv::Mat::eye(3,3,CV_16U);

 cv::Mat mat3 = mat2.clone();

 std::cout<<mat3<<std::endl;

输出结果:

[1, 0, 0;

0, 1, 0;

0, 0, 1]

缩小尺寸克隆,需要

需要注意的是,直接赋值并不定于克隆:例如mat3 = mat2只是把mat2的头部指针赋值为mat3,修改mat2或者mat3中任意一个,其他一个都会跟着修改。而mat3= mat2.clone()则创建了完全独立的变量mat3。例如下面的代码,运行结果不一样。

[std::cout<<mat2<<std::endl;](<//从其他矩阵克隆  对比  直接赋值
    cv::Mat mat2;
    mat2= cv::Mat::eye(3,3,CV_16U);
    cv::Mat mat3 = mat2.clone();
    cv::Mat mat4 = mat2;
    std::cout%3C<"mat2:"<<std::endl<<mat2<<std::endl;

    mat4.at<uint16_t%3E(0,0) = 0;
    std::cout<<"mat2:"<<std::endl<<mat2<<std::endl;

    std::cout<<"mat3:"<<std::endl<<mat3<<std::endl;>)

结果:

mat2:

[1, 0, 0;

0, 1, 0;

0, 0, 1]

mat2:

[0, 0, 0;

0, 1, 0;

0, 0, 1]

mat3:

[1, 0, 0;

0, 1, 0;

0, 0, 1]

mat4和mat2是指向同一个地址,而mat3是单独地址。所以改变mat4的值后,mat2也改变了,而mat3不变。

1.5 基于其他mat变量建立更小尺寸的mat


 //基于某个mat变量,建立更小尺寸的mat,发现是共用指针的。

 cv::Mat mat2;

 mat2= cv::Mat::eye(5,5,CV_16U);

 std::cout<<"mat2:"<<std::endl<<mat2<<std::endl;

  

 cv::Mat mat3(mat2,cv::Range(0,3),cv::Range(0,3));

 std::cout<<"mat3:"<<std::endl<<mat3<<std::endl;

  

 std::cout<<"将mat3 的 (0,0)元素赋值为0"<<std::endl;

 mat3.at<uint16_t>(0,0) = 0;

 std::cout<<"mat2:"<<std::endl<<mat2<<std::endl;

结果:

mat2:

[1, 0, 0, 0, 0;

0, 1, 0, 0, 0;

0, 0, 1, 0, 0;

0, 0, 0, 1, 0;

0, 0, 0, 0, 1]

mat3:

[1, 0, 0;

0, 1, 0;

0, 0, 1]

将mat3 的 (0,0)元素赋值为0

mat2:

[0, 0, 0, 0, 0;

0, 1, 0, 0, 0;

0, 0, 1, 0, 0;

0, 0, 0, 1, 0;

0, 0, 0, 0, 1]

2.mat的赋值

2.1 针对某个点的赋值

通过 mat.at<变量类型>(numRow,numCol) = num;命令对mat变量中某个索引值进行赋值。例如在1.5中出现的赋值。

2.2在创建mat变量时赋值

在采用构造方式创建变量时,直接附在最后一个变量。
给矩阵中每个像素赋值的参数变量,例如Scalar(0, 0, 255)。_

cv::Mat a(2, 2, CV_8UC3, cv::Scalar(0,0,255));//创建一个3通道矩阵,每个像素都是0,0,255
cv::Mat a(2, 2, CV_8UC3, cv::Scalar(0,255));//创建一个2通道矩阵,每个像素都是0,255
cv::Mat a(2, 2, CV_8UC1, cv::Scalar(255));//创建一个单通道矩阵,每个像素都是255

2.3 采用枚举法赋值

这种赋值方式是将矩阵中所有的元素都一一枚举出,并用数据流的形式赋值给Mat类。具体赋值形式:

cv::Mat a = (cv::Mat_<int>(3, 3) << 1, 2, 3, 4, 5, 6, 7, 8, 9);

也可以把需要赋值的数写成列表

float a[8] = { 5,6,7,8,1,2,3,4 };
cv::Mat b = cv::Mat(2, 2, CV_32FC2, a);

2.4 循环赋值

与通过枚举法赋值方法相类似,循环法赋值也是对矩阵中的每一位元素进行赋值,但是可以不在声明变量的时候进行赋值,而且可以对矩阵中的任意部分进行赋值:

cv::Mat c = cv::Mat_<int>(3, 3); //定义一个3*3的矩阵
for (int i = 0; i < c.rows; i++) //矩阵行数循环
{
    for (int j = 0; j < c.cols; j++) //矩阵列数循环
    {
        c.at<int>(i, j) = i+j;
    }
}
  • 10
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++中,可以使用模板方法来实现cv::Mat和std::vector之间的相互转换。具体的实现代码如下: ``` template<typename _Tp> std::vector<_Tp> convert_mat_to_vector(const cv::Mat& mat) { // 通道数不变,按行转为一行 return (std::vector<_Tp>)(mat.reshape(1, 1)); } template<typename _Tp> cv::Mat convert_vector_to_mat(std::vector<_Tp> v, int channels, int rows) { // 将vector变成单列的mat,这里需要clone(),因为这里的赋值操作是浅拷贝 cv::Mat mat = cv::Mat(v).clone(); cv::Mat dest = mat.reshape(channels, rows); return dest; } ``` 上述代码定义了两个模板方法,分别为convert_mat_to_vector和convert_vector_to_mat。convert_mat_to_vector方法将cv::Mat转换为std::vector,而convert_vector_to_mat方法将std::vector转换为cv::Mat。使用这些方法可以实现cv::Mat和std::vector之间的相互转换。 注意:在转换过程中,需要确保通道数和行数的正确性。在转换cv::Mat为std::vector时,使用reshape方法将多通道的cv::Mat转为一行;在转换std::vector为cv::Mat时,使用reshape方法将一行的std::vector转为指定的通道数和行数。 希望对你有帮助!<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [OpenCV - cv::Mat与unsigned char*数组或者float*数组相互转换,cv::Mat与std::vector的相互转换](https://blog.csdn.net/HW140701/article/details/131064164)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [opencv mat与std::vector互转](https://blog.csdn.net/qq_61862078/article/details/128883907)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值