1、大家来找茬https://testerhome.com/topics/11528
2、pip install numpy Matplotlib
pip install opencv-python
3、https://blog.csdn.net/ibaymin/article/details/74936742
4、网络代码,实现标记图片不一样处【https://blog.csdn.net/ibaymin/article/details/74936742】
确保电脑上已安装 openCV 和 Python 两个工具以及scikit-image和imutils两个库
# -*- coding: utf-8 -*- from skimage.measure import compare_ssim import imutils import cv2 #加载两张图片并将他们转换为灰度 imageA = cv2.imread(r"TEST1/70.png") imageB = cv2.imread(r"TEST1/71.png") grayA = cv2.cvtColor(imageA, cv2.COLOR_BGR2GRAY) grayB = cv2.cvtColor(imageB, cv2.COLOR_BGR2GRAY) #计算两个灰度图像之间的结构相似度指数 (score,diff) = compare_ssim(grayA,grayB,full = True) diff = (diff *255).astype("uint8") print("SSIM:{}".format(score)) #找到不同点的轮廓以致于我们可以在被标识为“不同”的区域周围放置矩形 thresh = cv2.threshold(diff,0,255,cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1] cnts = cv2.findContours(thresh.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) cnts = cnts[0] if imutils.is_cv2() else cnts[1] #找到一系列区域,在区域周围放置矩形 for c in cnts: (x,y,w,h) = cv2.boundingRect(c) cv2.rectangle(imageA,(x,y),(x+w,y+h),(0,0,255),2) cv2.rectangle(imageB,(x,y),(x+w,y+h),(0,0,255),2) #用cv2.imshow 展现最终对比之后的图片, cv2.imwrite 保存最终的结果图片 cv2.imshow("Modified",imageB) cv2.imwrite("TEST1/72.png",imageB) cv2.waitKey(0)
上述代码运行时出错:
grayA = cv2.cvtColor(imageA, cv2.COLOR_BGR2GRAY)
cv2.error: OpenCV(3.4.1) C:projectsopencv-pythonopencvmodulesimgprocsrccolor.cpp:11147: error: (-215) scn == 3 || scn == 4 in function cv::cvtColor
原因:输入的图片不存在,名称/格式输入错误
标记效果如:
5、输出相似度值,代码二片段
# -*- coding: utf-8 -*- from PIL import Image def make_regalur_image(img, size=(256, 256)): return img.resize(size).convert('RGB') # 几何转变,全部转化为256*256像素大小 def split_image(img, part_size=(64, 64)): w, h = img.size pw, ph = part_size assert w % pw == h % ph == 0 return [img.crop((i, j, i + pw, j + ph)).copy() for i in xrange(0, w, pw) for j in xrange(0, h, ph)] # region = img.crop(box) # 将img表示的图片对象拷贝到region中,这个region可以用来后续的操作(region其实就是一个 # image对象,box是个四元组(上下左右)) def hist_similar(lh, rh): assert len(lh) == len(rh) return sum(1 - (0 if l == r else float(abs(l - r)) / max(l, r)) for l, r in zip(lh, rh)) / len(lh) # 好像是根据图片的左右间隔来计算某个长度,zip是可以接受多个x,y,z数组值统一输出的输出语句 def calc_similar(li, ri): # return hist_similar(li.histogram(), ri.histogram()) return sum( hist_similar(l.histogram(), r.histogram()) for l, r in zip(split_image(li), split_image(ri))) / 16.0 # 256>64 # 其中histogram()对数组x(数组是随机取样得到的)进行直方图统计,它将数组x的取值范围分为100个区间, # 并统计x中的每个值落入各个区间中的次数。histogram()返回两个数组p和t2, # 其中p表示各个区间的取样值出现的频数,t2表示区间。 # 大概是计算一个像素点有多少颜色分布的 # 把split_image处理的东西zip一下,进行histogram,然后得到这个值 def calc_similar_by_path(lf, rf): li, ri = make_regalur_image(Image.open(lf)), make_regalur_image(Image.open(rf)) return calc_similar(li, ri) def make_doc_data(lf, rf): li, ri = make_regalur_image(Image.open(lf)), make_regalur_image(Image.open(rf)) li.save(lf + '_regalur.png') # 转换图片格式:img.save('file.jpg'),保存临时的 ri.save(rf + '_regalur.png') # img对象到硬盘 fd = open('stat.csv', 'w') # stat模块是做随机变量统计的,stat用来计算随机变量的期望值和方差 # 这句是关键啊,把histogram的结果进行map处理 fd.write(' '.join(l + ',' + r for l, r in zip(map(str, li.histogram()), map(str, ri.histogram())))) # print >>fd, ' ' # fd.write(','.join(map(str, ri.histogram()))) fd.close() import ImageDraw li = li.convert('RGB') # 与save对象,这是转换格式 draw = ImageDraw.Draw(li) for i in xrange(0, 256, 64): draw.line((0, i, 256, i), fill='#ff0000') draw.line((i, 0, i, 256), fill='#ff0000') # 从始至终划线!!!!!!!!!!!!!!!通过把每一列刷成红色,来进行颜色的随机分布划分 # 用法:pygame.draw.line(Surface, color, start_pos, end_pos, width=1) li.save(lf + '_lines.png') if __name__ == '__main__': path = r'TEST%d/%d.png' for i in xrange(1, 2): print 'test_case_%d: %.3f%%' % (i, calc_similar_by_path('TEST%d/%d.png' % (i, 1), 'TEST%d/%d.png' % (i, 1)) * 100) # make_doc_data('test/TEST4/1.JPG', 'test/TEST4/2.JPG')