使用python语言,视觉检测中怎么将两张图片判断是同一张图片,两张图片存在光照变化,位置变化(上下左右移动几十个像素),其实是同一张图片
3条回答 默认 最新
檀越@新空间 2025-08-06 10:31关注上午好☀️☀️☀️️
本答案参考通义千问在视觉检测中,判断两张图片是否为同一张图片(即使存在光照变化、**位置变化(上下左右移动几十个像素)**等),可以采用以下几种方法。以下是详细的解决方案:
一、使用图像相似度算法
1. SSIM(结构相似性指数)
- 原理:SSIM 是一种衡量两幅图像在亮度、对比度和结构上相似性的指标。
- 优点:对光照变化和轻微位移有较好的鲁棒性。
- 缺点:对于大范围的位移或旋转不敏感。
from skimage.metrics import structural_similarity as ssim import cv2 def compare_images_ssim(img1_path, img2_path): # 读取图像并转换为灰度图 img1 = cv2.imread(img1_path, 0) img2 = cv2.imread(img2_path, 0) # 计算 SSIM score, _ = ssim(img1, img2, full=True) return score重点:
ssim函数返回的是一个介于 -1 到 1 的值,越接近 1 表示越相似。
二、使用特征点匹配(如 SIFT、SURF、ORB)
2. SIFT / SURF / ORB 特征提取与匹配
- 原理:通过提取图像中的关键点和描述符,然后进行匹配。
- 优点:对光照变化、平移、旋转都有一定鲁棒性。
- 缺点:计算量较大,但适用于大多数情况。
import cv2 def match_features(img1_path, img2_path): # 读取图像 img1 = cv2.imread(img1_path) img2 = cv2.imread(img2_path) # 转换为灰度图 gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY) gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY) # 使用 ORB 特征提取器 orb = cv2.ORB_create() # 找到关键点和描述符 kp1, des1 = orb.detectAndCompute(gray1, None) kp2, des2 = orb.detectAndCompute(gray2, None) # 使用 BFMatcher 进行匹配 bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True) matches = bf.match(des1, des2) # 按距离排序 matches = sorted(matches, key=lambda x: x.distance) # 绘制匹配结果 matched_img = cv2.drawMatches(img1, kp1, img2, kp2, matches[:50], None, flags=2) cv2.imshow("Matches", matched_img) cv2.waitKey(0) cv2.destroyAllWindows() # 返回匹配数量 return len(matches)重点:
len(matches)越多,说明图像越相似。
三、使用深度学习模型(如 CNN 或 Siamese Network)
3. 使用预训练的 CNN 提取特征
- 原理:使用预训练的卷积神经网络(如 VGG、ResNet)提取图像特征,再比较特征向量之间的相似度。
- 优点:对光照变化、位置偏移具有较强鲁棒性。
- 缺点:需要一定的 GPU 算力支持。
import torch import torchvision.models as models import torchvision.transforms as transforms from PIL import Image # 加载预训练的 ResNet18 模型 model = models.resnet18(pretrained=True) model.eval() model = torch.nn.Sequential(*list(model.children())[:-1]) # 去掉最后的全连接层 # 图像预处理 transform = transforms.Compose([ transforms.Resize((224, 224)), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) ]) def extract_features(image_path): image = Image.open(image_path) image = transform(image).unsqueeze(0) # 添加 batch 维度 with torch.no_grad(): features = model(image) return features.squeeze().numpy() def compare_images_cnn(img1_path, img2_path): feat1 = extract_features(img1_path) feat2 = extract_features(img2_path) # 使用余弦相似度 similarity = 1 - (feat1 @ feat2.T) / (np.linalg.norm(feat1) * np.linalg.norm(feat2)) return similarity重点:
cosine similarity越接近 1,表示两张图片越相似。
四、结合上述方法(推荐方案)
4. 综合方案:使用特征匹配 + 相似度评分
def is_same_image(img1_path, img2_path, threshold=0.9): # 使用 SSIM ssim_score = compare_images_ssim(img1_path, img2_path) # 使用特征匹配 match_count = match_features(img1_path, img2_path) # 使用 CNN 特征相似度 cnn_score = compare_images_cnn(img1_path, img2_path) # 综合判断 if ssim_score > threshold and match_count > 50 and cnn_score > 0.9: return True else: return False重点:设置合理的阈值(如
threshold=0.9)来判断是否为同一张图片。
五、总结(有序列表)
- 使用 SSIM:评估图像结构相似性,适合光照变化和轻微位移。
- 使用特征点匹配(如 ORB):通过关键点匹配判断图像是否为同一张。
- 使用深度学习模型(CNN):提取高维特征,增强鲁棒性。
- 综合方案:结合多种方法,提高判断准确率。
- 设置合理阈值:根据实际应用场景调整判断标准。
如果你有具体图片或场景,我可以进一步优化代码或建议更合适的算法。
本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏 举报