You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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)

常见报错排查清单

  1. 轮廓检测报错:检查传入findContours的是不是单通道二值图(打印dilated_diff.shape,应该是(高度, 宽度),不是(高度, 宽度, 3))
  2. 噪点太多:调高二值化的阈值(比如把30改成50),或者增大膨胀的kernel(比如改成(7,7)),或者调大contourArea的过滤阈值
  3. 没检测到差异:再次确认两张截图的尺寸完全一致,或者调低二值化的阈值,让小差异也能被检测到
  4. 自适应阈值还是报错:试试换ADAPTIVE_THRESH_MEAN_C替代GAUSSIAN_C,或者调整blockSize的数值(比如改成15)

内容的提问来源于stack exchange,提问作者E. Jaep

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 09:37:03