opencv基础48-绘制图像轮廓并切割示例-cv2.drawContours()

绘制图像轮廓:drawContours函数

在 OpenCV 中,可以使用函数 cv2.drawContours()绘制图像轮廓。该函数的语法格式是:

image=cv2.drawContours( image, contours, contourIdx, color[,
thickness[, lineType[, hierarchy[, maxLevel[, offset]]]]] )

其中,函数的返回值为 image,表示目标图像,即绘制了边缘的原始图像。
该函数有如下参数:

  1. image:待绘制轮廓的图像。需要注意,函数 cv2.drawContours()会在图像 image 上直接绘制轮廓。也就是说,在函数执行完以后,image 不再是原始图像,而是包含了轮廓的图像。因此,如果图像 image 还有其他用途的话,则需要预先复制一份,将该副本图像传递给函cv2.drawContours()使用。

  2. contours:需要绘制的轮廓。该参数的类型与函数 cv2.findContours()的输出 contours 相同,都是 list 类型。

  3. contourIdx:需要绘制的边缘索引,告诉函数 cv2.drawContours()要绘制某一条轮廓还是全部轮廓。如果该参数是一个整数或者为零,则表示绘制对应索引号的轮廓;如果该值
    为负数(通常为“-1”),则表示绘制全部轮廓。

  4. color:绘制的颜色,用 BGR 格式表示。

  5. thickness:可选参数,表示绘制轮廓时所用画笔的粗细。如将该值设置为“-1”,则表示
    要绘制实心轮廓。

  6. lineType:可选参数,表示绘制轮廓时所用的线型。

  7. hierarchy:对应函数 cv2.findContours()所输出的层次信息。

  8. maxLevel:控制所绘制的轮廓层次的深度。如果值为 0,表示仅仅绘制第 0 层的轮廓;如果值为其他的非零正数,表示绘制最高层及以下的相同数量层级的轮廓。

  9. offset:偏移参数。该参数使轮廓偏移到不同的位置展示出来。

函数 cv2.drawContours()的参数 image 和返回值 image,在函数运算后的值是相同的。因此,也可以将函数 cv2.drawContours()写为没有返回值的形式:

cv2.drawContours( image, contours, contourIdx, color[, thickness[,
lineType[, hierarchy[, maxLevel[, offset]]]]] )

代码示例:绘制一幅图像内的所有轮廓。

如果要绘制图像内的所有轮廓,需要将函数 cv2.drawContours()的参数 contourIdx 的值设置为“-1”。
实验原图上一节中有可下载
代码如下:

import cv2
o = cv2.imread('contours.bmp')
cv2.imshow("original",o)
#将原图像转换为灰度图像
gray = cv2.cvtColor(o,cv2.COLOR_BGR2GRAY)
#将灰度图像转换为二值图像
ret, binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
#寻找轮廓,返回的contours是轮廓的列表,hierarchy是每个轮廓对应的属性
contours, hierarchy = cv2.findContours(binary,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
#绘制轮廓,contours是轮廓的列表,-1表示绘制所有轮廓,(0,0,255)表示轮廓颜色为红色,5表示轮廓宽度为5
o=cv2.drawContours(o,contours,-1,(0,0,255),5)
cv2.imshow("result",o)
cv2.waitKey()
cv2.destroyAllWindows()

运行效果如下:

在这里插入图片描述
在本程序中,轮廓的颜色被设置为红色(由于黑白印刷的原因,在纸质书中显示为灰色),
即(0, 0, 255),参数 thickness(轮廓线条的粗细)被设置为“5”。

示例2 逐个切割一幅图像内的边缘信息。

import cv2
import numpy as np
o = cv2.imread('contours.bmp')
#显示原始图像
cv2.imshow("original",o)
#将原图像转换为灰度图像
gray = cv2.cvtColor(o,cv2.COLOR_BGR2GRAY)
#将灰度图像转换为二值图像
ret, binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
#寻找轮廓,返回的contours是轮廓的列表,hierarchy是每个轮廓对应的属性
contours, hierarchy = cv2.findContours(binary,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
#获取轮廓的数量
n=len(contours)
#对每个轮廓进行绘制
contoursImg=[]
for i in range(n):#创建空白画布temp=np.zeros(o.shape,np.uint8)contoursImg.append(temp)#绘制轮廓,contours是轮廓的列表,i表示绘制第i个轮廓,(255,255,255)表示轮廓颜色为白色,5表示轮廓宽度为5contoursImg[i]=cv2.drawContours(contoursImg[i],contours,i,(255,255,255),5)cv2.imshow("contours[" + str(i)+"]",contoursImg[i])
cv2.waitKey()
cv2.destroyAllWindows()

在这里插入图片描述
在这里插入图片描述

示例3:使用轮廓绘制功能,提取前景对象。

将函数 cv2.drawContours()的参数 thickness 的值设置为“-1”,可以绘制前景对象的实心轮廓。将该实心轮廓与原始图像进行“按位与”操作,即可将前景对象从原始图像中提取出来。

代码如下:

import cv2
import numpy as np
o = cv2.imread('loc3.jpg')
cv2.imshow("original",o)
gray = cv2.cvtColor(o,cv2.COLOR_BGR2GRAY)
ret, binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(binary,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
#创建空白画布
mask=np.zeros(o.shape,np.uint8)
#绘制轮廓,contours是轮廓的列表,-1表示绘制所有轮廓,(255,255,255)表示轮廓颜色为白色,-1表示轮廓宽度为-1,表示对轮廓进行填充
mask=cv2.drawContours(mask,contours,-1,(255,255,255),-1)
#显示掩膜
cv2.imshow("mask" ,mask)
#将原图像和掩膜进行位运算
loc=cv2.bitwise_and(o,mask)
cv2.imshow("location" ,loc)
cv2.waitKey()
cv2.destroyAllWindows()

本例中将函数 cv2.drawContours()的参数 thickness 设置为“-1”,得到了前景对象的实心轮
廓 mask。接下来,通过语句“cv2.bitwise_and(o, mask)”,将原始图像 o 与实心轮廓 mask 进行
“按位与”运算,就得到了原始图像的前景对象。

运行结果:

  • 左图是原始图像,其前景对象是一朵小花。
  • 中间的图像是从原始图像得到的小花的实心轮廓。
  • 右图是提取的前景对象小花。
    在这里插入图片描述
    在这里插入图片描述

实验原图
在这里插入图片描述

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

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

相关文章

c基础扫雷

和三子棋一样,主函数先设计游戏菜单界面,这里就不做展示了。 初始化棋盘 初级扫雷大小为9*9的棋盘,但排雷是周围一圈进行排雷(8格),而边界可能会越界。数组扩大了一圈,行和列都加了2,所以我们用一个11*11的数组来初始化…

计算机科技历史纵横:8月6日的十大里程碑

计算机科技历史纵横:8月6日的十大里程碑 目录 引言1951年:EDSAC电脑完成第一个实际计算任务1964年:IBM发布System/360系列1973年:Xerox PARC开发出第一台个人电脑Xerox Alto1976年:Apple发布Apple I电脑1981年&#…

UDS诊断笔记

文章目录 常见缩写简介UDS寻址模式1. 物理寻址(点对点、一对一)2. 功能寻址(广播、一对多)3. 功能寻址使用场景举例 UDS报文格式UDS协议栈网络层网络层功能网络层协议1. 单帧 SF(Single Frame)2. 首帧 FC&a…

教你一招:非计算机科班如何丝滑转码?

近年来,很多人想要从其他行业跳槽转入计算机领域。非计算机科班如何丝滑转码? 目录 一、确定方向 二、确定学习计划(自学) 三、学习 看到组里好多非科班姐妹决定转码之后,因为相关背景知识不足难以确定学习计划&am…

【机密计算-大厂有话说】微软 Open Enclave SDK

前言 机密计算是基于硬件支持的可信执行环境的,比如 Intel SGX 硬件技术上面的 enclave 以及 Arm Trustzone 上的 OT-TEE,不过这些异构的 TEE 之间差异还是蛮大的,所以亟需一种能够屏蔽 TEE 差异软件中间件或者 SDK,这就是本文将要…

JavaScript 中替换所有匹配项的自定义函数非正则表达式

引言 在 JavaScript 中,字符串替换是常见的操作之一。虽然 JavaScript 提供了一些内置的字符串方法来实现替换,比如 replace() 方法,但它只会替换第一个匹配到的项。如果我们想要替换所有匹配到的项,就需要自己编写一个函数。本文…

生成测试报告,在Unittest框架中就是简单

测试套件(Test Suite)是测试用例、测试套件或两者的集合,用于组装一组要运行的测试(多个测试用例集合在一起)。 (1)创建一个测试套件: import unittest suite unittest.TestSuite…

面向开发人员的 Spring Boot 最佳实践

Spring Boot是一种广泛使用且非常流行的企业级高性能框架。以下是一些最佳实践和一些技巧,您可以使用它们来改进 Spring Boot 应用程序并使其更加高效。这篇文章会有点长,完整读完文章需要一些时间。 正确的包装风格 正确的打包将有助于轻松理解代码和…

STL模板——vector详解

一、vector对象的定义和初始化方式 vector 中的数据类型 T 可以代表任何数据类型,如 int、string、class、vector(构建多维数组) 等,就像一个可以放下任何东西的容器,因此 vector 也常被称作容器。字符串类型 string …

ElasticSearch索引生命周期管理--DELETE

概要 ElasticSearch中的索引生命周期管理,也就是ilm(Manage the index lifecycle),是指定了索引在不同周期下的处理策略。ilm 的对象是索引而不是索引中的数据。ilm 包括四个阶段:hot 、warm、cold和delete。hot、warm和cold表示…

【VUE】项目本地开启https访问模式(vite4)

在实际开发中,有时候需要项目以https形式进行页面访问/调试,下面介绍下非vue-cli创建的vue项目如何开启https 环境 vue: ^3.2.47vite: ^4.1.4 根据官方文档:开发服务器选项 | Vite 官方中文文档 ps:首次操作,不要被类…

Pyspark

2、DataFrame 2.1 介绍 在Spark语义中,DataFrame是一个分布式的行集合,可以想象为一个关系型数据库的表,或者一个带有列名的Excel表格。它和RDD一样,有这样一些特点: Immuatable:一旦RDD、DataFrame被创…

ssm+vue基于java的少儿编程网上报名系统源码和论文PPT

ssmvue基于java的少儿编程网上报名系统源码和论文PPT006 开发工具:idea 数据库mysql5.7(mysql5.7最佳) 数据库链接工具:navcat,小海豚等 开发技术:java ssm tomcat8.5 摘 要 在国家重视教育影响下,教育部门的密确配合下&#…

沐渥六门氮气柜技术参数详解

氮气柜是用来存储电子元器件、芯片、半导体器件、金属材料、电路板、精密仪器等物品的设备,通过充入氮气降低柜内湿度,达到防潮、防氧化、防静电、防锈和防霉效果。 六门氮气柜参数 1、容积:约1380L;外尺寸:W1200*D700…

一零六八、回顾MySQL关键字排序

一、 关键字书写顺序 select distinct from join on where group by having union (all) order by limit二、 关键字实际执行顺序 from on join where group by having select distinct union (all) order by limit个人理解&…

100G光模块的应用案例分析:电信、云计算和大数据领域

100G光模块是一种高速光模块,由于其高速率和低延迟的特性,在电信、云计算和大数据领域得到了广泛的应用。在本文中,我们将深入探讨100G光模块在这三个领域的应用案例。 一、电信领域 在电信领域,100G光模块被广泛用于构建高速通…

QT- QLineEdite设置自动补全功能,并修改自动补全的样式

#include <QApplication> #include <QLineEdit> #include <QCompleter> #include <QStringListModel> #include <QMainWindow>int main(int argc, char *argv[]) {QApplication app(argc, argv);// 创建一个字符串列表模型QStringListModel mode…

python流程控制语句学习笔记

if语句的使用 一、if判断语句介绍 if语句是用来进行判断的&#xff0c;其使用格式如下&#xff1a; if 要判断的条件: 条件成立时&#xff0c;要做的事情 demo1: age 30 print("------if判断开始------") if age > 18: print("我已经成年了") print…

HTML 元素中的name 属性

name 属性是 HTML 元素中常用的属性之一。它用于指定表单元素的名称&#xff0c;以便在提交表单时将其值与对应的键关联起来。 每个表单元素&#xff08;例如 <input>、<select> 和 <textarea>&#xff09;都可以具有一个 name 属性&#xff0c;该属性为元素…