C++ 有效计算随机误差

C++ 有效计算随机误差,c++,algorithm,opencv,image-processing,optimization,C++,Algorithm,Opencv,Image Processing,Optimization,我试图比较两个图像分割。 为此,我将每个图像转换为无符号短值向量,并计算, 根据以下公式: 其中: 这是我的代码(随机误差计算部分): cv::Mat im1,im2; //用于获取im1、im2数据的代码 //复制im1(:)->v1、im2(:)->v2的代码 int N=v1.size(); 双a=0; 双b=0; 对于(int i=0;i在阅读了您的评论后,我尝试了以下方法: 计算每对可能值的交点 使用交点结果计算误差 我直接在cv::Mat对象上执行计算,而没有将它们转换为std:

我试图比较两个图像分割。 为此,我将每个图像转换为无符号短值向量,并计算, 根据以下公式:

其中:

这是我的代码(随机误差计算部分):

cv::Mat im1,im2;
//用于获取im1、im2数据的代码
//复制im1(:)->v1、im2(:)->v2的代码
int N=v1.size();
双a=0;
双b=0;

对于(int i=0;i在阅读了您的评论后,我尝试了以下方法:

  • 计算每对可能值的交点
  • 使用交点结果计算误差
  • 我直接在cv::Mat对象上执行计算,而没有将它们转换为std::vector对象。这使我能够使用opencv函数并实现更快的运行时间

    代码:


    感谢大家的帮助!

    让我们假设第一幅图像中有p个不同的标签,第二幅图像中有Q个不同的标签。有效计算随机误差(也称为随机指数)的关键观察结果是,不同标签的数量通常比像素的数量小得多(即P,Q你能创建一个{value->count}的散列映射吗?这将把运行时间从O(n^2)减少到O(n)。这意味着你应该只需要外部循环(我认为)-对于每个
    i
    ,查找
    v1[i]
    ,结果就是你需要添加到
    a
    @OliverCharlesworth-排外的想法!我会试试。你不需要测试对。你只需要知道在对象的交点有多少个元素。从这些值你可以很容易地计算
    a
    b
    。@VittorioPatriarca我正在读e与drorco的方法相同。我认为两个对的索引需要对应。谢谢你的回答!你的回答基于与我相同的原则(我们实际上有相同的伪代码),但由于您在不需要openCV的情况下解决了一般情况下的问题,我认为您的解决方案更一般,这就是我接受它的原因。
    cv::Mat im1,im2;
    
    //code for acquiring data for im1, im2
    //code for copying im1(:)->v1, im2(:)->v2
    
    
    int N = v1.size();
    double a = 0;
    double b = 0;
    for (int i = 0; i <N; i++)
    {
        for (int j = 0; j < i; j++)
        {
            unsigned short l1 = v1[i];
            unsigned short l2 = v1[j];
            unsigned short gt1 = v2[i];
            unsigned short gt2 = v2[j];
            if (l1 == l2 && gt1 == gt2)
            {
                a++;
            }
            else if (l1 != l2 && gt1 != gt2)
            {
                b++;
            }
    
        }
    }
    
    double NPairs = (double)(N*N)/2;
    double res = (a + b) / NPairs;
    
    double a = 0, b = 0; //init variables
    
    //unique function finds all the unique value of a matrix, with an optional input mask
    std::set<unsigned short> m1Vals = unique(mat1); 
    for (unsigned short s1 : m1Vals)
    {
        cv::Mat mask1 = (mat1 == s1);
        std::set<unsigned short> m2ValsInRoi = unique(mat2, mat1==s1);
        for (unsigned short s2 : m2ValsInRoi)
        {
            cv::Mat mask2 = mat2 == s2;
            cv::Mat andMask = mask1 & mask2;
            double andVal = cv::countNonZero(andMask);
            a += (andVal*(andVal - 1)) / 2;
            b += ((double)cv::countNonZero(andMask) * (double)cv::countNonZero(~mask1 & ~mask2)) / 2;
        }
    }
    
    double NPairs = (double)(N*(N-1)) / 2;
    double res = (a + b) / NPairs;
    
    //mat1 = [1 1 2]
    cv::Mat mat1 = cv::Mat::ones(cv::Size(3, 1), CV_16U);
    mat1.at<ushort>(cv::Point(2, 0)) = 2;
    
    //mat2 = [1 2 1]
    cv::Mat mat2 = cv::Mat::ones(cv::Size(3, 1), CV_16U);
    mat2.at<ushort>(cv::Point(1, 0)) = 2;
    
    a = 0
    b = 1
    NPairs = 3
    result = 0.3333333