计算机视觉(opencv)练习——抠图(图像裁剪与轮廓提取) - 详解

news/2025/9/28 18:55:21/文章来源:https://www.cnblogs.com/lxjshuju/p/19117396


用 OpenCV 实现图像裁剪与轮廓提取 —— 以风扇图像为例

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

  • 调整图像尺寸并旋转

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

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

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

我们将以一张名为 fan.jpg 的图片作为示例,目标是提取图像中最大的物体区域,并保存成一张新图片 shanzi.png

原图:

运行结果:


1. 导入必要的库

import cv2
import numpy as np
  • cv2:OpenCV 的 Python 接口,提供各种图像处理函数。

  • numpy:用于创建掩模、矩阵运算等。


2. 读取、缩放和旋转图像

fan = cv2.imread('fan.jpg')  # 读取原图
fan = cv2.resize(fan, dsize=(640, 480))  # 调整图片尺寸
fan = cv2.rotate(fan, cv2.ROTATE_90_COUNTERCLOCKWISE)  # 逆时针旋转90度

解析:

  • cv2.imread() 读取图像,返回一个三维数组(高度、宽度、通道)。

  • cv2.resize() 将图像缩放到 640×480,保证后续处理尺寸统一。

  • cv2.rotate() 按指定模式旋转图像。这里使用 cv2.ROTATE_90_COUNTERCLOCKWISE 实现逆时针 90° 旋转。

⚠️ 注意:

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

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


3. 转为灰度并进行 Canny 边缘检测

fan_gray = cv2.cvtColor(fan, cv2.COLOR_BGR2GRAY)  # 转换为灰度图
cv2.imshow('fan_b', fan_gray)
cv2.waitKey(0)
zl_canny = cv2.Canny(fan_gray, threshold1=100, threshold2=150)  # Canny边缘检测
cv2.imshow('zl_canny', zl_canny)
cv2.waitKey(0)

解析:

  • cv2.cvtColor() 将彩色图转为灰度图,减少通道数,提高边缘检测效率。

  • cv2.Canny() 用双阈值算法检测边缘:

    • threshold1=100:低阈值,用于弱边缘判定。

    • threshold2=150:高阈值,强边缘必须大于此值。

  • cv2.imshow() 显示图像,cv2.waitKey(0) 等待用户按键。

提示:

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

  • 如果图像噪声大,建议先用 cv2.GaussianBlur() 进行平滑。


4. 查找轮廓并生成掩模

_, contours, hierarchy = cv2.findContours(zl_canny, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
image_copy = fan.copy()
image_copy = cv2.drawContours(image=image_copy, contours=contours, contourIdx=-1, color=(0, 255, 0), thickness=3)
cv2.imshow('contours_show', image_copy)
cv2.waitKey(0)
cnt = sorted(contours, key=cv2.contourArea, reverse=True)[0]  # 选取最大面积的轮廓
mask = np.zeros(fan_gray.shape, dtype="uint8")  # 创建一个黑色掩模
cv2.drawContours(mask, contours=[cnt], contourIdx=-1, color=255, thickness=-1)
cv2.imshow('mask', mask)
cv2.waitKey(0)

解析:

  • cv2.findContours() 找出所有轮廓:

    • cv2.RETR_EXTERNAL:只检测最外层轮廓,忽略嵌套。

    • cv2.CHAIN_APPROX_SIMPLE:压缩冗余点,只保留拐点,提高效率。

  • cv2.drawContours() 用绿色画出所有轮廓,方便观察。

  • sorted(..., key=cv2.contourArea, reverse=True)[0] 找到面积最大的轮廓。

  • np.zeros() 创建一张全黑的图(掩模)。

  • 再用 cv2.drawContours() 填充该轮廓(thickness = -1 表示填充)。

小技巧:

  • 如果想查看每个轮廓的面积,可以 for cnt in contours: print(cv2.contourArea(cnt))

  • 在某些 OpenCV 版本中,cv2.findContours() 只返回两个值,可以写成 contours, hierarchy = cv2.findContours(...)


5. 利用掩模提取目标区域并保存

thresh_mask_and = cv2.bitwise_and(fan, fan, mask=mask)
cv2.imshow('thresh_mask_and', thresh_mask_and)
cv2.waitKey(0)
cv2.imwrite('shanzi.png', thresh_mask_and)

解析:

  • cv2.bitwise_and() 按位与操作,将掩模中值为 255 的部分保留下来,其余变黑。

  • 结果就是原图中最大轮廓对应的区域。

  • cv2.imwrite() 保存图片。

建议:

  • 保存路径可以改成绝对路径,比如 cv2.imwrite(r'C:\output\shanzi.png', thresh_mask_and),避免找不到文件。

  • 如果后续还需要透明背景,可以将黑色部分处理成透明通道。


6. 运行效果

整个流程执行后,你将看到:

  1. 缩放+旋转后的图像

  2. 灰度图

  3. Canny 边缘图

  4. 绘制轮廓的彩色图

  5. 填充的掩模

  6. 最终裁剪出的目标区域,并保存为 shanzi.png

这样我们就实现了一个完整的 目标提取与裁剪 工作流。


总结

本文展示了一个典型的图像处理任务:

  • 图像预处理:缩放、旋转、灰度化

  • 边缘检测:Canny 算法

  • 轮廓提取:寻找最大面积目标

  • 掩模应用:提取目标并保存

这种方法不仅适用于风扇图片,也可以应用于其他物体提取,如分割零件、裁剪证件照、检测物品轮廓等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/921002.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

完整教程:上下文工程驱动智能体向 透明化推理日志

完整教程:上下文工程驱动智能体向 透明化推理日志pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas"…

基于Mysql+SpringBoot+vue框架-在线宠物用品交易网站的设计与实现 - 实践

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

深入解析:@scqilin/phone-ui 手机外观组件库

深入解析:@scqilin/phone-ui 手机外观组件库pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", &qu…

北京网站设计权威乐云践新站建设 app开发网站

原 Linux搭建SVN 服务器 发表于1年前(2014-08-05 17:55) 阅读(12257) | 评论(3) 31人收藏此文章, 我要收藏赞3摘要 Linux搭建SVN 服务器目录[-] Linux搭建SVN 服务器1 安装SVN2 使用客户端连接2.1 使用…

全景网站如何建设虚拟主机登录wordpress管理后台

本篇文章包含内容较多,请参照目录浏览,在每一部分结束或,有该部分可能遇到的问题0、开始本教程前请先备份电脑中的重要文件!!!!一、Ubuntu20.04 搭建更详细的内容请参照该博客:https://www.cnblogs.com/mas…

Tita项目与绩效一体化管理:驱动企业效能跃升的数字化引擎

在数字经济时代,企业竞争的核心已从单一业务能力转向组织整体效能的协同释放。项目管理作为企业战略落地的关键抓手,正面临从”任务执行”到”价值创造”的范式转变。Tita项目经营管理一体化平台,凭借其独特的项目与…

第七篇

今天是9月28日,今天是星期日但是补星期三的课,调休这玩意真是烦,早上上的离散和马克思主义基本原理,离散没咋明白,马原倒是听进去不少。

网站建设制作方法怎样建自己的网站免费的

1.IDEA修改maven路径无效 创建spring项目,Maven导入报错,无法正常导入jar报,发现setting中设置的maven路径不是自己下载的路径,修改后无效。运行之后maven路径又恢复为其默认的路径 解决方案: 删除.mvn文件&#xff0…

升级openssl影响

升级openssl影响在 CentOS(或者 RHEL 系)里,要判断 哪些软件依赖 OpenSSL,可以用几个不同层级的办法:1️⃣ 查询已安装软件包依赖(RPM 层面) # 哪些包依赖 openssl-libs rpm -q --whatrequires openssl-libs# 或…

Day23抽象类

package oop1.Demo8;//抽象类中,所由继承了它的子类,必须要实现它的方法~除非子类也是抽象类,那就继续套娃 public class A extends Action{@Overridepublic void dosomething() {} }package oop1.Demo8;//抽象类 …

陕西正天建设有限公司网站可以自己做网站赚钱吗

在宝塔面板环境下安装nps服务端 一、所需环境二、开始安装三、打开nps控制台四、更改默认账号密码和连接秘钥五、反向代理挂载SSL证书 一、所需环境 阿里云轻应用服务器(选择宝塔应用镜像)域名(最好也是阿里注册的域名)对应的ssl…

做影视网站犯法吗不用wordpress 知乎

总结: 初级:简单修改一下超参数,效果一般般但是够用,有时候甚至直接不够用 中级:optuna得出最好的超参数之后,再多一些epoch让train和testloss整体下降,然后结果就很不错。 高级:…

完整教程:开源的 CSS 动画库

完整教程:开源的 CSS 动画库pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco"…

ES 是否有类似mysql explain的语句诊断用法

目录一、explain API:分析查询匹配与索引使用1. 基本用法方式1:查询时添加 explain=true方式2:针对单个文档分析(推荐)2. 核心返回结果解读二、profile API:分析查询执行性能1. 基本用法2. 核心返回结果解读三、…

让每次语音唤醒都可靠,公牛沐光重构可观测体系

本文详细介绍了公牛沐光团队如何从开源监控方案 SkyWalking 成功迁移到阿里云 ARMS,构建起一套集观测、追踪、日志分析与智能告警于一体的全栈式可观测平台的实践历程。作者:公牛集团,周施乐 王雷 欧阳绩新;阿里云…

【2025-09-27】连岳摘抄

23:59自信与骄傲有异:自信者常沉着,而骄傲者常浮扬。——梁启超高三可能是人生压力最大的一年。高三生身体上发育成熟了,但大脑还没有,不能很好地控制自己的情绪。压力巨大与大脑未成熟,这对矛盾造成高三生容易暴…

第三周预习作业(AI)

第三周预习作业(AI)20231406王浩霖《密码系统设计》第三周预习报告 学习内容 《嗨翻C语言》第4章函数的使用与定义 参数传递与返回值 变量的作用域 头文件与多文件编程《Windows C/C++加密解密实战》第4章重点4.2, 4…

Python 爬虫 HTTPS 实战,requests httpx aiohttp 抓取技巧、证书问题与抓包调试全流程 - 教程

Python 爬虫 HTTPS 实战,requests httpx aiohttp 抓取技巧、证书问题与抓包调试全流程 - 教程pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !imp…