**1.Mat对象与IplImage对象
2.Mat对象使用
3.Mat定义数组**
Mat对象OpenCV2.0之后引进的图像数据结构、自动分配内存、不存在内存泄漏的问题,是面向对象的数据结构。分了两个部分,头部与数据部分
IplImage是从2001年OpenCV发布之后就一直存在,是C语言风格的数据结构,需要开发者自己分配与管理内存,对大的程序使用它容易导致内存泄漏问题
1.Mat()
创建一个Mat对象,在构造时不进行任何操作
//创建一个Mat对象
Mat img;
2.Mat(int rows , int cols,int type)
根据用户指定的行数、列数以及类型创建一个Mat对象
//创建一个3*3的图像,每个通道8个字节长度 uchar类型,通道数量为1的Mat对象
Mat img= Mat(3,3,CV_8UC1);
3.Mat(Size size , int type)
根据用户指定的大小以及类型,创建一个Mat对象
//读取本地图像返回给Mat对象src,根据src的大小,创建一个3*3的图像,每个通道8个字节长度 uchar类型,通道数量为1的Mat对象
Mat src = imread("E:/OpenCV/OpenCVPicture/horse.png");
Mat img= Mat(src.size(),CV_8UC1);
4.Mat(int rows , int cols,int type,const Scalar &s)
根据用户指定的行数、列数以及类型创建一个Mat对象并初始化每个像素的值,向量长度必须对应通道数
//创建一个3*3的图像,每个通道8个字节长度 uchar类型,通道数量为3的Mat对象,并将初始颜色设为(127,0,255)
Mat img= Mat(3,3,CV_8UC3,Scalar(127,0,255))
5.Mat(Size size , int type , const Scalar &s)
根据用户指定的大小以及类型,创建一个Mat对象并初始化每个像素的值,向量长度必须对应通道数
//读取本地图像返回给Mat对象src,根据src的大小,创建一个3*3的图像,每个通道8个字节长度 uchar类型,通道数量为3的Mat对象,并将初始颜色设为(127,0,255)
Mat src = imread("E:/OpenCV/OpenCVPicture/horse.png");
Mat img= Mat(src.size(),CV_8UC3,Scalar(127,0,255));
6.数组构造
使用矩阵数据构造一个Mat对象
//构成3*3
// 0 -1 0
// -1 5 -1
// 0 -1 0
//的Mat图像
Mat mat = (Mat_(3,3)<<0,-1,0,-1,5,-1,0,-1,0);
1.void copyTo(Mat mat)
Mat对象深拷贝
//将src对象的图像复制到dst对象中
Mat src = imread("E:/OpenCV/OpenCVPicture/horse.png");
Mat dst;
src.copyTo(dst);
2.void converto(Mat dst,int type)
Mat对象转化函数
//将src转化成每个通道8个字节长度 uchar类型,通道数量为3的Mat对象(可以在函数后面附加因子进行计算)
Mat src = imread("E:/OpenCV/OpenCVPicture/horse.png");
Mat dst;
str.converto(dst,CV_8UC3);
3.Mat clone()
Mat对象深拷贝
//将src对象的图像复制到dst对象中
Mat src = imread("E:/OpenCV/OpenCVPicture/horse.png");
Mat dst;
dst.clone(src);
4.int channels()
获取当前图像的通道数
//获取src的通道数
Mat src = imread("E:/OpenCV/OpenCVPicture/horse.png");
int channel = src.channels();
5.int depth()
获取当前图像的深度
//获取src的深度
Mat src = imread("E:/OpenCV/OpenCVPicture/horse.png");
int channel = src.depth();
6.bool empty()
判断图像是否为空
Mat src = imread("E:/OpenCV/OpenCVPicture/horse.png");
Mat dst;
src.empty(); //false
dst.empty(); //true
7.uchar* ptr(i = 0)
获取当前图像的指针
//获取src图像的第一行对应指针
Mat src = imread("E:/OpenCV/OpenCVPicture/horse.png");
const unchar* fisrtRow = src.ptr(0);
8.Mat zeros(int rows,int cols,int type)
创建全0的Mat对象
//创建2*2每个通道8个字节长度 uchar类型,通道数量为1的全0 Mat对象
Mat img = Mat::zeros(2,2,CV_8UC1)
9.Mat eye(int rows,int cols,int type)
创建对角线为1的Mat对象
//创建2*2每个通道8个字节长度 uchar类型,通道数量为1的对象线为1 Mat对象
//1 0
//0 1
Mat img = Mat::eye(2,2,CV_8UC1)
_Tp& at(int row,int col)
获取图像上一个点的像素,可对其进行获取或者修改,灰度图像和RGB图像有区别
/对于灰度图像进行像素点的获取以及修改/
//打开原始图像
Mat src = imread(“E:/OpenCV/OpenCVPicture/horse.png”);
Mat gray_src;
//将RGB图像转化成灰度图像
cvtColor(src,gray_src,CV_BGR2GRAY);
//获取灰度图像在 (0,0)处的像素值
uchar test = gray_src.at(0,0);
//修改灰度图像在 (0,0)处的像素值
gray_src.at(0,0) = 0
/对于RGB图像进行像素点的获取以及修改/
Mat src = imread(“E:/OpenCV/OpenCVPicture/horse.png”);
//获取RGB像素
uchar blue= src.at(0,0)[0]; //蓝色通道像素值
uchar green= src.at(0,0)[1]; //绿色通道像素值
uchar red = src.at(0,0)[2]; //红色通道像素值
//修改RGB像素
src.at(0,0)[0] = 0; //修改蓝色通道像素为0
src.at(0,0)[1] = 0; //修改绿色通道像素为0
src.at(0,0)[2] = 0; //修改红色通道像素为0
1.输出图像的内存是自动分配的
2.使用OpenCV的C++接口,不需要考虑内存分配问题
3.赋值操作和拷贝构造函数只会复制头部分
4.使用clone与copyTo两个函数实现数据完全复制
cv::Mat::Mat构造函数
Mat M(2,2,CV_8UC3, Scalar(0,0,255))
其中前两个参数分别表示行(row)跟列(column)、第三个CV_8UC3中的8表示每个通道占8位、U表示无符号、C表示Char类型、3表示通道数目是3,第四个参数是向量表示初始化每个像素值是多少,向量长度对应通道数目一致
创建多维数组cv::Mat::create
int sz[3] = {2,2,2};
Mat L(3,sz, CV_8UC1, Scalar::all(0));
Mat M;
M.create(4, 3, CV_8UC2);
M = Scalar(127,127);
cout << "M = " << endl << " " << M << endl << endl;
uchar* firstRow = M.ptr<uchar>(0);
printf("%d", *firstRow);
#include
#include
#include
#include
using namespace cv;
using namespace std;
int main(int argc, char** args) {
Mat image = imread("D:/test.jpg", IMREAD_GRAYSCALE);
if (image.empty()) {
cout << "could not find the image resource..." << std::endl;
return -1;
}
namedWindow("My Image", CV_WINDOW_AUTOSIZE);
imshow("My Image", image);
Mat M;
M.create(4, 3, CV_8UC2);
M = Scalar(127,127);
cout << "M = " << endl << " " << M << endl << endl;
uchar* firstRow = M.ptr<uchar>(0);
printf("%d\n", *firstRow);
Mat C = (Mat_<double>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
cout << "C = " << endl << " " << C << endl << endl;
waitKey(0);
return 0;
}
1.读写图像
2.读写像素
3.修改像素值
imread 可以指定加载为灰度或者RGB图像
Imwrite 保存图像文件,类型由扩展名决定
1.读一个GRAY像素点的像素值(CV_8UC1)
Scalar intensity = img.at(y, x);
或者 Scalar intensity = img.at(Point(x, y));
2.读一个RGB像素点的像素值
Vec3f intensity = img.at(y, x);
float blue = intensity.val[0];
float green = intensity.val[1];
float red = intensity.val[2];
灰度图像
img.at(y, x) = 128;
RGB三通道图像
img.at(y,x)[0]=128; // blue
img.at(y,x)[1]=128; // green
img.at(y,x)[2]=128; // red
空白图像赋值
img = Scalar(0);
ROI选择
Rect r(10, 10, 100, 100);
Mat smallImg = img®;
Vec3b对应三通道的顺序是blue、green、red的uchar类型数据。
Vec3f对应三通道的float类型数据
把CV_8UC1转换到CV32F1实现如下:
src.convertTo(dst, CV_32F);
#include
#include
#include
#include
using namespace cv;
using namespace std;
int main(int argc, char** args) {
Mat image = imread("D:/test.jpg", IMREAD_COLOR);
if (image.empty()) {
cout << "could not find the image resource..." << std::endl;
return -1;
}
int height = image.rows;
int width = image.cols;
int channels = image.channels();
printf("height=%d width=%d channels=%d", height, width, channels);
for (int row = 0; row < height; row++) {
for (int col = 0; col < width; col++) {
if (channels == 3) {
image.at<Vec3b>(row, col)[0] = 0; // blue
image.at<Vec3b>(row, col)[1] = 0; // green
}
}
}
namedWindow("My Image", CV_WINDOW_AUTOSIZE);
imshow("My Image", image);
waitKey(0);
return 0;
}