当前位置: 首页 > 知识库问答 >
问题:

用OpenCV/C++计算两幅图像的相似率

东门修能
2023-03-14

我使用OpenCV/C++来计算两幅图像之间的相似率。 我想告诉用户%图像A看起来像图像B。

我们来看看下面的代码:

double getSimilarityRate(const cv::Mat A, const cv::Mat B){

    double cpt = 0.0;

    cv::Mat imgGray1, imgGray2;

    cv::cvtColor(A, imgGray1, CV_BGR2GRAY);
    cv::cvtColor(B, imgGray2, CV_BGR2GRAY);

    imgGray1 = imgGray1 > 128;
    imgGray2 = imgGray2 > 128;

    double total = imgGray1.cols * imgGray1.rows;

    if(imgGray1.rows > 0 && imgGray1.rows == B.rows && imgGray1.cols > 0 && imgGray1.cols == B.cols){

        for(int rows = 0; rows < imgGray1.rows; rows++){

            for(int cols = 0; cols < imgGray1.cols; cols++){

                if(imgGray1.at<int>(rows, cols) == imgGray2.at<int>(rows,cols)) cpt ++;
            }
        }

    }else{

        std::cout << "No similartity between the two images ... [EXIT]" << std::endl;
        exit(0);

    }

    double rate = cpt / total;


    return rate * 100.0;
}

int main(void)
{

/* ------------------------------------------ # ALGO GETSIMILARITY BETWEEN 2 IMAGES # -------------------------------------- */

    double rate;

    string fileNameImage1("C:\\Users\\hugoo\\Documents\\Prog\\NexterMU\\Qt\\OpenCV\\DetectionShapeProgram\\mire.jpg");
    cv::Mat image1 = imread(fileNameImage1);

    string fileNameImage2("C:\\Users\\hugoo\\Documents\\Prog\\NexterMU\\Qt\\OpenCV\\DetectionShapeProgram\\mire.jpg");
    cv::Mat image2 = imread(fileNameImage2);

    if(image1.empty() || image2.empty()){

        std::cout << "Images couldn't be loaded" << std::endl;
        exit(-1);

    }
    
    rate =  getSimilarityRate(image1, image2) ;

首先,我将矩阵从BGR转换为灰度。 所以我只剩下一个频道了。 (比较起来要容易得多)。

cv::Mat imgGray1, imgGray2;

cv::cvtColor(A, imgGray1, CV_BGR2GRAY);
cv::cvtColor(B, imgGray2, CV_BGR2GRAY);

然后我将它们设置为二进制(255或0-->像素的白色或黑色):

imgGray1 = imgGray1 > 128;
imgGray2 = imgGray2 > 128;

在我的for循环中,我通过每个像素,并将他与第二幅图像中的其他像素进行比较。 如果匹配,我增加一个变量(cpt++)。

我计算速率并将其转换为%,其中:

 double rate = cpt / total;
 return rate * 100.0;

问题是它似乎计算不正确,因为它没有返回控制台中的速率值。。。

输出控制台

我认为问题来自于at()函数,也许我没有正确使用它。

如果有人能引导我度过难关,帮我解决这个问题,我会很感激的。

如果你需要更多的信息,告诉我:)。

谢谢。

共有1个答案

佟涵畅
2023-03-14

我怀疑imggray1.at (rows,cols) 应该改为imggray1.at (rows,cols)

当前.at()函数调用具有int作为模板参数,但通常cv::matuchar元素组成。 您确定您的映像包含int元素吗? 如果它确实由uchar元素组成,那么使用int模板参数将导致访问超出与图像对应的内存(基本上所有指针偏移量现在都是应该的4倍)。

更一般地,如果使用cv::mat::at(),则需要根据cv::mat::type()的输出使用不同的模板参数:

  • 8位3通道镜像(CV_8UC3)-->; .at (行,列)
  • 8位单通道镜像(CV_8UC1)-->; .at (row,column)
  • 32位3通道映像(CV_32FC3)-->; .at (行,列)
  • 32位单通道映像(CV_32FC1)-->; .at (row,column)

因此,如果函数应该支持任意的cv::mat,则需要编写一组if-else子句,或者完全避免.at()。 在您的情况下,由于imggray1imggray2是“二进制化”的,我想知道是否可以使用CV::Norm计算速率,可能如下:

// NORM_INF counts the number of non-equal elements.
int num_non_equal = cv::norm(imgGray1, imgGray2, NORM_INF);
double rate = 1.0 - num_non_equal / static_cast<double>(total);
 类似资料:
  • 问题内容: 我可以使用下面显示的代码找到匹配的功能。我想计算两个图像之间的百分比相似度。我是OpenCV的新手。任何帮助将不胜感激。 是否有其他可用于相同目的的库? 问题答案: 我发现两个库pHash和pdiff提供了我想要的东西。我将评估它们的性能以及与我的代码的兼容性,并选择最佳的代码。

  • 问题内容: 我正在尝试将一张图片与其他图片列表进行比较,并返回该列表中具有最高70%相似度的图片(例如Google搜索图片)。 我在这篇文章中获得了这段代码,并根据自己的情况进行了更改 我的问题是,如何将图像与图像列表进行比较并仅获得相似图像?有什么方法可以做到这一点? 问题答案: 我建议您看一下图像之间推土机的距离(EMD)。该度量给人一种将标准化的灰度图像转换成另一幅图像有多难的感觉,但可以将

  • 本文向大家介绍C#计算2个字符串的相似度,包括了C#计算2个字符串的相似度的使用技巧和注意事项,需要的朋友参考一下 计算字符串相似度,直接来C#代码 返回结果就是相似度了,验证码识别上用的到 爱给模板网提供 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。

  • 问题内容: 我在Python中具有以下测试代码以读取,设置阈值和显示图像: 我想计算带有特定标签(例如黑色)的图像内像素的数量。我怎样才能做到这一点 ?我看了OpenCV的教程,但没有找到任何帮助:-( 谢谢! 问题答案: 对于黑色图像,您将获得像素总数(行*列),然后从得出的结果中减去它。 对于其他值,您可以创建一个遮罩,该遮罩用于返回显示所需颜色/标签/值的所有位置的二进制遮罩,然后用于计算其

  • 问题内容: 如何找到向量之间的余弦相似度? 我需要找到相似性来衡量两行文本之间的相关性。 例如,我有两个句子: 用户界面系统 用户界面机 …及其在tF-idf之后的向量,然后使用LSI进行标准化,例如 和。 如何测量这些向量之间的相似性? 问题答案: 我最近在大学的信息检索部门做了一些tf-idf的工作。我使用了这种余弦相似度方法,该方法使用Jama:Java Matrix Package 。 有

  • 涉及函数cv2.add(),cv2.addWeighted() 一、图像加法 使用cv2.add()将两幅图像进行加法运算,也可以直接使用numpy,res=img1+img2.两幅图像的大小,类型必须一致,或者第二个图像可以是一个简单的标量值。 openCV的加法是一种饱和操作,而numpy的加法是一种模操作。 x=np.uint8([250]) y=np.uint8([10]) print(c

  • 问题内容: 我正在尝试匹配两个图像的直方图(在MATLAB中,这是可以做到的) 使用 ). 标准Python库中是否有可用的等效函数?我已经 查看了OpenCV、scipy和numpy,但没有看到任何类似的功能。 问题答案: 我以前写过一个答案 这里解释如何做 图像直方图的分段线性插值 高光/中音/阴影的特定比率。 相同的基本原则是[直方图]的基础 匹配两人之间 图像。基本上,你要计算出你的源和目

  • 问题内容: 假设您在数据库中按以下方式构造了一个表: 为了清楚起见,应输出: 请注意,由于向量存储在数据库中,因此我们仅需要存储非零条目。在此示例中,我们只有两个向量$ v_ {99} =(4,3,4,0)$和$ v_ {1234} =(0,5,2,3)$都在$ \ mathbb {R}中^ 4 $。 这些向量的余弦相似度应为$ \ displaystyle \ frac {23} {\ sqrt