赞
踩
本文深入探索OpenCV库中cv::Mat类的使用方法和技巧。cv::Mat作为OpenCV中用于存储图像数据的基本数据结构,其使用范围广泛且功能强大。通过本文,你将了解cv::Mat的创建、访问和修改数据的基本操作,以及其在图像处理任务中的具体应用。此外,我还会分享一些在使用cv::Mat时可能遇到的常见问题及其解决方案,帮助你更好地掌握这一工具。无论你是OpenCV的新手还是资深用户,相信这篇博客都能为你提供有价值的参考和启示。
Mat::Mat()
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)
Mat::Mat(int rows, int cols, int type, void* data, size_t step=AUTO_STEP)
Mat::Mat(Size size, int type, void* data, size_t step=AUTO_STEP)
Mat::Mat(const Mat& m, const Range& rowRange, const Range& colRange)
Mat::Mat(const Mat& m, const Rect& roi)
- cv::Mat a = cv::Mat::eye(4, 4, CV_64FC1); // 单通道double类型
- cv::Mat b = cv::Mat::eye(4, 4, CV_8UC1); // 单通道char类型
- cv::Point3f v1(34.0f, 21.34f, 32.0f);
- cv::Mat m{ cv::Mat_<cv::Point3f>(v1) };
- //得到1行1列3通道的矩阵
- cv::Point3f point(34.0f, 21.34f, 32.0f);
- cv::Mat m(point);
- //得到3行1列1通道的矩阵
- std::vector<double> vec{ 21.3, -10, 34.0, 3.2, 3.4 };
- cv::Mat m{ vec };
- //得到5行1列1通道的矩阵
- //得到2行1列2通道的矩阵
- std::vector<cv::Point2f> vecpts{ cv::Point2f(2.3, 3.1), cv::Point2f(9.3, -10.0) };
- cv::Mat m{ vecpts };
- //得到3行3列1通道的矩阵
- cv::Mat C = (cv::Mat_<double>(3,3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
这些方式看似正确,但实际不行
- cv::Mat matrix = cv::Mat::zeros(4, 4, CV_64FC1);
- cv::Mat calibration = cv::Mat::eye(3, 3, CV_64FC1);
-
- // 方法一
- cv::Mat a = matrix.rowRange(0, 3).colRange(0, 3); // 共享内存
- a = calibration;
-
- // 方法二
- cv::Mat matrix = cv::Mat::zeros(4, 4, CV_64FC1);
- matrix.rowRange(0, 3).colRange(0, 3) = calibration.clone();
-
- // 方法三
- calibration.copyTo(matrix.rowRange(0, 3).colRange(0, 3)); // 编译失败
正确的方式
- cv::Mat matrix = cv::Mat::zeros(4, 4, CV_64FC1);
- cv::Mat a = matrix.rowRange(0, 3).colRange(0, 3); // 共享内存
- xa.copyTo(a);
- cv::Mat b = matrix.rowRange(0, 3).col(3); // 共享内存
- xb.copyTo(b);
注意:只支持double类型的转换,不支持float类型
- #include <opencv2/core/eigen.hpp>
-
- cv::cv2eigen(cv_matrix, eigen_matrx);
-
- cv::eigen2cv(eigen_matrx, cv_matrix);
- cv::Mat matrix = cv::Mat::zeros(4, 4, CV_64FC1);
-
- // 方法一
- const double *data = matrix.ptr<double>(0);
-
- // 方法二
- // img.data的默认类型是unsigned char*
- double* data = (matrix*)img.data;
C++本来是强类型语言,但cv::Mat却是弱类型的,即当你拿到一个cv::Mat的时候你并不知道它里面存储的数据类型,很容易用错;
当你把你的cv::Mat对象传给某函数时,即使函数的形参加了const关键字,但它依然可能会被修改,这是因为cv::Mat有共享内存机制,它的拷贝是浅拷贝;
cv::Mat构造时间很长,如果非必要不建议使用,构造过程尽量写在循环外面;
- cv::Mat A = imread(“Imgpath”, CV_LOAD_IMAGE_COLOR);
-
- A.at<Vec3b>(row, col)[2] // 访问图像数据
注意 Mat::at 函数是个模板函数, 需要指明参数类型, 因为这张图是具有红蓝绿三通道的图,所以它的参数类型可以传递一个 Vec3b,这是一个存放 3 个 uchar 数据的 Vec(向量)。这里提供了索引重载,[2]表示的是返回第三个通道,在这里是 Red 通道,第一个通道(Blue)用[0]返回
imwrite(image_path, A);
- Mat src(m, n CV_8UC3);
- Mat dst;
- cvtColor(src,dst,CV_BGR2GRAY);
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。