OpenCV检查图像是否相似

来源:互联网 发布:淘宝海报尺寸 编辑:程序博客网 时间:2024/05/29 15:44

参考:
https://stackoverflow.com/questions/11541154/checking-images-for-similarity-with-opencv


1、比较直方图

最简单和最快速的方法之一。 建议几十年前作为一种手段来找到图片相似之处。 这个想法是,一个森林将有很多的绿色,人脸很多粉红色,或其他颜色。 所以,如果你将两幅图片的森林进行比较,你会得到直方图之间的一些相似之处,因为两者都有很多的绿色。

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

OpenCV方法:compareHist()


import cv2import numpy as npimport matplotlib.pyplot as pltimg=cv2.imread("messi5.jpg")# Comparing histogramsH1=cv2.calcHist([img],[1],None,[256],[0,256]) # 统计第2个波段H1=cv2.normalize(H1,H1,0,1,cv2.NORM_MINMAX,-1) # 归一化H2=cv2.calcHist([img],[2],None,[256],[0,256])H2=cv2.normalize(H2,H2,0,1,cv2.NORM_MINMAX,-1)Similarity=cv2.compareHist(H1,H2,0) # 比较直方图print(Similarity) # 0.55plt.subplot(2,1,1);plt.plot(H1)plt.subplot(2,1,2);plt.plot(H2)plt.show()

2、模板匹配

这里的一个很好的例子是matchTemplate找到好匹配。 它将搜索图像与正在搜索的图像进行卷积。 通常用于查找更大的图像部分。

缺点:只有相同的图像,相同的尺寸和方向才能返回良好的效果。
OpenCV方法:matchTemplate()


import cv2import numpy as npfrom matplotlib import pyplot as pltimg = cv2.imread('messi5.jpg',1)img2 = img.copy()template = cv2.imread('messi_face.jpg',1)template=cv2.resize(template,None,fx=1.5,fy=2)h, w,c = template.shape# All the 6 methods for comparison in a listmethods = ['cv2.TM_CCOEFF', 'cv2.TM_CCOEFF_NORMED', 'cv2.TM_CCORR',            'cv2.TM_CCORR_NORMED', 'cv2.TM_SQDIFF', 'cv2.TM_SQDIFF_NORMED']# Apply template Matchingres = cv2.matchTemplate(img,template,cv2.TM_CCOEFF)min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)top_left = max_locbottom_right = (top_left[0] + h, top_left[1] + w)cv2.rectangle(img,top_left, bottom_right, 255, 2)plt.subplot(121),plt.imshow(res,cmap = 'gray')plt.title('Matching Result'), plt.xticks([]), plt.yticks([])plt.subplot(122),plt.imshow(img,cmap = 'gray')plt.title('Detected Point'), plt.xticks([]), plt.yticks([])plt.suptitle("TM_CCOEFF")plt.show()

附加

参考:https://stackoverflow.com/questions/8218997/how-to-detect-the-sun-from-the-space-sky-in-opencv/8221251#8221251

霍夫圆变换找太阳

# -*- coding: UTF-8 -*-import cv2import numpy as npimage=cv2.imread("b2gUH.png")# Color to Graygray=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)# color threshold_,gray=cv2.threshold(gray,150,255,cv2.THRESH_BINARY)# Morphologic open for 2 timesdst=cv2.morphologyEx(gray,cv2.MORPH_OPEN,None,iterations=2)# 使用霍夫圆变换circles = cv2.HoughCircles(dst,cv2.HOUGH_GRADIENT,12,dst.shape[1]/2,                            param1=50,param2=30,minRadius=0,maxRadius=0)circles = np.uint16(np.around(circles))for i in circles[0,:]:    # draw the outer circle    cv2.circle(image,(i[0],i[1]),i[2],(0,255,0),2)    # draw the center of the circle    cv2.circle(image,(i[0],i[1]),2,(0,0,255),3)cv2.imshow("dst",image)cv2.waitKey(0)cv2.destroyAllWindows()

模板匹配找太阳

# -*- coding: UTF-8 -*-import cv2import numpy as np# Load image and templateimg=cv2.imread("b2gUH.png")templ =cv2.imread("sun.png")# Create the result matrixresult_cols = img.shape[1] - templ.shape[1] + 1;result_rows = img.shape[0] - templ.shape[0] + 1;result=np.zeros([result_rows,result_cols],np.float32)# Do the Matching and Normalizeresult=cv2.matchTemplate(img,templ,cv2.TM_CCOEFF)cv2.normalize(result,result,0,1,cv2.NORM_MINMAX,-1)min_val, max_val, min_loc, max_loc=cv2.minMaxLoc(result)top_left = max_locbottom_right = (top_left[0] + templ.shape[0], top_left[1] + templ.shape[1])cv2.rectangle(img,top_left,bottom_right,(0, 255, 0),2,cv2.LINE_AA)cv2.rectangle(result,top_left,bottom_right,(0, 255, 0),2,cv2.LINE_AA)cv2.imshow("img",img)cv2.imshow("result",result)cv2.waitKey(0)cv2.destroyAllWindows()

3、特征匹配

被认为是最有效的图像搜索方法之一。 从图像中提取许多特征,以确保即使旋转/缩放/倾斜也能再次识别相同的特征。 以这种方式提取的特征可以与其他图像特征集匹配。 另一个在第一个图像中具有高比例特征的图像很可能描绘了同一个对象/场景。 它可以用来查找图片之间拍摄角度的相对差异,或重叠的数量。

这里有一些OpenCV的教程/示例,还有一个很好的视频。 整个OpenCV模块(features2d)专门用于它。
缺点:可能会很慢。 这并不完美。
http://answers.opencv.org/question/877/how-to-match-2-hog-for-object-detection/#882

4、方法总结

import cv2class CompareImage(object):    def __init__(self, image_1_path, image_2_path):        self.minimum_commutative_image_diff = 0.25        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)        img_hist_diff, img_template_diff, commutative_image_diff = self.get_image_difference(image_1, image_2)        if img_hist_diff<0.3 and img_template_diff<0.3:            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 = 1-cv2.compareHist(first_image_hist, second_image_hist,0)        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 [img_hist_diff,img_template_diff,commutative_image_diff]if __name__ == '__main__':    compare_image = CompareImage('E:/07/L15-3345E-2311N.tif', 'E:/08/L15-3345E-2311N.tif')    image_difference = compare_image.compare_image()    print(image_difference)
阅读全文
0 0
原创粉丝点击