gpt4 book ai didi

c++ - 使用 opencv/c++ 计算两个图像之间的相似率

转载 作者:行者123 更新时间:2023-12-02 16:50:42 25 4
gpt4 key购买 nike

我正在使用 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 转换为 GREY。所以我只剩下一个 channel 了。 (更容易比较)。
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;
问题是它似乎没有正确计算,因为它没有在控制台中返回我的速率值......
Output Console
我认为问题来自 at() 函数,也许我没有正确使用它。

最佳答案

我怀疑 imgGray1.at<int>(rows, cols)应该是 imgGray1.at<uchar>(rows, cols)反而。
目前.at()函数调用有 int作为模板参数,但通常是 cv::Matuchar 组成元素。你确定你的图片有int元素?如果它包含 uchar元素,然后使用 int模板参数将导致访问超出与图像对应的内存(基本上所有指针偏移量现在将是它们应有的 4 倍)。
更一般地说,如果您使用 cv::Mat::at() ,您需要根据 cv::Mat::type() 的输出使用不同的模板参数:

  • 8 位 3 channel 图像 (CV_8UC3) --> .at<cv::Vec3b>(row, column)
  • 8 位 1 channel 图像 (CV_8UC1) --> .at<uchar>(row, column)
  • 32 位 3 channel 图像 (CV_32FC3) --> .at<cv::Vec3f>(row, column)
  • 32 位 1 channel 图像 (CV_32FC1) --> .at<float>(row, column)

  • 因此,如果一个函数应该支持任意 cv::Mat的,要么需要编写一堆 if-else 子句,要么避免 .at()共。在您的情况下,由于 imgGray1imgGray2被“二值化”,我想知道 rate可以使用 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);

    关于c++ - 使用 opencv/c++ 计算两个图像之间的相似率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63036139/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com