opencv Mat isContinuous()

本文解释了在内存中Mat数据结构的连续性概念及其重要性。通常情况下,Mat数据的每一行在内存中是连续存储的;然而,在进行某些操作如选取感兴趣区域(ROI)后,这种连续性可能会被打破。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这里的continue的意思是在内存上continue,正常情况下,头一行的末尾在内存里和下一行的开头是相连的,但是有时候我们做了一些操作,选取了Mat 的一部分,例如选了一个ROI 这时候就不满足上面说的相连了。那么这时候continuous就被判定为假。

转载于:https://www.cnblogs.com/drunknbeard/p/9671477.html

### 将 OpenCV 的 `cv::Mat` 转换为 Armadillo 的 `arma::mat` 为了实现从 OpenCV 的 `cv::Mat` 到 Armadillo 的 `arma::mat` 的转换,通常需要编写自定义函数来逐元素读取数据或将内存直接映射给 Armadillo。下面详细介绍两种常见的方式。 --- #### 方法一:逐元素赋值 这种方法适用于任意类型的矩阵(如浮点数、整数等),但效率较低,因为它涉及显式的循环操作。 ##### 实现代码 ```cpp #include <armadillo> #include <opencv2/core.hpp> void Cv_mat_to_arma_mat(const cv::Mat& cv_mat_in, arma::mat& arma_mat_out) { // 初始化 Armadillo 矩阵大小 arma_mat_out.set_size(cv_mat_in.rows, cv_mat_in.cols); // 遍历 OpenCV 矩阵并将数据复制到 Armadillo 矩阵中 for (int r = 0; r < cv_mat_in.rows; ++r) { for (int c = 0; c < cv_mat_in.cols; ++c) { arma_mat_out(r, c) = static_cast<double>(cv_mat_in.at<float>(r, c)); // 假设输入为 float 类型 } } } ``` 在这个例子中,假设输入的 `cv::Mat` 是单通道浮点类型 (`CV_32F`)。如果输入类型不同,则需调整 `.at<>()` 函数中的模板参数[^1]。 --- #### 方法二:利用内存共享 对于连续存储的矩阵(即未压缩且无步幅偏移的情况),可以直接将 OpenCV 矩阵的数据指针传递给 Armadillo,从而避免不必要的拷贝。 ##### 实现代码 ```cpp #include <armadillo> #include <opencv2/core.hpp> void Cv_mat_to_arma_mat_shared(const cv::Mat& cv_mat_in, arma::mat& arma_mat_out) { // 检查输入是否为连续存储 if (!cv_mat_in.isContinuous()) { throw std::runtime_error("Input matrix must be continuous."); } // 设置 Armadillo 矩阵大小 int rows = cv_mat_in.rows; int cols = cv_mat_in.cols; // 使用 Armadillo 的构造函数直接绑定数据指针 arma_mat_out = arma::mat(reinterpret_cast<const double*>(cv_mat_in.ptr<float>()), rows, cols, false /* 不复制 */); } ``` 这里的关键在于使用 `reinterpret_cast` 和 `ptr()` 获取 OpenCV 矩阵的底层数据地址,并将其传递给 Armadillo 的构造函数。注意,这种方式仅适用于连续存储的矩阵[^2]。 --- #### 注意事项 1. **数据类型匹配**:OpenCV 支持多种数据类型(如 `uint8`, `float`, `double` 等),而 Armadillo 默认支持双精度浮点数 (`double`)。因此,在转换前可能需要对数据进行类型转换。 2. **内存管理**:当采用内存共享方式时,必须确保原始 `cv::Mat` 对象在其整个生命周期内保持有效,否则可能导致未定义行为。 3. **性能优化**:对于大尺寸矩阵,建议优先考虑内存共享方法以减少冗余拷贝开销。 --- ### 示例测试代码 以下是一个完整的示例程序,演示如何将 OpenCV 的灰度图像转换为 Armadillo 矩阵: ```cpp #include <iostream> #include <armadillo> #include <opencv2/core.hpp> #include <opencv2/imgcodecs.hpp> // 定义转换函数 void Cv_mat_to_arma_mat(const cv::Mat& cv_mat_in, arma::mat& arma_mat_out) { arma_mat_out.set_size(cv_mat_in.rows, cv_mat_in.cols); for (int r = 0; r < cv_mat_in.rows; ++r) { for (int c = 0; c < cv_mat_in.cols; ++c) { arma_mat_out(r, c) = static_cast<double>(cv_mat_in.at<float>(r, c)); } } } int main() { // 加载一张灰度图像并转换为浮点类型 cv::Mat img = cv::imread("image.png", cv::IMREAD_GRAYSCALE); if (img.empty()) { std::cerr << "Error loading image." << std::endl; return -1; } img.convertTo(img, CV_32F); // 创建目标 Armadillo 矩阵 arma::mat arma_img; Cv_mat_to_arma_mat(img, arma_img); // 打印部分结果 std::cout << "Armadillo Matrix Size: " << arma_img.n_rows << "x" << arma_img.n_cols << std::endl; std::cout << "First few elements of the matrix:" << std::endl << arma_img.submat(0, 0, 5, 5) << std::endl; return 0; } ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值