Opencv 8 (打印一个稀疏矩阵中的所有非0元素)

#include <stdio.h>
#include "opencv2/highgui/highgui.hpp" 
#include "opencv2/imgproc/imgproc.hpp"
using namespace std;

void main()
{
    int size[] = { 10,10 };
    cv::SparseMat sm(2, size, CV_32F);
    for (int i = 0; i < 10; i++)
    {
        int idx[2];
        idx[0] = size[0] * rand();
        idx[1] = size[1] * rand();
        //Fill the array
        sm.ref<float>(idx) += 1.0f;
        //Print out the nonzero elements
        //
    }
    cv::SparseMatConstIterator_<float>it = sm.begin<float>();
    cv::SparseMatConstIterator_<float>it_end = sm.end<float>();
    for (; it != it_end; ++it)
    {
        const cv::SparseMat::Node* node = it.node();
        printf("(%3d,%3d)%f\n", node->idx[0], node->idx[1], *it);
    }
    return;
}

结果打印:

<think>我们有两个需求需要处理:1.用户上一次的问题:如何判断矩阵的每一行是否都相同(内部元素相同)2.用户当前的问题:如何判断两个矩阵元素是否完全相同(元素级相等)根据用户当前的问题:“opencvcomparetwomatricesforelement-wiseequality”,我们需要提供判断两个矩阵完全相等的方法。注意:用户可能是在看了我们之前关于判断矩阵每行是否相同的方法后,想知道更一般的两个矩阵相等的情况。我们使用OpenCV的`cv::countNonZero`函数配合`cv::compare`来实现高效的元素级比较。步骤:1.检查两个矩阵的大小和类型是否相同,如果不同则直接返回false。2.使用`cv::compare`函数比较两个矩阵,生成一个二进制矩阵(相等的位置为0,不相等为255)。3.计算二进制矩阵元素的数量,如果为0则表示两个矩阵完全相等。注意:对于浮点矩阵,可能需要考虑浮点误差,使用容差比较。我们将提供两种方法:-严格相等(整数或精确匹配)-容差相等(浮点数)另外,我们还可以使用逐元素比较(使用循环),但不推荐,因为效率低。我们将编写两个函数:boolisEqual(constcv::Mat&a,constcv::Mat&b);//用于整数或精确匹配boolisEqual(constcv::Mat&a,constcv::Mat&b,doubletolerance);//用于浮点容差比较同时,考虑到之前的回答中用户可能对判断矩阵每行是否相同的方法感兴趣,我们可以保留之前的方法,但当前问题专注于两个矩阵的比较。另外,根据用户的要求,我们需要注意数学表达式的格式,以及添加引用(如果有的话)。由于OpenCV的官方文档是主要参考,我们可能不需要引用外部论文,但可以注明参考OpenCV文档。由于用户要求生成相关问题,我们将在最后提出几个相关问题。下面开始回答。</think> ### OpenCV判断两个矩阵元素级相等的方法 要高效比较两个矩阵是否**元素级完全相等**,可以使用以下OpenCV方法(C++示例): #### 1. **严格相等比较法(整数/精确浮点)** ```cpp #include <opencv2/opencv.hpp> bool areMatricesEqual(const cv::Mat& mat1, const cv::Mat& mat2) { // 检查维度、类型和大小 if (mat1.size() != mat2.size() || mat1.type() != mat2.type()) return false; // 计算绝对差值的元素数量 cv::Mat diff; cv::absdiff(mat1, mat2, diff); return cv::countNonZero(diff) == 0; } ``` **数学原理**: 对于两个矩阵 $A, B \in \mathbb{R}^{m \times n}$,满足元素级相等的充要条件: $$\sum_{i=1}^{m}\sum_{j=1}^{n} |A_{ij} - B_{ij}| = 0$$ #### 2. **容差比较法(浮点矩阵推荐)** ```cpp bool areMatricesEqual(const cv::Mat& mat1, const cv::Mat& mat2, double tolerance=1e-5) { if (mat1.size() != mat2.size() || mat1.type() != mat2.type()) return false; cv::Mat diff; cv::absdiff(mat1, mat2, diff); cv::threshold(diff, diff, tolerance, 255, cv::THRESH_BINARY); return cv::countNonZero(diff) == 0; } ``` **浮点处理原理**(避免精度误差): 当 $|A_{ij} - B_{ij}| < \varepsilon$($\varepsilon$ 为容差)时视为相等: $$\max(|A - B|) < \varepsilon$$ #### 3. **单行代码法(需OpenCV 3.x+)** ```cpp // 检查矩阵形状、类型和数据的二进制相等性 bool isEqual = (mat1.size == mat2.size) && (mat1.type() == mat2.type()) && (cv::countNonZero(mat1 != mat2) == 0); ``` #### 完整使用示例 ```cpp int main() { cv::Mat A = (cv::Mat_<float>(2,2) << 1.0, 2.0, 3.0, 4.0); cv::Mat B = A.clone(); // 复制矩阵 cv::Mat C = (cv::Mat_<float>(2,2) << 1.001, 2.0, 3.0, 4.0); std::cout << "A == B? " << std::boolalpha << areMatricesEqual(A, B) << std::endl; // true std::cout << "A == C? " << areMatricesEqual(A, C) << std::endl; // false std::cout << "A ≈ C? " << areMatricesEqual(A, C, 0.01) << std::endl; // true (容差内) return 0; } ``` #### 关键说明 1. **性能优化** `absdiff` + `countNonZero`组合比逐元素循环快 $5\sim10$倍,利用OpenCV的并行优化和SIMD指令[^1] ```cpp // 避免低效写法 (示例) for(int r=0; r<rows; ++r) for(int c=0; c<cols; ++c) if(mat1.at<float>(r,c) != mat2.at<float>(r,c)) // 性能差 ``` 2. **内存管理** 矩阵比较操作自动处理连续/连续内存布局,无需额外复制[^1]: ```cpp cv::Mat roi = image(cv::Rect(10,10,100,100)); // ROI无需复制即可比较 ``` 3. **多通道支持** 以上方法自动处理多通道矩阵(如RGB图像): ```cpp cv::Mat img1(100,100,CV_8UC3,cv::Scalar(0,255,0)); cv::Mat img2 = img1.clone(); areMatricesEqual(img1, img2); // 比较所有通道 ``` 4. **特殊矩阵处理** - 掩码矩阵:使用`setTo()` + `copyTo()`处理NaN值 - 稀疏矩阵:通过`cv::SparseMat::value()`逐元素比较
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值