zoukankan      html  css  js  c++  java
  • 自动化:图像相似度比较,并标记不一样的地方

    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')
    每天努力一点,每天学习一点。 Keep Moving...
  • 相关阅读:
    CSS预编译:less入门
    JavaScript学习(五):函数表达式
    关于JavaScript new 的一些疑问
    JavaScript学习(四):面对对象的程序设计
    JavaScript学习(三):引用类型
    JavaScript学习(二):变量、作用域和内存问题
    JavaScript学习(一):基本概念
    匿名函数的this指向为什么是window?
    阿里云ECS在CentOS 6.8中使用Nginx提示:nginx: [emerg] socket() [::]:80 failed (97: Address family not supported by protocol)的解决方法
    Centos释放缓存
  • 原文地址:https://www.cnblogs.com/channy14/p/9138528.html
Copyright © 2011-2022 走看看