基于业务需求的图片对比

  1 """
  2 1.先将文件夹内的图片进行遍历,获取所有文件名称,放到列表中。只需要获取一个文件夹内的名称即可,因为新旧文件夹内图片的名称都是一样的,只是截图时候的版本不同
  3 2.通过ssim将新旧文件夹内的图片进行对比,得到相似度评分,并将差异处进行框选
  4 3.将旧图、新图、对比图、对比结果 放置在excel表中
  5 4.将excel表和对比报告通过email发送给指定人
  6 """
  7 
  8 import os
  9 import cv2
 10 import imutils
 11 import xlsxwriter
 12 import numpy as np
 13 from skimage.metrics import structural_similarity as ssim
 14 
 15 """找到图片的坐标"""
 16 def find_all_pic(new_pic_location, old_pic_location):
 17     new_pic_location_list = []
 18     old_pic_location_list = []
 19     for root, dirs, files in os.walk(new_pic_location):
 20         for file in files:
 21             new_pic_location_list.append(file)
 22         # print(new_pic_location_list)
 23     for root, dirs, files in os.walk(old_pic_location):
 24         for file in files:
 25             old_pic_location_list.append(file)
 26         # print(old_pic_location_list)
 27     if new_pic_location_list == old_pic_location_list:
 28         """如果说新截图的图片名和旧截图的名一样的话,说明坐标位置是相同的,随便取一组就好了"""
 29         pic_location_list = new_pic_location_list
 30         # print(pic_location_list)
 31         return pic_location_list
 32     else:
 33         print('=-=-=-=-=-=')
 34 
 35 def ssim_check(new_pic, old_pic):
 36     new_pic  = cv2.imread(new_pic)
 37     old_pic = cv2.imread(old_pic)
 38 
 39     "转灰度图"
 40     new_pic_gray = cv2.cvtColor(new_pic, cv2.COLOR_BGR2GRAY)
 41     old_pic_gray = cv2.cvtColor(old_pic, cv2.COLOR_BGR2GRAY)
 42 
 43     (score, diff) = ssim(new_pic_gray, old_pic_gray,win_size = 111, gaussian_weights = True, full = True)
 44     print("图片相似度: {:.4f}%".format(score * 100))
 45 
 46 
 47     return  score, diff, new_pic, old_pic
 48 
 49 def find_contours(diff, before, after):
 50 
 51     """diff 图像包含两个图像之间的实际图像差异,并表示为 0到 1 范围内的浮点数据类型
 52     将数组转换为 [0,255] 范围内的整型8位无符号"""
 53     diff = (diff * 255).astype("uint8")
 54     # print(diff)
 55     # cv2.imshow('two img different',diff)
 56 
 57     # diff_box = cv2.merge([diff, diff, diff])
 58     '''使用numpy stack()函数将数组进行2维堆叠 结果和cv2.merge算法相同,在大型矩阵中使用numpy速度更快'''
 59     diff_box = np.stack((diff, diff, diff), axis = 2)  # 灰度图层面对比
 60     # print(diff_box)
 61 
 62 
 63     '''二值化并对差异图像进行阈值设置阈值,查找轮廓以获得两个图像的不同区域  使用cv2.THRESH_OTSU方法时注意阈值要设定为0 '''
 64     thresh = cv2.threshold(diff, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]  # [0]返回的是阈值  [1]是返回灰度图二值化后的结果
 65     # print('这是thresh{}'.format(thresh))
 66     # cv2.imshow('thresh', thresh)
 67 
 68     '''轮廓提取'''
 69     contours = cv2.findContours(thresh.copy(),
 70                                 cv2.RETR_EXTERNAL,  # CV.RETR_EXTERNAL仅检索外轮廓。并为所有轮廓设置层级结构
 71                                 cv2.CHAIN_APPROX_SIMPLE)  # CV.CHAIN_APPROX_SIMPLE -压缩水平、垂直、对角线方向的元素,仅留该方向的终点坐标,例如一个矩形轮廓只需4个点来保存轮廓信息
 72     # print('轮廓坐标{}'.format(contours))
 73     # print(len(contours))
 74     # print('=============')
 75     contours = imutils.grab_contours(contours)
 76 
 77     for c in contours:
 78         area = cv2.contourArea(c)
 79         if area > 500:  # 异常点绿框阈值控制
 80             x, y, w, h = cv2.boundingRect(c)
 81             # cv2.rectangle(before, (x, y), (x + w, y + h), (0, 255, 0), 2)
 82             cv2.rectangle(after, (x, y), (x + w, y + h), (0, 255, 0), 2)
 83             # cv2.rectangle(diff_box, (x, y), (x + w, y + h), (0, 255, 0), 2)
 84 
 85     '''原始图片对比结果'''
 86     # cv2.imshow('before', before)
 87 
 88     '''更改后图片对比结果'''
 89     # cv2.imshow('after', after)
 90 
 91     '''灰度图片'''
 92     # cv2.imshow('diff', diff)
 93     # cv2.imshow('diff_box', diff_box)
 94 
 95     cv2.waitKey()
 96     cv2.destroyAllWindows()
 97     return after
 98 
 99 def put_pic_into_contrast(pic_name, after):
100     if not os.path.exists("contrast_jpg"):
101         os.makedirs(r'D:\opencvtest\contrast_jpg')
102     cv2.imwrite(r'D:\opencvtest\contrast_jpg\{}'.format(pic_name), after)
103 
104 def excel_workbook(pic_name, score, worksheet, row, col):
105     score *= 100
106     worksheet.write(row, col, pic_name)
107     worksheet.insert_image(row, col + 1, r'D:\opencvtest\old_jpg\{}'.format(pic_name),
108                                {'x_scale': 1, 'y_scale': 1})
109     worksheet.insert_image(row, col + 2, r'D:\opencvtest\contrast_jpg\{}'.format(pic_name),
110                                {'x_scale': 0.81, 'y_scale': 0.81})
111     worksheet.write(row, col + 3, str(round(score, 3))+'%')
112     print(row)
113 
114 def main(new_jpg_location, old_jpg_location):
115     workbook = xlsxwriter.Workbook('version_contrast.xlsx')
116     worksheet = workbook.add_worksheet("版本截图对比")
117     worksheet.set_column('A:A', 20)
118     worksheet.set_column('B:C', 40)
119     worksheet.set_column('D:D', 10)
120     worksheet.write(0, 0, '图片名称')
121     worksheet.write(0, 1, '旧版本截图')
122     worksheet.write(0, 2, '新版本截图')
123     worksheet.write(0, 3, '图像相似度')
124     row, col = 1, 0
125     for pic_name in find_all_pic(new_jpg_location, old_jpg_location):
126         # print(pic_name)
127         pic_old = r'D:\opencvtest\old_jpg\{}'.format(pic_name)
128         pic_new = r'D:\opencvtest\new_jpg\{}'.format(pic_name)
129 
130         score, diff, new_pic, old_pic = ssim_check(pic_new, pic_old)
131 
132         after = find_contours(diff, before = old_pic, after = new_pic)
133 
134         put_pic_into_contrast(pic_name, after = after)
135 
136         excel_workbook(pic_name, score, worksheet, row, col)
137         row += 1
138 
139 
140     workbook.close()
141 
142 
143 if __name__ == '__main__':
144     new_jpg_location = r'D:\opencvtest\new_jpg'
145     old_jpg_location = r'D:\opencvtest\old_jpg'
146     main(new_jpg_location, old_jpg_location)

 

posted @ 2023-08-20 21:08  razryang  阅读(19)  评论(0编辑  收藏  举报