news 2026/8/11 13:57:47

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
计算机视觉——Opencv(实现抠图功能)

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

  • 调整图像尺寸并旋转

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

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

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

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

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

# 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 边缘检测(核心步骤)

# -------------------------- 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

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

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

查找轮廓 + 版本兼容处理

# -------------------------- 查找轮廓(兼容所有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)

# -------------------------- 生成掩模 -------------------------- # 创建和图片一样大的全黑图片(掩模) 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:填充轮廓内部

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

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

提取扇子 + 保存图片

# -------------------------- 提取扇子并保存 -------------------------- # 按位与操作:只保留掩模白色区域 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)

    • 阈值调低

运行结果

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/14 15:39:27

C++编译期字符串加密

1、非修改序列算法这些算法不会改变它们所操作的容器中的元素。1.1 find 和 find_iffind(begin, end, value):查找第一个等于 value 的元素,返回迭代器(未找到返回 end)。find_if(begin, end, predicate):查找第一个满…

作者头像 李华
网站建设 2026/7/14 15:39:29

TSP算法小软件V7.0源代码(ubuntu24+lazarus4+sqlite3)

TSP算法小软件V7.0源代码(ubuntu24lazarus4sqlite3) 2024年2月 网名:窗明几净~天气几好^几何原本^欧几里得关于TSP的 P=NP 解法的可能性猜想:海岸线猜想三界火宅人 /开源(元)盛世/阴汁成世 2026-03-16网上寻T…

作者头像 李华
网站建设 2026/7/14 15:39:26

P1550 [USACO08OCT] Watering Hole G

使用并查集&#xff0c;将水井的打井钱看作是边加入edges中即可#include<bits/stdc.h> using namespace std; struct Edge{int u,v,w; }; vector<int> parent; int find(int x){if(x!parent[x]){parent[x]find(parent[x]);}return parent[x]; } bool unite(int x,i…

作者头像 李华
网站建设 2026/7/14 15:39:27

推荐开源项目:Aperi‘Solve - 图像深度分析平台

推荐开源项目&#xff1a;AperiSolve - 图像深度分析平台 【免费下载链接】AperiSolve Steganalysis web platform 项目地址: https://gitcode.com/gh_mirrors/ap/AperiSolve 1、项目介绍 AperiSolve 是一个强大的图像分析平台&#xff0c;特别专注于隐藏信息的检测与提…

作者头像 李华
网站建设 2026/7/16 20:04:03

linux的常用命令

linux的常用命令 1 压缩解压缩 &#xff08;1&#xff09;解压到指定目录 tar -zxvf nginx-1.23.1 -C /home/aries/nginx&#xff08;2&#xff09;unzip解压zip文件 -o&#xff1a;表示解压后覆盖目录中的相同文件 不进行询问 unzip - o **.zip -d 目录2 列表 文件内容大小…

作者头像 李华
网站建设 2026/7/14 15:39:45

基于Git图形化工具TortoiseGit在Gitee上进行代码托管与协作开发

参考视频&#xff1a;TortoiseGit常用的基本使用教程 点击观看 文章目录前言一、下载软件二、基本操作1.在Gitee网站上创建远程仓库2.clone远程仓库到本地电脑3.如果是团队协作需要创建自己的分支4.add将代码添加到本地仓库5.commit提交代码到本地仓库6.push推送本次操作到远程…

作者头像 李华