我是图像处理的新手。我的问题是......
我使用相机拍摄图像,然后使用此图像并对照列表容器检查它。如果列表容器包含看起来像此图像的图像,则执行操作,否则不执行。
例子...
- 我有一张图片“img_one”
- 我的列表包含“image_one,image_two,image_three”
- 显示列表有 image_one(即看起来像这张图片)
那么如何根据列表容器中的项目检查此图像并显示哪个图像看起来像此图像?
先谢谢朋友。所有的想法都受到赞赏。
我是图像处理的新手。我的问题是......
我使用相机拍摄图像,然后使用此图像并对照列表容器检查它。如果列表容器包含看起来像此图像的图像,则执行操作,否则不执行。
例子...
那么如何根据列表容器中的项目检查此图像并显示哪个图像看起来像此图像?
先谢谢朋友。所有的想法都受到赞赏。
这在很大程度上取决于您对“重复”的定义。
如果您正在寻找完全相同的副本(复制粘贴),那么游戏很简单。Safir 提出的方法,只进行了一些性能改进,就可以了。
如果您想找到几乎完全相同的副本,那么这项工作会突然变得异常困难。查看此检查图像与 OpenCV 的相似性以获取更多信息。
现在,回到“简单”的方法,这取决于你必须比较多少张图片。因为将每个图像与包含 1000 张图像的文件夹中的所有其他图像进行比较,您可以获得 1.000.000 次图像读取和比较。(因为您不能一次将它们全部存储在 RAM 中,您将不得不加载和卸载它们一百万次)即使是强大的桌面处理器,这种方式也太多了。
一种简单的方法是对每个图像使用散列函数(如 sha2),然后只比较散列。直方图可能是图像的一个很好的临时“散列”(尽管您可能需要使用 memcmp 仔细检查)。
即使您尝试蛮力方法(将每个图像像素与另一个进行比较),更快的方法是使用 memcmp() 而不是逐个像素地访问图像。
我认为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。
我认为比较两张图像有点耗时。但是您可以通过从适配器或您将图像与 ListView 绑定的位置相互比较该图像的二进制文件来检查它。