将两张图片的不同标记出来

  1. 差异过于细微,阈值设置不当:您的差异可能是颜色或位置的微小变化,当前的阈值和处理方式可能不足以检测到这些细微差异。

  2. 图像配准不够精确:由于两张图片内容高度相似,特征点匹配可能存在误差,导致图像对齐不准确,影响差异检测。

  3. 灰度处理损失了颜色信息:如果差异体现在颜色上,转换为灰度图后,颜色变化可能被忽略。

  4. 形态学操作和面积过滤参数不合适:形态学处理和面积过滤的参数可能导致小的差异区域被过滤掉。


解决方案

1. 降低阈值,提高敏感度
  • 降低阈值:在阈值处理步骤中,将阈值从30降低到更小的值,如510,使得对细微差异更加敏感。

    _, thresh = cv2.threshold(diff, 5, 255, cv2.THRESH_BINARY)
    
2. 使用彩色图像进行差异检测
  • 直接计算彩色图像的差异:由于差异可能体现在颜色上,使用彩色图像的差异计算会更有效。

    # 计算彩色图像的差异
    diff_color = cv2.absdiff(img1_aligned, img2_color)
    # 转换为灰度图
    diff_gray = cv2.cvtColor(diff_color, cv2.COLOR_BGR2GRAY)
    # 阈值处理
    _, thresh = cv2.threshold(diff_gray, 5, 255, cv2.THRESH_BINARY)
    
3. 使用结构相似性(SSIM)
  • SSIM对细微差异更敏感:使用SSIM可以检测到亮度、对比度和结构上的微小变化。

    from skimage.metrics import structural_similarity as ssim# 计算SSIM
    score, diff = ssim(img1_aligned_gray, img2_gray, full=True)
    diff = (diff * 255).astype("uint8")
    diff = cv2.bitwise_not(diff)  # 反转图像
    # 阈值处理
    _, thresh = cv2.threshold(diff, 5, 255, cv2.THRESH_BINARY)
    

    注意:需要安装scikit-image库:

    pip install scikit-image
    
4. 调整形态学操作和面积阈值
  • 形态学操作:调整迭代次数和核大小,以保留更多细节。

    kernel = np.ones((3, 3), np.uint8)
    thresh = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=1)
    thresh = cv2.dilate(thresh, kernel, iterations=1)
    
  • 降低面积过滤阈值:减少cv2.contourArea()的阈值,确保小的差异区域也能被标记。

    if area > 5:  # 从50降低到5
    
5. 验证图像配准效果
  • 可视化匹配的特征点:检查特征点匹配是否准确。

    # 绘制前50个匹配点
    img_matches = cv2.drawMatches(img1_color, keypoints1, img2_color, keypoints2, good_matches[:50], None, flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)
    cv2.imshow('Matches', img_matches)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
  • 尝试其他特征检测器:如SIFTSURF,但需注意它们的许可证要求。


修改后的完整代码

import cv2
import numpy as np
from skimage.metrics import structural_similarity as ssim# 读取两张图片
img1_color = cv2.imread('find_difference_image1.png')  # 待配准的原始图像1
img2_color = cv2.imread('find_difference_image2.png')  # 基准的原始图像2# 检查图片是否成功读取
if img1_color is None or img2_color is None:print("错误:无法读取图片。请检查文件路径。")exit()# 将图片转换为灰度图
img1_gray = cv2.cvtColor(img1_color, cv2.COLOR_BGR2GRAY)
img2_gray = cv2.cvtColor(img2_color, cv2.COLOR_BGR2GRAY)# 创建ORB特征检测器
orb = cv2.ORB_create(10000)  # 增加特征点数量# 检测并计算特征点和描述子
keypoints1, descriptors1 = orb.detectAndCompute(img1_gray, None)
keypoints2, descriptors2 = orb.detectAndCompute(img2_gray, None)# 创建BFMatcher对象
bf = cv2.BFMatcher(cv2.NORM_HAMMING)# KNN匹配,k=2
matches = bf.knnMatch(descriptors1, descriptors2, k=2)# 过滤匹配结果,应用比值测试(Lowe's ratio test)
good_matches = []
for m, n in matches:if m.distance < 0.75 * n.distance:good_matches.append(m)# 检查是否有足够的匹配点
if len(good_matches) > 10:# 提取匹配的关键点坐标src_pts = np.float32([keypoints1[m.queryIdx].pt for m in good_matches]).reshape(-1, 1, 2)dst_pts = np.float32([keypoints2[m.trainIdx].pt for m in good_matches]).reshape(-1, 1, 2)# 计算Homography矩阵M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)# 将img1变换到img2的坐标系h, w = img2_gray.shapeimg1_aligned = cv2.warpPerspective(img1_color, M, (w, h))# 使用SSIM计算差异img1_aligned_gray = cv2.cvtColor(img1_aligned, cv2.COLOR_BGR2GRAY)score, diff = ssim(img1_aligned_gray, img2_gray, full=True)diff = (diff * 255).astype("uint8")diff = cv2.bitwise_not(diff)  # 反转图像# 阈值处理_, thresh = cv2.threshold(diff, 5, 255, cv2.THRESH_BINARY)# 使用形态学操作去除噪声和小的差异kernel = np.ones((3, 3), np.uint8)thresh = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=1)thresh = cv2.dilate(thresh, kernel, iterations=1)# 查找差异区域的轮廓contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)# 计算逆变换矩阵M_inv = np.linalg.inv(M)# 在原始的img1_color上绘制差异区域for contour in contours:area = cv2.contourArea(contour)if area > 5:# 将轮廓坐标转换为浮点型contour = contour.astype(np.float32)# 使用逆变换矩阵将坐标变换回img1的坐标系contour_transformed = cv2.perspectiveTransform(contour, M_inv)# 将坐标转换为整数contour_transformed = contour_transformed.astype(np.int32)# 绘制轮廓cv2.drawContours(img1_color, [contour_transformed], -1, (0, 0, 255), 2)# 在原始图像2上绘制差异区域for contour in contours:area = cv2.contourArea(contour)if area > 5:cv2.drawContours(img2_color, [contour], -1, (0, 0, 255), 2)# 调整图片大小以便显示img1_original_resized = cv2.resize(cv2.imread('find_difference_image1.png'), (400, 300))img2_original_resized = cv2.resize(cv2.imread('find_difference_image2.png'), (400, 300))img1_diff_resized = cv2.resize(img1_color, (400, 300))img2_diff_resized = cv2.resize(img2_color, (400, 300))# 将四张图片拼接成一张图片top_row = np.hstack((img1_original_resized, img2_original_resized))bottom_row = np.hstack((img1_diff_resized, img2_diff_resized))combined_image = np.vstack((top_row, bottom_row))# 显示组合后的图片cv2.imshow('Original and Difference Images', combined_image)cv2.waitKey(0)cv2.destroyAllWindows()
else:print("匹配点不足,无法计算Homography矩阵。")exit()

进一步的建议

  • 检查配准质量:使用cv2.drawMatches()可视化特征点匹配,确保配准准确。

  • 调整SSIM参数ssim()函数的参数可以调整,如gaussian_weightssigma等,以提高对细微差异的检测能力。

  • 尝试其他差异检测方法:如计算颜色直方图的差异,或者使用更高级的图像差异算法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/56752.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何区分不同类型的光源

" 声明&#xff1a;此文档中的大部分内容来源于网络&#xff0c;经校对和整理后分享给大家&#xff0c;仅供学习参考使用。" 1、问题背景 之前调试的项目中&#xff0c;客户提供的客观验收标准中要求用到TL83光源&#xff0c;用来测试图像的颜色误差及白平衡。 TL83光…

用Java爬虫API,轻松获取taobao商品SKU信息

在电子商务的世界里&#xff0c;SKU&#xff08;Stock Keeping Unit&#xff0c;库存单位&#xff09;是商品管理的基础。对于商家来说&#xff0c;SKU的详细信息对于库存管理、价格策略制定、市场分析等都有着重要作用。taobao作为中国最大的电子商务平台之一&#xff0c;提供…

windows下载配置CAS单点登录

下载 github下载 云盘瞎子啊 版本对应jdk&#xff0c;根据自身环境下载对应版本的cas。 安装 下载完成之后解压 按照.md文档执行打包命令 build.bat package配置 如果不用https&#xff0c;需要进行以下配置&#xff1a; 修改配置文件application.properties 在最后一行…

【远程监控新体验】OpenObserve结合内网穿透无公网IP远程访问全攻略

文章目录 前言1. 安装Docker2. Docker镜像源添加方法3. 创建并启动OpenObserve容器4. 本地访问测试5. 公网访问本地部署的OpenObserve5.1 内网穿透工具安装5.2 创建公网地址6. 配置固定公网地址前言 本文主要介绍如何在Linux系统使用Docker快速本地化部署OpenObserve云原生可观…

Ajax处理错误信息(处理响应报文)

<!DOCTYPE html> <html><head><meta charset"utf-8" /><title></title></head><body><form action""><div>用户名<input type"text" class"username"></div>…

时间序列神器Prophet教程2-饱和预测

公众号&#xff1a;尤而小屋编辑&#xff1a;Peter作者&#xff1a;Peter 大家好&#xff0c;我是Peter~ 本文是时间序列预测神器Prophet的第二篇&#xff1a;使用Prophet如何实现饱和预测 饱和预测增长-Saturating Forecasts 默认情况下&#xff0c;Prophet 使用线性模型来…

【C++】string类(2)

&#x1f973;个人主页: 起名字真南 &#x1f973;个人专栏:【数据结构初阶】 【C语言】 【C】 目录 引言1 模拟实现string类基本框架2 实现string类中的主要成员函数2.1 Push_Back 函数2.2 reserve 函数2.3 append 函数2.4 c_str 函数2.5 begin ,end 函数2.5 operator 函数2.6…

VScode写Java项目的教程

VScode写Java项目的教程 1.首先必选先安装Java解释器2.安装插件Java Extension Pack3.创建项目创建项目结构选择项目类型 4.测试结果源码内容 今天用一台老式笔记本写代码&#xff0c;IDEA跑不动就准备用VScode突然间就蒙了&#xff0c;怎么创建项目啊&#xff1f;于是就有了这…

自动驾驶系列—加速自动驾驶系统开发:多型号SoC快速适配的最佳实践

&#x1f31f;&#x1f31f; 欢迎来到我的技术小筑&#xff0c;一个专为技术探索者打造的交流空间。在这里&#xff0c;我们不仅分享代码的智慧&#xff0c;还探讨技术的深度与广度。无论您是资深开发者还是技术新手&#xff0c;这里都有一片属于您的天空。让我们在知识的海洋中…

Python编程探索:从基础语法到循环结构实践(下)

文章目录 前言&#x1f377;四、 字符串拼接&#xff1a;连接多个字符串&#x1f378;4.1 使用 操作符进行字符串拼接&#x1f378;4.2 使用 join() 方法进行字符串拼接&#x1f378;4.3 使用 format() 方法进行格式化拼接&#x1f378;4.4 使用 f-string&#xff08;格式化字…

OpenWRT 和 Padavan 路由器配置网络打印机 实现远程打印

本文首发于只抄博客&#xff0c;欢迎点击原文链接了解更多内容。 前言 之前有给大家介绍过 Armbian 安装 CUPS 作为打印服务器&#xff0c;像是 N1 盒子、玩客云&#xff0c;甚至是随身 WiFi 都可以通过 CUPS 来进行打印。但是有些朋友不想专门为打印机添置一个设备&#xff0…

每天5分钟玩转C#/.NET之C#语言详细介绍

C#语言介绍 C# 语言是适用于 .NET 平台&#xff08;免费的跨平台开源开发环境&#xff09;的最流行语言。 C# 程序可以在许多不同的设备上运行&#xff0c;从物联网 (IoT) 设备到云以及介于两者之间的任何设备。 可为手机、台式机、笔记本电脑和服务器编写应用。C# 是一种跨平…

iba Data Export 导出面板选项

时间线选择真实时间“Absolute date / time” 时间间隔选择0.5Sec.&#xff08;最小为0.01Sec.&#xff09; 右侧数据根据需要选择

数学建模算法与应用 第15章 预测方法

目录 15.1 微分方程模型 Matlab代码示例&#xff1a;求解简单的微分方程 15.2 灰色预测模型&#xff08;GM&#xff09; Matlab代码示例&#xff1a;灰色预测模型 15.3 自回归模型&#xff08;AR&#xff09; Matlab代码示例&#xff1a;AR模型的预测 15.4 指数平滑法 M…

1997-2022年各省农作物总播种面积数据(无缺失)

1997-2022年各省农作物总播种面积数据 1、时间&#xff1a;1997-2022年 2、来源&#xff1a;国家统计局、统计年鉴 3、指标&#xff1a;农作物总播种面积(千公顷) 4、范围&#xff1a;31省 5、缺失情况&#xff1a;无缺失 6、指标解释&#xff1a;农作物播种面积指农业生…

SCI英文文献阅读工具【全文翻译】【逐句翻译】

关注B站可以观看更多实战教学视频&#xff1a;hallo128的个人空间 SCI英文文献阅读工具【全文翻译】【逐句翻译】 1. 全文翻译【DeepL】 适用于泛读网址&#xff1a;https://www.deepl.com/zh/translator/files 1.1 前提 文档大小&#xff1a;pdf文档不超过5M&#xff08;可先…

Java实现邮件发送功能

目录 一、准备工作 二、简易文本邮件发送的实现 2.1 步骤 2.2 代码 三、复杂文件内容的发送 3.1 文件构成解析 3.2 包含图片的发送 3.3 包含附件的发送 四、实战 4.1 jsp动态页面 4.2 实体类POJO 4.3 Servlet 4.4 注册Servlet 4.5 发送邮箱核心类 一、准备工作 1、…

快速创建一个vue项目并运行

前期准备工作: 1.安装node 2.安装npm 3.设置淘宝镜像 4.全局安装webpack 5.webpack 4.X 开始&#xff0c;需要安装 webpack-cli 依赖 6.全局安装vue-cli 正文开始: 1.创建项目 ,回车 vue init webpack vue-svg > Project name vue-demo 项目名称 回车 > Pro…

harmonyOS next之实现时间打卡定时器

需求&#xff1a;实现一个时间打卡签到按钮。 实现方法&#xff1a;每隔一秒钟获取一下当前时间。 实现代码如下&#xff1a; Column(){Text(this.curTime).fontColor(#FFFFFF).fontWeight(600).fontSize(32vp)Text(上班打卡).fontColor(#FFFFFF) } .width(170vp) .height(170…

⭐️苹果电脑安装windows10双系统【详细图文步骤保姆级教程】【本教材适用于MAC台式机、笔记本MacBook air和pro】

苹果电脑安装windows10双系统【详细图文步骤保姆级教程】【本教材适用于MAC台式机、笔记本MacBook air和pro】 苹果电脑安装windows10双系统一、准备工作准备项1&#xff1a;U盘作为系统安装盘准备项2&#xff1a;您需要安装的系统镜像 二、启动转换助理步骤1&#xff1a;找到启…