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...
  • 相关阅读:
    MySQL "show users"
    MySQL
    A MySQL 'create table' syntax example
    MySQL backup
    MySQL show status
    Tomcat, pathinfo, and servlets
    Servlet forward example
    Servlet redirect example
    Java servlet example
    How to forward from one JSP to another JSP
  • 原文地址:https://www.cnblogs.com/channy14/p/9138528.html
Copyright © 2011-2022 走看看