使用OpenCV与Selenium对比新旧CMS页面截图差异遇报错求助
解决新旧CMS页面截图对比的OpenCV报错问题
嘿,我帮你捋捋这个问题——你用Selenium截新旧CMS页面、再用OpenCV找差异画矩形的思路完全没问题,报错肯定是某个细节没踩对,咱们一步步来解决:
第一步:先把Selenium截图的坑填上
很多人忽略了固定窗口尺寸这一点,要是新旧页面的截图尺寸不一样,后续OpenCV处理直接炸锅。先确保你的截图代码是这样的:
from selenium import webdriver def capture_cms_screenshot(url, save_path): # 配置Chrome选项,固定窗口大小是关键! options = webdriver.ChromeOptions() options.add_argument("--headless=new") # 无头模式,不用弹浏览器窗口 options.add_argument("--window-size=1920,1080") # 统一窗口尺寸,可根据你的页面调整 options.add_argument("--disable-extensions") # 避免插件干扰 driver = webdriver.Chrome(options=options) driver.get(url) # 加个等待确保页面加载完成 driver.implicitly_wait(10) driver.save_screenshot(save_path) driver.quit() # 调用截图:替换成你的新旧CMS地址 capture_cms_screenshot("旧CMS页面URL", "old_cms.png") capture_cms_screenshot("新CMS页面URL", "new_cms.png")
运行完可以检查下两张图的尺寸,用cv2.imread读入后打印shape,必须完全一致!
第二步:搞定自适应阈值的报错
自适应阈值报错90%的原因是没转灰度图或者参数不对,它只能处理单通道的灰度图,而且blockSize必须是奇数。给你个能跑通的示例:
import cv2 import numpy as np # 读取图像并转灰度 old_img = cv2.imread("old_cms.png") new_img = cv2.imread("new_cms.png") # 先检查图像是否读取成功 if old_img is None or new_img is None: raise ValueError("图像读取失败!检查文件路径是否正确,或者截图是否损坏") old_gray = cv2.cvtColor(old_img, cv2.COLOR_BGR2GRAY) new_gray = cv2.cvtColor(new_img, cv2.COLOR_BGR2GRAY) # 正确调用自适应阈值:blockSize用奇数,C是微调的常数(2-5都可以) adapt_thresh_old = cv2.adaptiveThreshold( old_gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2 ) adapt_thresh_new = cv2.adaptiveThreshold( new_gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2 )
如果还是报错,把具体的错误信息贴出来,但先确保上面的步骤都做了——转灰度、blockSize是奇数、图像有效。
第三步:解决轮廓检测的报错
如果关掉自适应阈值后轮廓检测还是报错,大概率是差异图没处理好或者轮廓检测参数用错了。直接给你一个稳定的完整对比流程,跳过容易出问题的自适应阈值(如果不是必须用的话):
# 1. 计算灰度图的差异 diff = cv2.absdiff(old_gray, new_gray) # 2. 二值化:把差异区域转成白色,背景黑色(阈值30可以根据实际调整) _, thresh = cv2.threshold(diff, 30, 255, cv2.THRESH_BINARY) # 3. 膨胀操作:把零散的小差异点合并成大区域,方便轮廓检测 kernel = np.ones((5,5), np.uint8) dilated_diff = cv2.dilate(thresh, kernel, iterations=2) # 4. 轮廓检测:这里注意参数顺序,返回的是轮廓和层级 contours, _ = cv2.findContours(dilated_diff, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 5. 在新页面截图上画红色矩形标记差异 result_img = new_img.copy() for contour in contours: # 过滤掉小噪点(面积阈值100可以自己调) if cv2.contourArea(contour) < 100: continue # 获取轮廓的外接矩形 x, y, w, h = cv2.boundingRect(contour) # 画矩形:红色,线宽2 cv2.rectangle(result_img, (x, y), (x+w, y+h), (0, 0, 255), 2) # 保存结果图 cv2.imwrite("cms_diff_result.png", result_img)
常见报错排查清单
- 轮廓检测报错:检查传入
findContours的是不是单通道二值图(打印dilated_diff.shape,应该是(高度, 宽度),不是(高度, 宽度, 3)) - 噪点太多:调高二值化的阈值(比如把30改成50),或者增大膨胀的
kernel(比如改成(7,7)),或者调大contourArea的过滤阈值 - 没检测到差异:再次确认两张截图的尺寸完全一致,或者调低二值化的阈值,让小差异也能被检测到
- 自适应阈值还是报错:试试换
ADAPTIVE_THRESH_MEAN_C替代GAUSSIAN_C,或者调整blockSize的数值(比如改成15)
内容的提问来源于stack exchange,提问作者E. Jaep
相关产品推荐
相关产品推荐

