opencv实现寻找两张图片的不同

from skimage.measure import compare_ssim
import argparse
import imutils
import cv2
import os
import subprocess
import sys


class DiffPic:
    def __init__(self, picA, picB):
        '''
        :param picA: 清洗前数据图片集
        :param picB: 清洗后数据图片集
        '''
        self.aPath = picA
        self.bPath = picB

    def diff(self):
        aCount = adjustPath(self.aPath)
        bCount = adjustPath(self.bPath)
        if aCount != bCount:
            print("两个图片集中的图片数量不相等,请检查是否遗漏!")
        else:
            pA = subprocess.Popen("ls " + self.aPath, shell=True,
                                  stdout=subprocess.PIPE)
            pA_str = pA.stdout.read().decode('utf-8')

            pB = subprocess.Popen('ls ' + self.bPath, shell=True,
                                  stdout=subprocess.PIPE)
            pB_str = pB.stdout.read().decode('utf-8')
            aList = pA_str.split('\n')
            bList = pB_str.split('\n')
            # print(aList)
            for p in aList[:-1]:
                # print(p)
                if p in bList:
                    imageA = cv2.imread(self.aPath + '/' + p)
                    imageB = cv2.imread(self.bPath + '/' + p)
                    # 置灰
                    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[1] if imutils.is_cv3() else cnts[0]
                    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 = imutils.grab_contours(cnts)
                    # cnts = cnts[1] if imutils.is_cv3() else cnts[0]
                    # 找到一系列区域,在区域周围放置矩形
                    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("Original", imageA)
                    cv2.imshow("Modified", imageB)
                    cv2.imshow("Diff", diff)
                    cv2.imshow("Thresh", thresh)
                    result_png = p.split('.')[0] + "_result.png"
                    print(result_png)
                    cv2.imwrite("/Users/tal/picDiff/diff_result/" + result_png, imageA)
                    #cv2.waitKey(0)
                    print("图片比较后不同之处会在" + result_png + "图片上进行展示,请查看")

                else:
                    raise Exception(p + "该图片没有可比较的图片存在")


def adjustPath(path):
    '''
    :param path: 路径,默认该路径只存放图片
    :return: 路径下存在的图片数量
    '''
    if os.path.exists(path):
        pics = subprocess.Popen('ls ' + path + ' | wc -l', shell=True, stdout=subprocess.PIPE)
        # print(pics.stdout.read().decode('utf-8'))
        count = int(pics.stdout.read().decode('utf-8'))
        # print(count)
        if count > 0:
            print(path + "下存有" + str(count) + "张图片。")
            return count
        else:
            raise Exception("no pictures")
    else:
        raise Exception("this dir do not exists")


if __name__ == "__main__":
    a = "/Users/tal/picDiff/B"
    b = "/Users/tal/picDiff/A"
    d = DiffPic(a, b)
    d.diff()

用以批量比较,两个文件的图片命名必须一样

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值