一、代码实现
cv::Mat类是用来存放图像(以及其他矩阵数据)的数据结构。在所有的OpenCV类和函数中,这个数据结构具有核心地位。
上代码:
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
// test function that creates an image
cv::Mat function() {
// create image
cv::Mat ima(500, 500, CV_8U, 50);
// return it
return ima;
}
int main() {
// define image windows
cv::namedWindow("Image 1");
cv::namedWindow("Image 2");
cv::namedWindow("Image 3");
cv::namedWindow("Image 4");
cv::namedWindow("Image 5");
cv::namedWindow("Image");
// create a new image made of 240 rows and 320 columns
cv::Mat image1(240, 320, CV_8U, 100);
// or:
// cv::Mat image1(240,320,CV_8U,cv::Scalar(100));
cv::imshow("Image", image1); // show the image
cv::waitKey(0); // wait for a key pressed
// re-allocate a new image
// (only if size or type are different)
image1.create(200, 200, CV_8U);
image1 = 200;
cv::imshow("Image", image1); // show the image
cv::waitKey(0); // wait for a key pressed
// create a red color image
// channel order is BGR
cv::Mat image2(240, 320, CV_8UC3, cv::Scalar(0, 0, 255));
// or:
// cv::Mat image2(cv::Size(320,240),CV_8UC3);
// image2= cv::Scalar(0,0,255);
cv::imshow("Image", image2); // show the image
cv::waitKey(0); // wait for a key pressed
// read an image
cv::Mat image3 = cv::imread("G:\\OpenCV2pictures\\puppy.bmp");
// all these images point to the same data block
cv::Mat image4(image3);
image1 = image3;
// these images are new copies of the source image
image3.copyTo(image2);
cv::Mat image5 = image3.clone();
// transform the image for testing
cv::flip(image3, image3, 1);
// check which images have been affected by the processing
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); // wait for a key pressed
// get a gray-level image from a function
cv::Mat gray = function();
cv::imshow("Image", gray); // show the image
cv::waitKey(0); // wait for a key pressed
// read the image in gray scale
image1 = cv::imread("G:\\OpenCV2pictures\\puppy.bmp", CV_LOAD_IMAGE_GRAYSCALE);
// convert the image into a floating point image [0,1]
image1.convertTo(image2, CV_32F, 1 / 255.0, 0.0);
cv::imshow("Image", image2); // show the image
cv::waitKey(0); // wait for a key pressed
return 0;
}
运行结果:
二、实现原理
1、cv::Mat有两个必不可少的组成部分:一个头部和一个数据块。头部包含了矩阵的所有相关信息(大小、通道数量、数据类型)。数据块包含了图像中所有像素的值。头部有一个指向数据块的指针,即data属性。
2、cv::Mat有一个很重要的属性,即只有在明确要求时,内存块才会被复制。实际上,大多数操作仅仅复制了cv::Mat的头部,因此多个对象会同时指向同一个数据块。这种内存管理模式可以提高应用程序的运行效率,避免内存泄漏。
3、指定元素的类型时,用CV_8U表示每个像素对应1字节,用字母U表示无符号,字母S表示有符号。对于彩色图,可以用三通道类型:CV_8UC3,16位的整数:CV_16SC3,32位的浮点数:CV_32F。
4、当两个图像之间赋值时,图像数据(即像素)并不会被复制,此时两个图像都指向同一个内存块。对其中的任何一个做转换都会影响到其他图像。如果要对图像内容做一个深复制,可以使用copyTo方法。
参考书:《OpenCV计算机视觉编程攻略》
版权声明:本文为weixin_38952721原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。