Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Image 使用OpenCV检查图像的相似性_Image_Opencv_Comparison_Similarity - Fatal编程技术网

Image 使用OpenCV检查图像的相似性

Image 使用OpenCV检查图像的相似性,image,opencv,comparison,similarity,Image,Opencv,Comparison,Similarity,OpenCV是否支持比较两个图像,并返回一些值(可能是百分比),指示这些图像的相似程度?例如,如果两次传递相同的图像,则返回100%;如果图像完全不同,则返回0% 我已经在StackOverflow上阅读了很多类似的主题。我也做了一些谷歌搜索。遗憾的是,我无法给出令人满意的答案。这是一个巨大的主题,答案从3行代码到整个研究杂志 我将概述最常见的此类技术及其结果 比较直方图 最简单、最快的方法之一。几十年前提出的一种发现图片相似性的方法。这个想法是一片森林会有很多绿色,一张人类的脸会有很多粉红色,

OpenCV是否支持比较两个图像,并返回一些值(可能是百分比),指示这些图像的相似程度?例如,如果两次传递相同的图像,则返回100%;如果图像完全不同,则返回0%


我已经在StackOverflow上阅读了很多类似的主题。我也做了一些谷歌搜索。遗憾的是,我无法给出令人满意的答案。

这是一个巨大的主题,答案从3行代码到整个研究杂志

我将概述最常见的此类技术及其结果

比较直方图 最简单、最快的方法之一。几十年前提出的一种发现图片相似性的方法。这个想法是一片森林会有很多绿色,一张人类的脸会有很多粉红色,或者别的什么。所以,如果你将两幅图片与森林进行比较,你会发现直方图之间有一些相似性,因为两者都有很多绿色

缺点:它太简单化了。香蕉和海滩看起来是一样的,因为它们都是黄色的

OpenCV方法:compareHist()

模板匹配 这是一个很好的例子。它将搜索图像与正在搜索的图像进行卷积。它通常用于在较大的图像中查找较小的图像部分

缺点:它只能返回相同图像、相同大小和方向的良好结果

OpenCV方法:matchTemplate()

特征匹配 被认为是进行图像搜索最有效的方法之一。从图像中提取大量特征,确保即使在旋转、缩放或倾斜时也能再次识别相同的特征。通过这种方法提取的特征可以与其他图像特征集进行匹配。具有与第一幅图像匹配的高比例特征的另一幅图像被认为描绘了相同的场景

找到两组点之间的单应性,还可以找到原始图片之间拍摄角度的相对差异或重叠量

这方面有很多OpenCV教程/示例,还有一个不错的视频。一个完整的OpenCV模块(features2d)专用于此

缺点:速度可能很慢。它并不完美



在网站上,我谈论的是特征描述符之间的区别,当比较整个图像和纹理描述符时,它们非常重要,纹理描述符用于识别图像中的人脸或汽车等对象。

如果用于匹配相同的图像(相同的大小/方向)


有点离题,但pythonic
numpy
方法很有用。它的健壮性和快速性,但只是比较像素,而不是图片包含的对象或数据(它需要相同大小和形状的图像):

在没有openCV和任何计算机视觉库的情况下,一种非常简单和快速的方法是通过

import numpy as np
picture1 = np.random.rand(100,100)
picture2 = np.random.rand(100,100)
picture1_norm = picture1/np.sqrt(np.sum(picture1**2))
picture2_norm = picture2/np.sqrt(np.sum(picture2**2))
定义两个标准图片(或矩阵)后,您可以将要比较的图片相乘求和:

1) 如果比较类似图片,总和将返回1:

In[1]: np.sum(picture1_norm**2)
Out[1]: 1.0
2) 如果它们不相似,则会得到一个介于0和1之间的值(如果乘以100,则为百分比):


请注意,如果您有彩色图片,您必须在所有3维中执行此操作,或者仅比较灰度缩放版本。我经常需要将大量图片与任意内容进行比较,这是一种非常快速的方法。

Sam的解决方案应该足够了。我使用了直方图差异和模板匹配的组合,因为没有一种方法100%适用于我。不过,我对直方图方法不太重视。下面是我如何用简单的python脚本实现的

import cv2

class CompareImage(object):

    def __init__(self, image_1_path, image_2_path):
        self.minimum_commutative_image_diff = 1
        self.image_1_path = image_1_path
        self.image_2_path = image_2_path

    def compare_image(self):
        image_1 = cv2.imread(self.image_1_path, 0)
        image_2 = cv2.imread(self.image_2_path, 0)
        commutative_image_diff = self.get_image_difference(image_1, image_2)

        if commutative_image_diff < self.minimum_commutative_image_diff:
            print "Matched"
            return commutative_image_diff
        return 10000 //random failure value

    @staticmethod
    def get_image_difference(image_1, image_2):
        first_image_hist = cv2.calcHist([image_1], [0], None, [256], [0, 256])
        second_image_hist = cv2.calcHist([image_2], [0], None, [256], [0, 256])

        img_hist_diff = cv2.compareHist(first_image_hist, second_image_hist, cv2.HISTCMP_BHATTACHARYYA)
        img_template_probability_match = cv2.matchTemplate(first_image_hist, second_image_hist, cv2.TM_CCOEFF_NORMED)[0][0]
        img_template_diff = 1 - img_template_probability_match

        # taking only 10% of histogram diff, since it's less accurate than template method
        commutative_image_diff = (img_hist_diff / 10) + img_template_diff
        return commutative_image_diff


    if __name__ == '__main__':
        compare_image = CompareImage('image1/path', 'image2/path')
        image_difference = compare_image.compare_image()
        print image_difference
导入cv2
类比较图像(对象):
定义初始路径(自、映像1路径、映像2路径):
self.minimum_可交换_image_diff=1
self.image\u 1\u path=image\u 1\u path
self.image\u 2\u path=image\u 2\u path
def比较_图像(自身):
image\u 1=cv2.imread(self.image\u 1\u路径,0)
image_2=cv2.imread(self.image_2_路径,0)
可交换图像差异=自。获取图像差异(图像1,图像2)
如果可交换映像差异
您好,我只是按照您的步骤操作,但我发现规格化部分无法获得正确的结果。最终结果远远大于1.0。有什么想法吗?请参见上的答案,以比较只有几个不同图像的类似图像(例如,一个新对象移动到其他相同的视图中),您还可以使用
absdiff
阈值化结果生成一个遮罩,允许您突出显示场景之间变化的区域。我不太懂python。但什么是“可交换的图像差异”类型?cv.垫或双层。如果是cv.Mat,比较“可交换图像差异In[2]: np.sum(picture2_norm*picture1_norm) Out[2]: 0.75389941124629822
import cv2

class CompareImage(object):

    def __init__(self, image_1_path, image_2_path):
        self.minimum_commutative_image_diff = 1
        self.image_1_path = image_1_path
        self.image_2_path = image_2_path

    def compare_image(self):
        image_1 = cv2.imread(self.image_1_path, 0)
        image_2 = cv2.imread(self.image_2_path, 0)
        commutative_image_diff = self.get_image_difference(image_1, image_2)

        if commutative_image_diff < self.minimum_commutative_image_diff:
            print "Matched"
            return commutative_image_diff
        return 10000 //random failure value

    @staticmethod
    def get_image_difference(image_1, image_2):
        first_image_hist = cv2.calcHist([image_1], [0], None, [256], [0, 256])
        second_image_hist = cv2.calcHist([image_2], [0], None, [256], [0, 256])

        img_hist_diff = cv2.compareHist(first_image_hist, second_image_hist, cv2.HISTCMP_BHATTACHARYYA)
        img_template_probability_match = cv2.matchTemplate(first_image_hist, second_image_hist, cv2.TM_CCOEFF_NORMED)[0][0]
        img_template_diff = 1 - img_template_probability_match

        # taking only 10% of histogram diff, since it's less accurate than template method
        commutative_image_diff = (img_hist_diff / 10) + img_template_diff
        return commutative_image_diff


    if __name__ == '__main__':
        compare_image = CompareImage('image1/path', 'image2/path')
        image_difference = compare_image.compare_image()
        print image_difference