Python实现对比两张图片并标记差异

 更新时间:2025年04月28日 09:17:40   作者:大霸王龙  
这篇文章主要为大家详细介绍了使用Python对比两张CAD图并标记差异的解决方案,文中的示例代码简洁易懂,具有一定的借鉴价值,有需要的小伙伴可以参考一下

以下是使用Python对比两张CAD图并标记差异的解决方案,结合图像处理和CAD结构分析:

一、环境准备与库选择

图像处理库:使用OpenCV进行图像差异检测、颜色空间转换和轮廓分析。

CAD解析库:若为DXF格式,使用ezdxf解析实体信息(如块、线条、圆等)。

几何计算库:scikit-image用于结构相似性(SSIM)和仿射变换匹配。

import cv2
import ezdxf
from skimage.metrics import structural_similarity

二、关键步骤实现

1. 加载与预处理

图像格式:使用OpenCV读取图片并转换为灰度图,进行高斯模糊去噪。

left_img = cv2.imread("left.png")
right_img = cv2.imread("right.png")
gray_left = cv2.cvtColor(left_img, cv2.COLOR_BGR2GRAY)
gray_right = cv2.cvtColor(right_img, cv2.COLOR_BGR2GRAY)

DXF格式:通过ezdxf提取实体坐标和属性。

doc_left = ezdxf.readfile("left.dxf")
doc_right = ezdxf.readfile("right.dxf")

2. 红框区域检测

颜色阈值法:在HSV空间识别红色区域,提取红框坐标。

hsv = cv2.cvtColor(right_img, cv2.COLOR_BGR2HSV)
lower_red = np.array([0, 50, 50])
upper_red = np.array([10, 255, 255])
mask = cv2.inRange(hsv, lower_red, upper_red)
contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

3. 差异检测

图像差异法:通过像素对比标记新增部件。

diff = cv2.absdiff(gray_left, gray_right)
_, thresh = cv2.threshold(diff, 30, 255, cv2.THRESH_BINARY)

实体对比法(DXF):遍历右图实体,检查是否存在于左图。

right_entities = {entity.dxf.handle for entity in doc_right.modelspace()}
left_entities = {entity.dxf.handle for entity in doc_left.modelspace()}
new_entities = right_entities - left_entities

4. 旋转匹配检测

仿射变换匹配:对左图零件进行旋转,与右图红框区域计算相似度。

(height, width) = right_roi.shape[:2]
center = (width // 2, height // 2)
rotation_matrix = cv2.getRotationMatrix2D(center, angle=90, scale=1)
rotated_left = cv2.warpAffine(left_roi, rotation_matrix, (width, height))
ssim_score = structural_similarity(rotated_left, right_roi)
if ssim_score > 0.8:  # 阈值可调整
    cv2.rectangle(right_img, (x, y), (x+w, y+h), (0, 255, 0), 2)  # 标记为旋转后的零件

5. 结果标记

在右图中用绿色框标记旋转后的零件,用红色框标记完全新增的零件。

for (x, y, w, h) in new_contours:
    cv2.rectangle(right_img, (x, y), (x+w, y+h), (0, 0, 255), 2)

三、优化与注意事项

阈值调整:根据实际图像质量调整SSIM相似度阈值(如0.7-0.9)。

多角度旋转匹配:若旋转角度未知,可遍历0°-360°以寻找最大匹配值。

矢量数据优先:若为DXF文件,直接对比实体属性更高效。

示例输出效果

红色框:右图新增的独立零部件。

绿色框:左图零件经旋转后存在于右图的区域。

通过结合图像差异和几何变换匹配,可精准识别新增与变换的零件。若需完整代码或参数调优细节,可进一步提供CAD样本文件。

四、方法补充

1.基于openCV和python的skimage查找并标记两张图片的不同

代码实现

导入图像处理库

from skimage.metrics import structural_similarity as compare_ssim
import imutils
import cv2
import numpy as np

读取图片

image = "C:/Users/ts/Desktop/img/screenshot.png"
imageCompare = "C:/Users/ts/Desktop/img/screenshot1.png"
image= cv2.imdecode(np.fromfile(image, dtype=np.uint8), -1)
image_compare= cv2.imdecode(np.fromfile(image_compare, dtype=np.uint8), -1)

调整对比的两张图片尺寸一样

h1, w1,c1 = image.shape
h2, w2,c2= imageCompare.shape
image_compare = cv2.resize(image_compare ,dsize=(w1,h1))

图片转灰度图

gray_image= cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
gray_image_ompare = cv2.cvtColor(image_compare ,cv2.COLOR_BGR2GRAY)

使用structural_similarity对比获取图像相似度和不同

(score,diff) = compare_ssim(gray_image,gray_image_ompare ,full = True)
diff = (diff *255).astype("uint8")
retval,thresh = cv2.threshold(diff,200,255,cv2.THRESH_BINARY_INV)
 #参数thresh:阈值,用于确定像素是否应该被视为前景或背景,调测下来200比较合适
cnts=cv2.findContours(thresh.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[1] if imutils.is_cv3() else cnts[0]
loacation_list =[]
for c in cnts:
      (x,y,w,h) = cv2.boundingRect(c)  
      loacation_list.append((x,y,x+w,y+h))

圈出不同并标记序号

for index,item in enumerate(loacation_list):
    #圈出不同    
    x,y,x1,y1 = item
    cv2.rectangle(imageA,(x,y),(x1,y1),(0,0,255),2)
    cv2.rectangle(imageB,(x,y),(x1,y1),(0,0,255),2)
    #不同处添加序号
    imageA = cv2.putText(imageA,str(index+1), (x,y+24), cv2.FONT_HERSHEY_DUPLEX, 1, (0, 0, 255))

2.使用OpenCV比较两张图片的相似度

实现代码

import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfFloat;
import org.opencv.core.MatOfInt;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

import java.util.Arrays;

public class ImageSimilarity {

   static {
        // 设置库路径
        System.setProperty("java.library.path", "D:\\anzhuang\\opencv\\opencv\\build\\java\\x64");
        // 加载 OpenCV 库
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    }

    /**
     * 比较两张图片的相似度
     * @param imgPath1 图片1的路径
     * @param imgPath2 图片2的路径
     * @return 相似度值(范围:0到1,1表示完全相同)
     */
    public static double compareImages(String imgPath1, String imgPath2) {
        // 加载图片
        Mat img1 = Imgcodecs.imread(imgPath1);
        Mat img2 = Imgcodecs.imread(imgPath2);

        // 转换为灰度图
        Mat grayImg1 = new Mat();
        Mat grayImg2 = new Mat();
        Imgproc.cvtColor(img1, grayImg1, Imgproc.COLOR_BGR2GRAY);
        Imgproc.cvtColor(img2, grayImg2, Imgproc.COLOR_BGR2GRAY);

        // 计算直方图
        Mat hist1 = new Mat();
        Mat hist2 = new Mat();
        MatOfInt histSize = new MatOfInt(256); // 直方图大小
        MatOfFloat ranges = new MatOfFloat(0f, 256f); // 像素值范围
        Imgproc.calcHist(Arrays.asList(grayImg1), new MatOfInt(0), new Mat(), hist1, histSize, ranges);
        Imgproc.calcHist(Arrays.asList(grayImg2), new MatOfInt(0), new Mat(), hist2, histSize, ranges);

        // 比较直方图
        return Imgproc.compareHist(hist1, hist2, Imgproc.CV_COMP_CORREL);
    }

    public static void main(String[] args) {
        String imgPath1 = "path/to/image1.jpg";
        String imgPath2 = "path/to/image2.jpg";

        double similarity = compareImages(imgPath1, imgPath2);
        System.out.println("图片相似度: " + similarity);
    }
}

到此这篇关于Python实现对比两张图片并标记差异的文章就介绍到这了,更多相关Python图片对比内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Python设计模式结构型代理模式

    Python设计模式结构型代理模式

    这篇文章主要介绍了Python设计模式结构型代理模式,代理模式即Proxy Pattern,为其他对象提供一种代理以控制对这个对象的访问,下文内容详细介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-02-02
  • 使用Python操作ArangoDB的方法步骤

    使用Python操作ArangoDB的方法步骤

    这篇文章主要介绍了使用Python操作ArangoDB的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-02-02
  • Python实现将通信达.day文件读取为DataFrame

    Python实现将通信达.day文件读取为DataFrame

    今天小编就为大家分享一篇Python实现将通信达.day文件读取为DataFrame,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-12-12
  • Python实现制作透明背景的电子印章

    Python实现制作透明背景的电子印章

    这篇文章主要为大家详细介绍了如何利用Python语言实现制作透明背景的电子印章,文中的示例代码讲解详细,感兴趣的小伙伴可以尝试一下
    2022-09-09
  • Python实现破解猜数游戏算法示例

    Python实现破解猜数游戏算法示例

    这篇文章主要介绍了Python实现破解猜数游戏算法,简单描述了猜数游戏的原理,并结合具体实例形式分析了Python破解猜数游戏的相关实现技巧,需要的朋友可以参考下
    2017-09-09
  • Python 中拼音库 PyPinyin 用法详解

    Python 中拼音库 PyPinyin 用法详解

    很多朋友问小编怎样把一批中文文件转拼音命名呢?下面就让我们来了解 Python 的一个库 PyPinyin 吧,感兴趣的朋友跟随小编一起看看吧
    2021-05-05
  • Python的网络编程库Gevent的安装及使用技巧

    Python的网络编程库Gevent的安装及使用技巧

    Gevent库的奥义在于并发式的高性能网络程序设计支持,这里我们将来讲解Python的网络编程库Gevent的安装及使用技巧,来看一下Gevent支持的多进程程序编写:
    2016-06-06
  • selenium 多窗口切换的实现(windows)

    selenium 多窗口切换的实现(windows)

    这篇文章主要介绍了selenium 多窗口切换的实现(windows),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-01-01
  • python图的深度优先和广度优先算法实例分析

    python图的深度优先和广度优先算法实例分析

    这篇文章主要介绍了python图的深度优先和广度优先算法,结合实例形式分析了图的深度优先算法与广度优先算法相关概念、原理、实现技巧与操作注意事项,需要的朋友可以参考下
    2019-10-10
  • Django中自定义admin Xadmin的实现代码

    Django中自定义admin Xadmin的实现代码

    这篇文章主要介绍了Django中自定义admin---Xadmin的实现代码,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值 ,需要的朋友可以参考下
    2019-08-08

最新评论