M a t 对 象 及 其 基 本 操 作 Mat对象及其基本操作 Mat对象及其基本操作
1.Mat对象
Mat的定义
Mat(matrix矩阵):图像文件的内存数据对象
Mat:header (宽、高、通道数等信息)+ data(图像数据信息)

数据类型和通道信息
图像深度 |
对应数据类型 |
CV_8U |
8位无符号-字节类型 |
CV_8S |
8位有符号-字节类型 |
CV_16U |
16位无符号类型 |
CV_16S |
16位有符号类型 |
CV_32S |
32整形数据类型 |
CV_32F |
32位浮点数类型 |
CV_64F |
64位双精度类型 |
单通道 |
双通道 |
三通道 |
四通道 |
CV_8UC1 |
CV_8UC2 |
CV_8UC3 |
CV_8UC4 |
CV_32SC1 |
CV_32SC2 |
CV_32SC3 |
CV_32SC4 |
CV_32FC1 |
CV_32FC2 |
CV_32FC3 |
CV_32FC4 |
CV_64FC1 |
CV_64FC2 |
CV_64FC3 |
CV_64FC4 |
CV_16SC1 |
CV_16SC2 |
CV_16SC3 |
CV_16SC4 |
#include
#include
using namespace cv;
using namespace std;
int main(int argc, char** argv) {
Mat src = imread("E:/cats.jpg", IMREAD_COLOR);
if (src.empty()) {
printf("image is empty!!!");
return -1;
}
namedWindow("image", WINDOW_FREERATIO);
imshow("image", src);
int width = src.cols;
int height = src.rows;
int dim = src.channels();
printf("width : %d,height:%d,channels: %d",width,height,dim);
waitKey(0);
destroyAllWindows();
return 0;
}

2 属性与操作
#include
#include
using namespace cv;
using namespace std;
int main(int argc, char** argv) {
Mat src = imread("E:/cats.jpg", IMREAD_COLOR);
if (src.empty()) {
printf("image is empty!!!");
return -1;
}
namedWindow("image", WINDOW_FREERATIO);
imshow("image", src);
int width = src.cols;
int height = src.rows;
int dim = src.channels();
int img_depth = src.depth();
int img_type = src.type();
printf("width : %d,height:%d,channels: %d,depth:%d,type: %d",width,height,dim, img_depth, img_type);
waitKey(0);
destroyAllWindows();
return 0;
}

数据类型和通道类型:(0,16)和下表对应:CV_8U、 CV_8UC3
图像深度 |
对应数据类型 |
CV_8U |
8位无符号-字节类型 |
CV_8S |
8位有符号-字节类型 |
CV_16U |
16位无符号类型 |
CV_16S |
16位有符号类型 |
CV_32S |
32整形数据类型 |
CV_32F |
32位浮点数类型 |
CV_64F |
64位双精度类型 |
单通道 |
双通道 |
三通道 |
四通道 |
CV_8UC1 |
CV_8UC2 |
CV_8UC3 |
CV_8UC4 |
CV_32SC1 |
CV_32SC2 |
CV_32SC3 |
CV_32SC4 |
CV_32FC1 |
CV_32FC2 |
CV_32FC3 |
CV_32FC4 |
CV_64FC1 |
CV_64FC2 |
CV_64FC3 |
CV_64FC4 |
CV_16SC1 |
CV_16SC2 |
CV_16SC3 |
CV_16SC4 |
3 创建
- 3.1 创建空白Mat对象
- 从现有图像创建
- 创建填充值的Mat对象
- 创建单通道与多通道Mat对象
- 遍历与访问像素值
3.1 创建空白Mat对象
#include
#include
using namespace cv;
using namespace std;
int main(int argc, char** argv) {
Mat t1 = Mat(256, 256, CV_8SC1);
t1 = Scalar(0);
imshow("t1", t1);
Mat t2 = Mat(256, 256, CV_8SC3);
t2 = Scalar(0, 255, 0);
imshow("t2", t2);
waitKey(0);
destroyAllWindows();
return 0;
}


Mat(Size(512,512), CV_8SC1);
#include
#include
using namespace cv;
using namespace std;
int main(int argc, char** argv) {
Mat t1 = Mat(Size(512,512), CV_8SC1);
t1 = Scalar(0);
imshow("t1", t1);
Mat t2 = Mat(Size(512, 512), CV_8SC3);
t2 = Scalar(0, 255, 0);
imshow("t2", t2);
waitKey(0);
destroyAllWindows();
return 0;
}
Mat::zeros(Size(256,256),CV_8SC1);
using namespace cv;
using namespace std;
int main(int argc, char** argv) {
Mat t1 = Mat::zeros(Size(256,256),CV_8SC1);
imshow("t1", t1);
waitKey(0);
destroyAllWindows();
return 0;
}
3.2 从现有图像创建
#include
#include
using namespace cv;
using namespace std;
int main(int argc, char** argv) {
Mat src = imread("E:/cats.jpg", IMREAD_COLOR);
if (src.empty()) {
printf("image is empty!!!");
return -1;
}
Mat t1 = src;
t1 = Scalar(0, 255, 0);
Mat t2 = src.clone();
imshow("t2", t2);
Mat t3 = Mat::zeros(src.size(), src.type());
imshow("t3", t3);
waitKey(0);
destroyAllWindows();
return 0;
}
创建源图大小一样的全零矩阵
Mat t3 = Mat::zeros(src.size(), src.type());
imshow("t3", t3);
4 遍历访问每个像素值
#include
#include
using namespace cv;
using namespace std;
int main(int argc, char** argv) {
Mat src = imread("E:/cats.jpg", IMREAD_COLOR);
if (src.empty()) {
printf("image is empty!!!");
return -1;
}
int height = src.rows;
int width = src.cols;
int ch = src.channels();
for (int row = 0; row < height; row++) {
for (int col = 0; col < width;col++) {
if (ch == 3) {
Vec3b pixel = src.at<Vec3b>(row, col);
int blue = pixel[0];
int green = pixel[1];
int red = pixel[2];
src.at<Vec3b>(row, col)[0] = 255 - blue;
src.at<Vec3b>(row, col)[1] = 255 - green;
src.at<Vec3b>(row, col)[2] = 255 - red;
}
if (ch == 1) {
int pv = src.at<uchar>(row, col);
src.at<uchar>(row, col) = (255 - pv);
}
}
}
imshow("src", src);
waitKey(0);
destroyAllWindows();
return 0;
}

指针操作(实际工程中,多用指针,因为更加高效)
#include
#include
using namespace cv;
using namespace std;
int main(int argc, char** argv) {
Mat src = imread("E:/cats.jpg", IMREAD_COLOR);
if (src.empty()) {
printf("image is empty!!!");
return -1;
}
int height = src.rows;
int width = src.cols;
int ch = src.channels();
Mat result = Mat::zeros(src.size(), src.type());
for (int row = 0; row < height; row++) {
uchar* curr_row = src.ptr<uchar>(row);
uchar* result_row = result.ptr<uchar>(row);
for (int col = 0; col < width;col++) {
if (ch == 3) {
int blue = *curr_row++;
int green = *curr_row++;
int red = *curr_row++;
*result_row++ = blue;
*result_row++ = green;
*result_row++ = red;
}
if (ch == 1) {
int pv = *curr_row++;
*result_row++ = pv;
}
}
}
imshow("result", result);
waitKey(0);
destroyAllWindows();
return 0;
}
