cv::Mat

原文地址:

OpenCV中矩阵类详解之一:Mat

【OpenCV学习笔记】二、深入了解 cv::Mat

CV_32FC1和CV_64FC1的区别?

OpenCV里面Mat方法中的Scalar详解

1.创建一个240行 × 320列的新图像,CV_8UC1表示每个像素对应1字节,单通道,用字母U表示无符号,灰度值为100

 cv::Mat image1(240, 320, CV_8UC1, 100); 

CV_32FC1和CV_64FC1,前者是32位数据,后者是64位数据。因此前者类型的数据必须以指向32位数据类型的指针存取,否则会报错,而后者类型的数据必须以指向64位数据类型的指针存取,否则会报错。

也就是说,你如果用CV_32FC1,那么后面对该矩阵的输入输出的数据指针类型都应该是float,这在32位编译器上是32位浮点数,也就是单精度
你如果用CV_64FC1,那么后面对该矩阵的输入输出的数据指针类型都应该是double,这在32位编译器上是64位浮点数,也就是双精度

创建Mat矩阵

示例1:

//1.使用构造函数,常见的几个如下:  
Mat::Mat(); //default  
Mat::Mat(int rows, int cols, int type);  
Mat::Mat(Size size, int type);  
Mat::Mat(int rows, int cols, int type, const Scalar& s);  
Mat::Mat(Size size, int type, const Scalar& s);  
Mat::Mat(const Mat& m);  
//参数说明:  
//int rows:高  
//int cols:宽  
//int type:参见"Mat类型定义"  
//Size size:矩阵尺寸,注意宽和高的顺序:Size(cols, rows)  
//const Scalar& s:用于初始化矩阵元素的数值  
//const Mat& m:拷贝m的矩阵头给新的Mat对象,但是不复制数据!相当于创建了m的一个引用对象  

//例子1:创建100*90的矩阵,**矩阵元素为3通道32位浮点型**  
cv::Mat M(100, 90, CV_32FC3);  
//例子2:使用一维或多维数组来初始化矩阵,  
double m[3][3] = {{a, b, c}, {d, e, f}, {g, h, i}};  
cv::Mat M = cv::Mat(3, 3, CV_64F, m);  

//2.使用create函数:  
Mat a = create(10, 9, CV_16U);  //创建10*9的矩阵,矩阵元素为16位无符号整型  
//create的一个特殊用法:如果初始化的时候没有传入size的参数,或者后面需要改变size的参数,可以使用create来调整  
// make 7x7 complex matrix filled with 1+3j.  
cv::Mat M(7,7,CV_32FC2,Scalar(1,3));  
// and now turn M to 100x60 15-channel 8-bit matrix.  
// The old content will be deallocated:隐式使用release()释放  
M.create(100,60,CV_8UC(15));</span>  

示例2:

#include <iostream>  
#include <opencv2/core/core.hpp>  
#include <opencv2/highgui/highgui.hpp>  
// 测试函数, 它创建一个图像  
cv::Mat function() {  
    // 创建图像  
    cv::Mat ima(500, 500, CV_8U, 50);  
    // 返回图像  
    return ima;  
}   
int main()   
{  
    // 定义图像窗口  
    cv::namedWindow("Image 1");  
    cv::namedWindow("Image 2");  
    cv::namedWindow("Image 3");  
    cv::namedWindow("Image 4");  
    cv::namedWindow("Image 5");  
    cv::namedWindow("Image");  
    /*我们需要指定每个矩阵元素的类型,这里我们用CV_8U表示每个像素 
    对应1字节,用字母U表示无符号,你也可用字母S表示有符号。对于 
    彩色图像,你应该用三通道类型(CV_8UC3),也可以定义16位和 
    32位的整数(有符号或无符号),例如CV_16SC3。我们甚至可以使 
    用32位和64位的浮点数(例如CV_32F)。*/  
    // 创建一个240行 × 320列的新图像  
    cv::Mat image1(240, 320, CV_8U, 100);  
    cv::imshow("Image", image1); // 显示图像  
    cv::waitKey(0); // 等待按键  
    /*我们可以随时用create方法分配或重新分配图像的数据块,如果图 
    像已经分配,首先其原来的内容会被释放。*/  
    // 重新分配一个新的图像  
    image1.create(200, 200, CV_8U);  
    image1 = 200;  
    cv::imshow("Image", image1); // 显示图像  
    cv::waitKey(0); // 等待按键  
    /*图像(或矩阵)的每个元素都可以包含多个值(例如彩色图像中的三 
    个通道),因此OpenCV引入了一个简单的数据结构cv::Scalar, 
    用于在调用函数时传递像素值。该结构通常包含一个或三个值。*/  
    // 创建一个红色的图像  
    // 通道次序为BGR  
    cv::Mat image2(240, 320, CV_8UC3, cv::Scalar(0, 0, 255));  
    // 或者:  
    // cv::Mat image2(cv::Size(320,240),CV_8UC3);  
    // image2= cv::Scalar(0,0,255);  
    cv::imshow("Image", image2); // 显示图像  
    cv::waitKey(0); // 等待按键  
    // 读入一个图像  
    cv::Mat image3 = cv::imread("puppy.bmp");  
    /*一旦没有了指向cv::Mat对象的引用, 分配的内存就会被自动释 
        放。 这一点非常方便, 因为它避免了C++动态内存分配中经常发生的 
        内存泄漏问题。 这是OpenCV 2中一个关键的机制, 它的实现方法是 
        通过cv::Mat实现计数引用和浅复制。 因此, 当在两个图像之间赋 
        值时, 图像数据( 即像素) 并不会被复制, 此时两个图像都指向同一 
        个内存块。 这同样适用于图像间的值传递或值返回。 由于维护了一个 
        引用计数器, 因此只有当图像的所有引用都将释放或赋值给另一个图 
        像时, 内存才会被释放;*/  
    // 所有这些图像都指向同一个数据块。  
    //下面的两个图像,对其中的任何一个做转换都会影响到其他图像。  
    cv::Mat image4(image3);  
    image1 = image3;  
    /*如果要对图像内容做一个深复制, 你可以使用copyTo方法, 在此情况下 
    目标图像会调用create方法。 另一个生成图像副本的方法是clone, 即创建 
    一个完全相同的新图像*/  
    // 这些图像是源图像的副本图像  
    image3.copyTo(image2);  
    cv::Mat image5 = image3.clone();  
    // 转换图像用来测试  
    cv::flip(image3, image3, 1);  
    // 检查哪些图像在处理过程中受到了影响  
    cv::imshow("Image 3", image3);  
    cv::imshow("Image 1", image1);  
    cv::imshow("Image 2", image2);  
    cv::imshow("Image 4", image4);  
    cv::imshow("Image 5", image5);  
    cv::waitKey(0); // 等待按键  
    // 从函数中获取一个灰度图像  
    cv::Mat gray = function();  
    cv::imshow("Image", gray); // 显示图像  
    cv::waitKey(0); // 等待按键  
    // 作为灰度图像读入  
    image1 = cv::imread("puppy.bmp", CV_LOAD_IMAGE_GRAYSCALE);  
    /*如果你需要把一个图像复制到另一个图像中, 而两者的数据类型不一 
    定相同, 那就要使用convertTo方法.需要注意的是, 这两个图像的通道数量 
    必须相同。*/  
    image1.convertTo(image2, CV_32F, 1 / 255.0, 0.0);  
    cv::imshow("Image", image2); // 显示图像  
    cv::waitKey(0); // 等待按键  
    return 0;  
}  

示例3:

Mat M(7,7,CV_32FC2,Scalar(1,3));

解释如下:创建一个M矩阵,7行7列,类型为CV_32F,C2表示有2个通道。Scalar(1,3)是对矩阵进行初始化赋值。第一个通道全为1,第2个通道全为3。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值