day16 - 提取图像前景

news/2024/12/5 3:22:51/

在我们平时使用购物软件是会发现通常在搜索框右侧都会有一个相机的标志,这个标志是可以让用户通过图片来搜索自己需要购买的内容。拍照购物将用户拍摄的商品与商品图库的图像进行对比,找到最为相似的商品。但是由于用户拍摄的图像是任意的随机的,不可能与商家的商品图完全吻合,复杂的商品背景对拍照购物造成了很大的影响,商品与背景图像的分离技术成为了技术的关键。

本期我们来学习使用图像轮廓相关的技术来实现图像前景的提取。

完成本期内容,你可以:

  • 了解图像轮廓的基本定义
  • 了解图像轮廓检测与边缘检测的区别
  • 学会提取图像的轮廓并绘制轮廓

若要运行案例代码,你需要有:

  • 操作系统:Ubuntu 16 以上 或者 Windows10

  • 工具软件:VScode 或者其他源码编辑器

  • 硬件环境:无特殊要求

  • 核心库:python 3.6.13, opencv-contrib-python 3.4.11.39,opencv-python 3.4.2.16


判断图形轮廓

OpenCV中提供了cv2.findContours()函数可以通过计算图像梯度来判断出图像的边缘。

函数原型:contours, hierarchy = cv2.findContours( image, mode, method)

contours为返回的轮廓。hierarchy为返回的图像的拓扑信息(轮廓层次)。

参数描述如下:

  • contours:返回的轮廓。
  • hierarchy:图像的拓扑信息(轮廓层次)。
  • image:原始图像。
  • mode:轮廓检索模式。
  • method:轮廓的近似方法
mode参数含义
cv2.RETR_EXTERNAL只检测外轮廓
cv2.RETR_LIST检测所有轮廓,轮廓不建立等级
cv2.RETR_CCOMP检测所有轮廓,建立两个等级的轮廓
cv2.RETR_TREE检测所有轮廓,建立等级树轮廓
method参数含义
cv2.CHAIN_APPROX_NONE存储所有的轮廓点
cv2.CHAIN_APPROX_SIMPLE压缩存储
cv2.CHAIN_APPROX_TC89_L1使用ten-Chinl chain 近似算法
cv2.CHAIN_APPROX_TC89_KCOS使用ten-Chinl chain 近似算法

绘制图像轮廓

OpenCV中提供了cv2.drawContours()函数来绘制图像轮廓。

函数原型:image=cv.drawContours(image, contours, contourIdx, color[, thickness[, lineType[, hierarchy[, maxLevel[, offset]]]]])

image为目标图像,绘制了边缘的原始图像。

参数描述如下:

  • image:待绘制轮廓图像。
  • contours:需要绘制的轮廓。
  • contourIdx:需要绘制的边缘索引。
  • color:绘制的颜色,用 BGR 格式表示。
  • thickness:可选参数,表示绘制轮廓时所用的画笔粗细。
  • lineType:可选,绘制的线型。
  • hierarchy:对应函数cv2.findContours()所输出的层次信息。
  • maxLevel:该参数控制绘制的轮廓层次深度。
  • offset:偏移参数。

绘制多边形轮廓

OpenCV中提供了cv2.approxPolyDP()函数来绘制多边形轮廓。

函数原型:approxCurve = cv2.approxPolyDP( curve, epsilon, closed )

approxCurve为逼近多边形点集;

参数描述如下:

  • curve:是轮廓。
  • epsilon:精度,原始轮廓的边界点与逼近多边形边界之间的最大距离。
  • closed:逻辑值。该值为真时,逼近多边形是封闭的;否则,逼近曲线是不封闭的。

具体步骤

使用图像轮廓相关技术提取图像前景。

请添加图片描述

请添加图片描述

步骤一:创建项目工具

创建项目名为提取图像前景,项目根目录下新建code文件夹储存代码,新建dataset文件夹储存数据,项目结构如下:

提取图像前景                             # 项目名称
├── code                               # 储存代码文件
├── dataset                            # 储存数据文件

注:如项目结构已存在,无需再创建。

步骤二:获取轮廓并绘制

  1. 导入所需模块:OpenCV、NumPy ;
  2. 读取dataset文件夹下的dandelion.jpg 图片;
  3. 将原图像复制,用于绘制图像轮廓;
  4. 将图像转换为二值图像;
  5. 获取图像轮廓并绘制;

代码实现

# 导入OpenCV、numpy
import cv2
import numpy as npo = cv2.imread('../dataset/dandelion.jpg')# 读取原图
img = o.copy() # 复制图像
gray = cv2.cvtColor(o,cv2.COLOR_BGR2GRAY)  # 原图从彩图变成单通道灰度图像
ret, binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)  # 灰度图像转化为二值图像,阈值为127,最大值为255
# 获取二值化图像中的轮廓以及储存轮廓层次数据
contours, hierarchy = cv2.findContours(binary,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
# 在复制得到的图像上绘制轮廓
cv2.drawContours(img, contours, -1, (0, 0, 255), 2)

步骤三:提取图像前景

  1. 创建一张与原始图像大小相同值为0的数组(黑色图像)作为掩码;
  2. 在掩码中绘制出实心轮廓,颜色为白色;
  3. 将原始图像与掩码图像进行与运算,获取前景;

代码实现

# 创建原始图像大小相同的值为0的数组(黑色图像)
mask=np.zeros(o.shape,np.uint8) 
# 在mask中绘制出实心轮廓,颜色为白色
mask=cv2.drawContours(mask,contours,-1,(255,255,255),-1) 
# 将mask和原始图像进行计算,获取前景
loc=cv2.bitwise_and(o,mask)  

步骤四:结果展示

  1. 展示出绘制了图像轮廓的图像;
  2. 展示出掩码图像;
  3. 展示提取的前景图像;

代码实现

cv2.imshow("contours",img)
cv2.imshow("mask" ,mask)
cv2.imshow("foreground" ,foreground)
cv2.waitKey()
cv2.destroyAllWindows()

使用图像轮廓相关的技术来实现提取图像的前景,主要是因为绘制图像轮廓时可以绘制实心轮廓,在通过一张掩码图像来进行图像运算,根据之前讲过的图像运算的规律,可以将图像的前景提取出来。


http://www.ppmy.cn/news/81436.html

相关文章

八股总结(六):Android基础:四大组件与UI控件

文章目录 四大组件基本概念Activityzygote是什么?有什么作用?SystemServer是什么?有什么用,与zygote的关系是什么?为什么称为服务端对象?APP、AMS、zygote是三个独立的进程,他们之间如何通信呢&…

使用贝壳物联控制led灯

1、完成esp8266 01S的固件刷机 1.1 使用刷机软件刷原生固件 esp8266 01S要使用标准固件1M(主要是01S是8M) 1.2 刷机接线方式 ttl直接连esp8266 接线: tts esp8266 3v3 ---》面包板高----》3.3 tx--------------…

(原创)getX+Dio实现Flutter悬浮置顶的页面效果

前言 Flutter的开发相对已经比较成熟了,现在市面上不少商业应用也在使用这个技术 老实说,Flutter去实现一些基础的ui界面,效率还是很高的 当然前提是你对它要有一定的了解。 今天就演示一下,如何去实现一个基础悬浮置顶的页面效果…

第十一章 Productions最佳实践 - 生产电子表格

文章目录 第十一章 Productions最佳实践 - 生产电子表格生产电子表格界面设计 第十一章 Productions最佳实践 - 生产电子表格 生产电子表格 维护一个电子表格是很有帮助的,它可以逐个应用程序地组织信息系统。作为一般准则,应该为每个提供传入或传出数…

LeetCode 496 下一个更大元素 I

题目&#xff1a; nums1 中数字 x 的 下一个更大元素 是指 x 在 nums2 中对应位置 右侧 的 第一个 比 x 大的元素。 给你两个 没有重复元素 的数组 nums1 和 nums2 &#xff0c;下标从 0 开始计数&#xff0c;其中nums1 是 nums2 的子集。 对于每个 0 < i < nums1.leng…

电源方案对比

电源 1.方案选择&#xff1a;1 LM2596 2 MP1584 3&#xff1a;TPS54301LM25962.MP1584&#xff1a;3.TPS5430 2.1输出2A电流的纹波2.2 输出3A电流的纹波3.动态响应4.发热5.电源转换效率6.综合指标reference 1.方案选择&#xff1a;1 LM2596 2 MP1584 3&#xff1a;TPS5430 1LM…

Java【问题 05】yml配置文件boolean一直为false问题分析解决

yml配置文件boolean一直为false 1.问题说明2.bug复现2.1 yml配置2.2 配置类2.3 测试类2.4 结果输出 3.源码分析3.1 Data3.2 Generate Getters and Setters 4.问题解决4.1 修改参数名称4.2 添加Getter和Setter方法 1.问题说明 application.yml配置文件里的布尔值获取后一直为fa…

5。STM32裸机开发(4)

嵌入式软件开发学习过程记录&#xff0c;本部分结合本人的学习经验撰写&#xff0c;系统描述各类基础例程的程序撰写逻辑。构建裸机开发的思维&#xff0c;为RTOS做铺垫&#xff08;本部分基于库函数版实现&#xff09;&#xff0c;如有不足之处&#xff0c;敬请批评指正。 &…