计算机视觉——Opencv(实现抠图功能)

本文将介绍如何利用 OpenCV (cv2)NumPy 对图像进行一系列操作:

  • 调整图像尺寸并旋转

  • 使用 Canny 算法进行边缘检测

  • 提取最大轮廓并生成掩模

  • 利用掩模提取原图中的目标区域并保存

我们将以下面这张图作为示例,目标是提取图像中最大的物体区域,并保存成一张新图片

导入库 + 读取图片 + 预处理

python 复制代码
# 1. 导入需要的库
import cv2
import numpy as np

# -------------------------- 读取并预处理图片 --------------------------
# 读取图片(把路径换成你自己的图片路径)
img = cv2.imread(r"C:\Users\LEGION\Desktop\fba8f805b62cae66c6579969abeb86d8.jpg")

# 检查图片是否读取成功(非常重要!)
if img is None:
    raise FileNotFoundError("图片读取失败,请检查路径是否正确!")

# 统一调整图片大小:宽640,高480
img_resized = cv2.resize(img, (640, 480))

# 逆时针旋转90度(让扇子摆正,方便检测)
img_rotated = cv2.rotate(img_resized, cv2.ROTATE_90_COUNTERCLOCKWISE)

# 显示效果
cv2.imshow("1-原图预处理后", img_rotated)
cv2.waitKey(0)
cv2.destroyAllWindows()

整尺寸 resize()

  • 统一图片大小,降低计算量,保证处理稳定

旋转图片 rotate()

  • ROTATE_90_COUNTERCLOCKWISE = 逆时针 90 度

  • 作用:让扇子摆正,边缘检测更准确

注意:

  • 旋转方向要明确,如果写成 cv2.ROTATE_90_CLOCKWISE 就会顺时针旋转。

  • 缩放先于旋转,可以避免旋转后图像尺寸不一致导致的裁切问题。

Canny 边缘检测(核心步骤)

python 复制代码
# -------------------------- Canny边缘检测 --------------------------
# 1. 转为灰度图(边缘检测必须用灰度图)
gray = cv2.cvtColor(img_rotated, cv2.COLOR_BGR2GRAY)

# 2. 高斯模糊:去噪点(边缘检测前必做)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)

# 3. Canny边缘检测
edges = cv2.Canny(blurred, 50, 150)

# 显示结果
cv2.imshow("2-灰度图", gray)
cv2.imshow("3-模糊后", blurred)
cv2.imshow("4-Canny边缘结果", edges)
cv2.waitKey(0)
cv2.destroyAllWindows()
  1. 灰度化 cvtColor

    • 彩色图有 3 个通道,灰度图只有 1 个通道

    • Canny 边缘检测只接受灰度图

  2. 高斯模糊 GaussianBlur

    • (5,5)是模糊核大小(必须奇数)

    • 作用:消除噪点,防止把噪点当成边缘

  3. Canny 边缘检测

    • 50:低阈值 ------ 小于这个值的边缘会被抛弃

    • 150:高阈值 ------ 大于这个值的边缘会被保留

    • 标准比例:1:2 或 1:3

运行后你会看到:扇子变成白色线条,背景黑色,这就是边缘。

提示:阈值可以调节,低阈值太小会有噪声,太大会丢失细节。

查找轮廓 + 版本兼容处理

python 复制代码
# -------------------------- 查找轮廓(兼容所有OpenCV版本) --------------------------
# 查找轮廓
contour_result = cv2.findContours(
    edges.copy(),
    cv2.RETR_EXTERNAL,   # 只找最外层轮廓
    cv2.CHAIN_APPROX_SIMPLE
)

# 版本兼容(3.x 和 4.x/5.x 返回值不同)
if len(contour_result) == 2:
    contours, hierarchy = contour_result
else:
    _, contours, hierarchy = contour_result

# 判断是否找到轮廓
if not contours:
    raise ValueError("未检测到扇子轮廓,请调整Canny阈值!")

# 选择面积最大的轮廓(扇子主体)
max_contour = max(contours, key=cv2.contourArea)

print(f"找到 {len(contours)} 个轮廓,最大轮廓面积为:{cv2.contourArea(max_contour)}")
  • findContours 查找轮廓

    • 从 Canny 边缘图中提取所有闭合形状

    • RETR_EXTERNAL:只提取最外层,不包含内部小孔

  • 版本兼容

    • OpenCV 3.x 返回 3 个值

    • OpenCV 4.x/5.x 返回 2 个值

    • 代码自动适配,不会报错

  • 筛选最大轮廓

    • 扇子是图片中最大的物体

    • max(..., key=cv2.contourArea) 自动选出扇子轮廓

生成掩模(Mask)

python 复制代码
# -------------------------- 生成掩模 --------------------------
# 创建和图片一样大的全黑图片(掩模)
mask = np.zeros_like(img_rotated)

# 在掩模上把扇子轮廓涂成白色
cv2.drawContours(
    mask,        # 在哪个图上画
    [max_contour],  # 画哪个轮廓
    -1,          # 画所有层级
    (255,255,255), # 白色
    cv2.FILLED   # 填充内部
)

# 显示掩模
cv2.imshow("5-掩模", mask)
cv2.waitKey(0)
cv2.destroyAllWindows()
  • 掩模是什么?

    • 全黑图片 = 不要的区域

    • 白色区域 = 要保留的区域

  • drawContours 填充轮廓

    • cv2.FILLED:填充轮廓内部

    • 最终得到一张只有扇子是白色、其余全黑的图片,这就是掩模

掩模作用:告诉程序 "只保留白色区域"。

提取扇子 + 保存图片

python 复制代码
# -------------------------- 提取扇子并保存 --------------------------
# 按位与操作:只保留掩模白色区域
result = cv2.bitwise_and(img_rotated, mask)

# 保存图片
cv2.imwrite("shanzi.png", result)

# 显示最终结果
cv2.imshow("6-最终提取的扇子", result)
cv2.waitKey(0)
cv2.destroyAllWindows()

print("✅ 处理完成!扇子已保存为 shanzi.png")

bitwise_and 按位与

  • 只有原图和掩模同时为非 0的区域才会保留

  • 黑色区域(0)会被直接过滤

常见问题

  • 检测不到轮廓

    • 把 Canny 阈值调低:30, 100
  • 提取不完整

    • 模糊核改小:(3,3)

    • 阈值调低

运行结果

相关推荐
confiself2 小时前
deer-flow2本地启动(无make无nginx启动)
linux·人工智能
王解2 小时前
OpenClaw 技能深度解析(一):Self-Improving —— 从 SKILL.md 看 AI 的自我进化逻辑
人工智能·ai agent·skill·openclaw
雷焰财经2 小时前
破解差异化转型之困:从宇信科技“双龙头”项目看其全栈赋能之道
大数据·人工智能·科技
EasyGBS2 小时前
零成本守护监控画质:国标GB28181平台EasyGBS视频质量诊断覆盖11类画质异常
人工智能·音视频·蓝屏·画面冻结·花屏检测·画面抖动·画面模糊
格林威2 小时前
工业相机图像高速存储(C++版):直接IO存储方法,附Basler相机实战代码!
开发语言·c++·人工智能·数码相机·计算机视觉·视觉检测·工业相机
智算菩萨2 小时前
深度解析ChatGPT 5.4赋能Python Selenium网页自动化测试:从理论到实践的完整指南
人工智能·python·selenium·ai·chatgpt
大傻^2 小时前
【Spring AI -01】Spring AI 2.0 架构重构深度解析:从单体核心到模块化领域的演进
人工智能·spring·架构·spring ai·模块化设计·java 21·架构迁移
未来之窗软件服务2 小时前
vosk-ASR asterisk-ari调用[AI人工智能(五十四)]—东方仙盟
人工智能·仙盟创梦ide·东方仙盟
芯片-嵌入式2 小时前
具身智能(4):最重要的感知sensor:相机
人工智能·深度学习·dnn