我们可以检查列表中是否存在重复的图像吗?

时间:2013-03-22 11:57:53

标签: android image list opencv duplicates

我是图像处理新手。我的问题是......

  

我使用相机拍摄图像,然后使用此图像并对照列表容器进行检查。如果列表容器包含看起来像此图像的图像,则执行操作,否则不执行操作。

示例...

  1. 我有一张图片“img_one”
  2. 我的列表包含“image_one,image_two,image_three”
  3. 显示列表有image_one(即看起来像这张图片)
  4. 那么如何针对列表容器中的项目检查此图像并显示哪个图像看起来像这个图像?

    先谢谢朋友们。所有的想法都受到赞赏。

3 个答案:

答案 0 :(得分:2)

很大程度上取决于你用“复制”来定义什么。

如果您正在寻找完全相同的副本(复制粘贴),游戏很简单。 Safir提出的方法,只有一些性能改进,是好的。

如果你想找到几乎完全相同的副本,这项工作突然变得非常困难。有关详细信息,请查看此Checking images for similarity with OpenCV

现在,回到“简单”的方法,它取决于你需要比较多少张图片。因为将每个图像与具有1000个图像的文件夹中的所有其他图像进行比较,可以进行1.000.000次图像读取和比较。 (因为你无法将它们全部存储在RAM中,所以你必须加载和卸载它们一百万次)这种方式对于一个功能强大的桌面处理器来说太过分了。

一种简单的方法是为每个图像使用散列函数(如sha2),然后仅比较散列。图像的一个好的特殊“散列”可能是直方图(虽然对于肯定,你可能想用memcmp仔细检查)。

即使您尝试使用蛮力方法(将每个图像像素与另一个图像像素进行比较),更快的方法是使用memcmp()而不是逐个像素地访问图像。

答案 1 :(得分:1)

我不认为opencv中存在这样的功能。你必须自己遍历像素并逐个检查它们。示例代码可以是这样的:

bool identical(cv::Mat m1, cv::Mat m2)
{
  if ( m1.cols != m2.cols || m1.rows != m2.rows || m1.channels() != m2.channels() || m1.type() != m2.type() )
    {
      return false;
    }

  for ( int i = 0; i < m1.rows; i++ )
    {
      for ( int j = 0; j < m1.cols; j++ )
        {
          if ( m1.at(i, j) != m2.at(i, j) )
            {
              return false;
            }
        }
    }
  return true;
}

如果您希望在所有像素中加倍迭代,可以查看OpenCV: Matrix Iteration

答案 2 :(得分:-1)

我认为比较两张图片需要花费一点时间。但是你可以通过从适配器或用ListView绑定图像的位置比较那些图像的二进制文件来检查它。