OpenCV-python numpy和基本作图

文章目录

  • 一、实验目的
  • 二、实验内容
  • 三、实验过程
    • Numpy
      • 1.NumPy 操作
      • 2.NumPy Ndarray 对象
      • 3.NumPy 基本类型
      • 4.NumPy 数组属性
        • ndarray.ndim
        • ndarray.shape
        • ndarray.itemsize
        • ndarray.flags
      • 5.NumPy 创建数组
        • numpy.empty
        • numpy.zeros
        • numpy.ones
      • 6.NumPy 从已有的数组创建数组
        • numpy.asarray
        • numpy.frombuffer
        • numpy.fromiter
      • 7.NumPy 从数值范围创建数组
        • numpy.arange
        • numpy.linspace
        • numpy.logspace
      • 8.NumPy 切片和索引
      • 9.NumPy 高级索引
        • 整数数组索引
        • 布尔索引
      • 10.NumPy 迭代数组
        • 修改数组中元素的值
        • 使用外部循环
      • 11.Numpy数组操作
        • 修改数组形状
        • numpy.reshape
        • numpy.ndarray.flatten
        • numpy.ravel
        • numpy.transpose
        • numpy.rollaxis
        • numpy.swapaxes
    • 准备工作
      • 小插曲
      • numpy包
    • 图像处理
      • 颜色转换
      • 画矩形
      • 画圆
      • 画椭圆
      • 画线段
      • 画和填充多边形
      • 绘制文字
      • 为图像添加边框
      • 轮廓检测和画出轮廓
  • 四、实验结果
  • 五、实验结论

一、实验目的

本实验是利用python中的numpy库中的函数,对数组进行各种各样的操作和对图像进行各种操作。对数组进行的操作包括熟悉numpy的基本操作——学习如何创建、访问和修改NumPy数组,了解数组的属性和方法;学习如何改变数组的形状,例如改变维度、转置数组、重塑数组等;还有学习如何使用NumPy的索引和切片操作,对数组进行元素的访问和修改。对图像的操作包括学习如何实现颜色变换、画基本图形、文字绘制、为图像添加边框以及在图像中查找轮廓。通过该实验,可以帮助我们掌握numpy的基本操作和常用函数,理解数组的概念和运算;同时可以深入了解OpenCV图像处理模块的功能和应用,并对不同的图像处理算法和技术有所了解,实验过程也可以帮助我更加熟悉OpenCV提供的函数和方法,为将来在计算机视觉和图像处理领域的实际应用中打下基础。

二、实验内容

1.numpy基本操作

2.基本图形的绘制

三、实验过程

Numpy

NumPy - 简介

NumPy 是一个 Python 包。 它代表 “Numeric Python”。 它是一个由多维数组对象和用于处理数组的例程集合组成的库。

Numeric,即 NumPy 的前身,是由 Jim Hugunin 开发的。 也开发了另一个包 Numarray ,它拥有一些额外的功能。 2005年,Travis Oliphant 通过将 Numarray 的功能集成到 Numeric 包中来创建 NumPy 包。 这个开源项目有很多贡献者。

1.NumPy 操作

使用NumPy,开发人员可以执行以下操作:

  • 数组的算数和逻辑运算。

  • 傅立叶变换和用于图形操作的例程。

  • 与线性代数有关的操作。 NumPy 拥有线性代数和随机数生成的内置函数。

2.NumPy Ndarray 对象

NumPy 最重要的一个特点是其 N 维数组对象 ndarray,它是一系列同类型数据的集合,以 0 下标为开始进行集合中元素的索引。

ndarray 对象是用于存放同类型元素的多维数组。

ndarray 中的每个元素在内存中都有相同存储大小的区域。

ndarray 内部由以下内容组成:

  • 一个指向数据(内存或内存映射文件中的一块数据)的指针。

  • 数据类型或 dtype,描述在数组中的固定大小值的格子。

  • 一个表示数组形状(shape)的元组,表示各维度大小的元组。

  • 一个跨度元组(stride),其中的整数指的是为了前进到当前维度下一个元素需要"跨过"的字节数。

ndarray 的内部结构:
ndarray

跨度可以是负数,这样会使数组在内存中后向移动,切片中 obj[::-1] 或 obj[:,::-1] 就是如此。

创建一个 ndarray 只需调用 NumPy 的 array 函数即可:

名称描述
object数组或嵌套的数列
dtype数组元素的数据类型,可选
copy对象是否需要复制,可选
order创建数组的样式,C为行方向,F为列方向,A为任意方向(默认)
subok默认返回一个与基类类型一致的数组
ndmin指定生成数组的最小维度NumPy 数据类型

numpy 支持的数据类型比 Python 内置的类型要多很多,基本上可以和 C 语言的数据类型对应上,其中部分类型对应为 Python 内置的类型。下表列举了常用

3.NumPy 基本类型

名称描述
bool_布尔型数据类型(True 或者 False)
int_默认的整数类型(类似于 C 语言中的 long,int32 或 int64)
intc与 C 的 int 类型一样,一般是 int32 或 int 64
intp用于索引的整数类型(类似于 C 的 ssize_t,一般情况下仍然是 int32 或 int64)
int8字节(-128 to 127)
int16整数(-32768 to 32767)
int32整数(-2147483648 to 2147483647)
int64整数(-9223372036854775808 to 9223372036854775807)
uint8无符号整数(0 to 255)
uint16无符号整数(0 to 65535)
uint32无符号整数(0 to 4294967295)
uint64无符号整数(0 to 18446744073709551615)
float_float64 类型的简写
float16半精度浮点数,包括:1 个符号位,5 个指数位,10 个尾数位
float32单精度浮点数,包括:1 个符号位,8 个指数位,23 个尾数位
float64双精度浮点数,包括:1 个符号位,11 个指数位,52 个尾数位
complex_complex128 类型的简写,即 128 位复数
complex64复数,表示双 32 位浮点数(实数部分和虚数部分)
complex128复数,表示双 64 位浮点数(实数部分和虚数部分)

numpy 的数值类型实际上是 dtype 对象的实例,并对应唯一的字符,包括 np.bool_,np.int32,np.float32,等等。

4.NumPy 数组属性

本章节我们将来了解 NumPy 数组的一些基本属性。

NumPy 数组的维数称为秩(rank),秩就是轴的数量,即数组的维度,一维数组的秩为 1,二维数组的秩为 2,以此类推。

在 NumPy中,每一个线性的数组称为是一个轴(axis),也就是维度(dimensions)。比如说,二维数组相当于是两个一维数组,其中第一个一维数组中每个元素又是一个一维数组。所以一维数组就是 NumPy 中的轴(axis),第一个轴相当于是底层数组,第二个轴是底层数组里的数组。而轴的数量——秩,就是数组的维数。

很多时候可以声明 axis。axis=0,表示沿着第 0 轴进行操作,即对每一列进行操作;axis=1,表示沿着第1轴进行操作,即对每一行进行操作。

NumPy 的数组中比较重要 ndarray 对象属性有:

属性说明
ndarray.ndim秩,即轴的数量或维度的数量
ndarray.shape数组的维度,对于矩阵,n 行 m 列
ndarray.size数组元素的总个数,相当于 .shape 中 n*m 的值
ndarray.dtypendarray 对象的元素类型
ndarray.itemsizendarray 对象中每个元素的大小,以字节为单位
ndarray.flagsndarray 对象的内存信息
ndarray.realndarray元素的实部
ndarray.imagndarray 元素的虚部
ndarray.data包含实际数组元素的缓冲区,由于一般通过数组的索引获取元素,所以通常不需要使用这个属性。
ndarray.ndim

ndarray.ndim 用于返回数组的维数,等于秩。

ndarray.shape

ndarray.shape 表示数组的维度,返回一个元组,这个元组的长度就是维度的数目,即 ndim 属性(秩)。比如,一个二维数组,其维度表示"行数"和"列数"。

ndarray.shape 也可以用于调整数组大小。

ndarray.itemsize

ndarray.itemsize 以字节的形式返回数组中每一个元素的大小。

例如,一个元素类型为 float64 的数组 itemsize 属性值为 8(float64 占用 64 个 bits,每个字节长度为 8,所以 64/8,占用 8 个字节),又如,一个元素类型为 complex32 的数组 item 属性为 4(32/8)。

ndarray.flags

ndarray.flags 返回 ndarray 对象的内存信息

5.NumPy 创建数组

ndarray 数组除了可以使用底层 ndarray 构造器来创建外,也可以通过以下几种方式来创建。

numpy.empty

numpy.empty 方法用来创建一个指定形状(shape)、数据类型(dtype)且未初始化的数组:

numpy.empty(shape, dtype = float, order = ‘C’)

参数说明:

参数描述
shape数组形状
dtype数据类型,可选
order有"C"和"F"两个选项,分别代表,行优先和列优先,在计算机内存中的存储元素的顺序。
numpy.zeros

创建指定大小的数组,数组元素以 0 来填充:

numpy.zeros(shape, dtype = float, order = ‘C’)

参数说明:

参数描述
shape数组形状
dtype数据类型,可选
order‘C’ 用于 C 的行数组,或者 ‘F’ 用于 FORTRAN 的列数组
numpy.ones

创建指定形状的数组,数组元素以 1 来填充:

numpy.ones(shape, dtype = None, order = ‘C’)

参数说明:

参数描述
shape数组形状
dtype数据类型,可选
order‘C’ 用于 C 的行数组,或者 ‘F’ 用于 FORTRAN 的列数组

6.NumPy 从已有的数组创建数组

本章节我们将学习如何从已有的数组创建数组。

numpy.asarray

numpy.asarray 类似 numpy.array,但 numpy.asarray 参数只有三个,比 numpy.array 少两个。

numpy.asarray(a, dtype = None, order = None)

参数说明:

参数描述
a任意形式的输入参数,可以是,列表, 列表的元组, 元组, 元组的元组, 元组的列表,多维数组
dtype数据类型,可选
order可选,有"C"和"F"两个选项,分别代表,行优先和列优先,在计算机内存中的存储元素的顺序。
numpy.frombuffer

numpy.frombuffer 用于实现动态数组。

numpy.frombuffer 接受 buffer 输入参数,以流的形式读入转化成 ndarray 对象。

numpy.frombuffer(buffer, dtype = float, count = -1, offset = 0)

**注意:**buffer 是字符串的时候,Python3 默认 str 是 Unicode 类型,所以要转成 bytestring 在原 str 前加上 b。

参数说明:

参数描述
buffer可以是任意对象,会以流的形式读入。
dtype返回数组的数据类型,可选
count读取的数据数量,默认为-1,读取所有数据。
offset读取的起始位置,默认为0。
numpy.fromiter

numpy.fromiter 方法从可迭代对象中建立 ndarray 对象,返回一维数组。

numpy.fromiter(iterable, dtype, count=-1)

参数描述
iterable可迭代对象
dtype返回数组的数据类型
count读取的数据数量,默认为-1,读取所有数据

7.NumPy 从数值范围创建数组

这一章节我们将学习如何从数值范围创建数组。

numpy.arange

numpy 包中的使用 arange 函数创建数值范围并返回 ndarray 对象,函数格式如下:

numpy.arange(start, stop, step, dtype)

根据 start 与 stop 指定的范围以及 step 设定的步长,生成一个 ndarray。

参数说明:

参数描述
start起始值,默认为0
stop终止值(不包含)
step步长,默认为1
dtype返回ndarray的数据类型,如果没有提供,则会使用输入数据的类型。
numpy.linspace

numpy.linspace 函数用于创建一个一维数组,数组是一个等差数列构成的,格式如下:

np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)

参数说明:

参数描述
start序列的起始值
stop序列的终止值,如果endpointtrue,该值包含于数列中
num要生成的等步长的样本数量,默认为50
endpoint该值为 true 时,数列中包含stop值,反之不包含,默认是True。
retstep如果为 True 时,生成的数组中会显示间距,反之不显示。
dtypendarray 的数据类型
numpy.logspace

numpy.logspace 函数用于创建一个于等比数列。格式如下:

np.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None)

base 参数意思是取对数的时候 log 的下标。

参数描述
start序列的起始值为:base ** start
stop序列的终止值为:base ** stop。如果endpointtrue,该值包含于数列中
num要生成的等步长的样本数量,默认为50
endpoint该值为 true 时,数列中中包含stop值,反之不包含,默认是True。
base对数 log 的底数。
dtypendarray 的数据类型

8.NumPy 切片和索引

ndarray对象的内容可以通过索引或切片来访问和修改,与 Python 中 list 的切片操作一样。ndarray 数组可以基于 0 - n 的下标进行索引,切片对象可以通过内置的 slice 函数,并设置 start, stop 及 step 参数进行,从原数组中切割出一个新数组。实例 import numpy as np a = np.arange(10) s = slice(2,7,2) # 从索引 2 开始到索引 7 停止,间隔为2 print (a[s])

输出结果为:

[2 4 6]

以上实例中,我们首先通过 arange() 函数创建 ndarray 对象。 然后,分别设置起始,终止和步长的参数为 2,7 和 2。

我们也可以通过冒号分隔切片参数 start:stop:step 来进行切片操作:实例 import numpy as np a = np.arange(10) b = a[2:7:2] # 从索引 2 开始到索引 7 停止,间隔为 2 print(b)

输出结果为:

[2 4 6]

冒号 : 的解释:如果只放置一个参数,如 [2],将返回与该索引相对应的单个元素。如果为 [2:],表示从该索引开始以后的所有项都将被提取。如果使用了两个参数,如 [2:7],那么则提取两个索引(不包括停止索引)之间的项。实例 import numpy as np a = np.arange(10) # [0 1 2 3 4 5 6 7 8 9] b = a[5] print(b)

输出结果为:5

9.NumPy 高级索引

NumPy 比一般的 Python 序列提供更多的索引方式。

除了之前看到的用整数和切片的索引外,数组可以由整数数组索引、布尔索引及花式索引。

NumPy 中的高级索引指的是使用整数数组、布尔数组或者其他序列来访问数组的元素。相比于基本索引,高级索引可以访问到数组中的任意元素,并且可以用来对数组进行复杂的操作和修改。

整数数组索引

整数数组索引是指使用一个数组来访问另一个数组的元素。这个数组中的每个元素都是目标数组中某个维度上的索引值。

以下实例获取数组中 (0,0),(1,1)(2,0) 位置处的元素

实例 import numpy as np x = np.array([[1, 2], [3, 4], [5, 6]]) y = x[[0,1,2], [0,1,0]] print (y)

输出结果为:

[1 4 5]

布尔索引

我们可以通过一个布尔数组来索引目标数组。

布尔索引通过布尔运算(如:比较运算符)来获取符合指定条件的元素的数组。

以下实例获取大于 5 的元素:

实例 import numpy as np x = np.array([[ 0, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]]) print (‘我们的数组是:’) print (x) print (‘\n’) # 现在我们会打印出大于 5 的元素 print (‘大于 5 的元素是:’) print (x[x > 5])

输出结果为:

我们的数组是:[[ 0 1 2] [ 3 4 5] [ 6 7 8] [ 9 10 11]]

大于 5 的元素是:[ 6 7 8 9 10 11]

10.NumPy 迭代数组

NumPy 迭代器对象 numpy.nditer 提供了一种灵活访问一个或者多个数组元素的方式。

迭代器最基本的任务的可以完成对数组元素的访问。

接下来我们使用 arange() 函数创建一个 2X3 数组,并使用 nditer 对它进行迭代。

实例 import numpy as np a = np.arange(6).reshape(2,3) print (‘原始数组是:’) print (a) print (‘\n’) print (‘迭代输出元素:’) for x in np.nditer(a): print (x, end=", " ) print (‘\n’)

输出结果 原始数组是: [[0 1 2] [3 4 5]] 迭代输出元素: 0, 1, 2, 3, 4, 5,

修改数组中元素的值

nditer 对象有另一个可选参数 op_flags。 默认情况下,nditer 将视待迭代遍历的数组为只读对象(read-only),为了在遍历数组的同时,实现对数组元素值的修改,必须指定 readwrite 或者 writeonly 的模式。

实例 import numpy as np a = np.arange(0,60,5) a = a.reshape(3,4) print (‘原始数组是:’) print (a) print (‘\n’) for x in np.nditer(a, op_flags=[‘readwrite’]): x[…]=2*x print (‘修改后的数组是:’) print (a)

输出结果为: 原始数组是:[[ 0 5 10 15] [20 25 30 35] [40 45 50 55]] 修改后的数组是:[[ 0 10 20 30] [ 40 50 60 70] [ 80 90 100 110]]

使用外部循环

nditer 类的构造器拥有 flags 参数,它可以接受下列值:

参数描述
c_index可以跟踪 C 顺序的索引
f_index可以跟踪 Fortran 顺序的索引
multi_index每次迭代可以跟踪一种索引类型
external_loop给出的值是具有多个值的一维数组,而不是零维数组
    import numpy as np 
    a = np.arange(0,60,5) 
    a = a.reshape(3,4)  
    print ('原始数组是:')
    print (a)
    print ('\n')
    print ('修改后的数组是:')
    for x in np.nditer(a, flags =  ['external_loop'], order =  'F'):  
       print (x, end=", " )

输出结果: 原始数组是: [[ 0 5 10 15] [20 25 30 35] [40 45 50 55]] 修改后的数组是: [ 0 20 40], [ 5 25 45], [10 30 50], [15 35 55],

11.Numpy数组操作

修改数组形状
函数描述
reshape不改变数据的条件下修改形状
flat数组元素迭代器
flatten返回一份数组拷贝,对拷贝所做的修改不会影响原始数组
ravel返回展开数组
numpy.reshape

numpy.reshape 函数可以在不改变数据的条件下修改形状,格式如下:

numpy.reshape(arr, newshape, order=‘C’)

  • arr:要修改形状的数组
  • newshape:整数或者整数数组,新的形状应当兼容原有形状
  • order:‘C’ – 按行,‘F’ – 按列,‘A’ – 原顺序,‘k’ – 元素在内存中的出现顺序
numpy.ndarray.flatten

numpy.ndarray.flatten 返回一份数组拷贝,对拷贝所做的修改不会影响原始数组,格式如下:

ndarray.flatten(order=‘C’)

numpy.ravel

numpy.ravel() 展平的数组元素,顺序通常是"C风格",返回的是数组视图(view,有点类似 C/C++引用reference的意味),修改会影响原始数组。

该函数接收两个参数:

numpy.ravel(a, order=‘C’)

参数说明:

  • order:‘C’ – 按行,‘F’ – 按列,‘A’ – 原顺序,‘K’ – 元素在内存中的出现顺序。

翻转数组

函数描述
transpose对换数组的维度
ndarray.Tself.transpose() 相同
rollaxis向后滚动指定的轴
swapaxes对换数组的两个轴
numpy.transpose

numpy.transpose 函数用于对换数组的维度,格式如下:

numpy.transpose(arr, axes)

参数说明:

  • arr:要操作的数组
  • axes:整数列表,对应维度,通常所有维度都会对换。
numpy.rollaxis

numpy.rollaxis 函数向后滚动特定的轴到一个特定位置,格式如下:

numpy.rollaxis(arr, axis, start)

参数说明:

  • arr:数组
  • axis:要向后滚动的轴,其它轴的相对位置不会改变
  • start:默认为零,表示完整的滚动。会滚动到特定位置。
numpy.swapaxes

numpy.swapaxes 函数用于交换数组的两个轴,格式如下:

numpy.swapaxes(arr, axis1, axis2)

  • arr:输入的数组
  • axis1:对应第一个轴的整数
  • axis2:对应第二个轴的整数

准备工作

安装pycharm和需要的软件包来进行代码的编辑
在这里插入图片描述

直接编辑代码导入,然后进行包的下载

小插曲

下载包的时候一直报错

去查询了一下报错原因pip安装报403错误 解决方法

于是我就把镜像地址又改了回来

pip config set global.index-url https://pypi.python.org/simple/

当然最后我检查了,大概不是清华园的问题(也可能是)

是pycharm本身的pip没有更新的问题

在这里更新完后就没有这个问题了,不用更改清华园的镜像
在这里插入图片描述
可以先更新一下项目pip,如果还是不对,就把镜像地址改回来

numpy包

这里numpy是在python处理大数据学过的一个库

对应OpenCv来说

使用Python运行OpenCV的程序时,OpenCV使用NumPy数组存储图像数据。基于NumPy可以很方便的执行基于数组的图像运算,比如图像的加法运算、加权加法运算和位运算等。

图像处理

颜色转换

cvtColor函数

dst=cv2.cvtColor(src,code[, dst[, dstCn]])

其中

dst(destination)就表示我们经过函数处理后得到的目的图像,此时是矩阵形式;

src(source)表示我们要进行转换的源图像对象,也是矩阵形式

code是opencv中色彩空间定义的宏常量,展示了我们要图像转换所要达到的结果,常用的有COLOR_BGR2GRAY、COLOR_GRAY2BGR、COLOR_BGR2HSV、COLOR_BGR2RGB等,但是实际上可以调用的参数多达247种。

dstCn为目标图像的通道数,如果设置为0,会自动从源图像计算目标图像的通道数;

以下是代码实例

    from numpy import *
    import numpy as np
    import cv2
    
    # 将图片转为灰度图
    src_image = cv2.imread("test.jpg")
    gray_imagee = cv2.cvtColor(src_image, cv2.COLOR_BGR2GRAY)
    # 将图片转为HSV
    hsv_image = cv2.cvtColor(src_image, cv2.COLOR_BGR2HSV)
    # 展示一下
    cv2.imshow("src_image", src_image)
    cv2.imshow("gary_image", gray_imagee)
    cv2.imshow("hsv_image", hsv_image)
    cv2.waitKey(0)

src_iamge
在这里插入图片描述

hsv_image

在这里插入图片描述

gary_iamge

在这里插入图片描述

这样显示在显示器有点大,也可以写入

通过cv2.imwrite(“1.jpg”,hsv_iamge)函数来进行文件的保存然后查看会好一点

画矩形

rectangle()用法:

    cv2.rectangle(img, pt1, pt2, color, thickness, lineType, shift)

参数说明:

  • img:在哪个图像上画线

  • pt1, pt2:开始点, 结束点:指定线的开始与结束位置

  • color:颜色

    • (0, 0, 255):红

    • (0, 255, 0):绿

    • (255, 0, 0):蓝

  • thickness:线宽

  • lineType:线型(可取值-1, 4, 8, 18), 默认为8

  • shift:坐标缩放比例

代码

    # 画矩形
    img = np.zeros((480, 640, 3), np.uint8)
    
    cv2.rectangle(img, (20, 20), (400, 400), (0, 255, 0), 5)
    
    cv2.imshow('draw', img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

效果展示

在这里插入图片描述

画圆

circle()用法:

cv2.circle()(img, center, radius, color, thickness, lineType, shift)

参数说明:

  • img:在哪个图像上绘制圆

  • center:圆心坐标

  • radius:半径大小

  • color:颜色

  • thickness:线宽

  • lineType:线型

  • shift:坐标缩放比例

代码

    # 画圆
    img = np.zeros((480, 640, 3), np.uint8)
    
    cv2.circle(img, (320, 240), 100, (255, 0, 0), 5, 16)
    
    cv2.imshow('draw', img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

效果展示

在这里插入图片描述

画椭圆

ellipse()用法:

cv2.ellipse(img, center, axes, angle, startAngle, endAngle, color, thickness, lineType, shift)

参数说明:

  • img:在哪个图像上绘制椭圆

  • center:中心点

  • axes:长宽的一半

  • angle:角度

  • startAngle:从哪个角度开始

  • endAngle:从哪个角度结束

  • color:颜色

  • thickness:线宽

  • lineType:线型

  • shift:坐标缩放比例

代码

    # 画椭圆
    img = np.zeros((480, 640, 3), np.uint8)
    
    cv2.ellipse(img, (320, 240), (100, 50), 0, 0, 360, (255, 255, 255), 5, 16)
    
    cv2.imshow('draw', img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

效果展示
在这里插入图片描述

画线段

line()用法:

cv2.line(img, pt1, pt2, color, thickness, lineType, shift)

参数说明:

line()用法rectangle()用法 完全一致。

代码

    # 画线段
    img = np.zeros((480, 640, 3), np.uint8)
    
    # 划线, 坐标点(x, y)
    cv2.line(img, (20, 20), (400, 400), (0, 0, 255), 5, 16)
    
    cv2.imshow('draw', img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

效果展示

在这里插入图片描述

画和填充多边形

polylines():绘制多边形

cv2.polylines(img, pts, isClosed, color, thickness, lineType, shift)

参数说明:

  • img:在哪个图像上绘制和填充多边形

  • pts:多边形的点集,必须是int32位

  • isClosed:是否闭合

  • color:颜色

  • thickness:线宽

  • lineType:线型

  • shift:坐标缩放比例

代码

    img = np.zeros((480, 640, 3), np.uint8)
    
    pts = np.array([(300, 10), (150, 100), (450, 100)], np.int32)
    cv2.polylines(img, [pts], True, (0, 255, 255), 5, 16)
    
    cv2.imshow('draw', img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

效果展示

在这里插入图片描述

fillPoly:填充多边形

cv2.fillPoly(img, pts, color)

fillPoly用法polylines用法 完全一致。

代码

    img = np.zeros((480, 640, 3), np.uint8)
    
    pts = np.array([(300, 10), (150, 100), (450, 100)], np.int32)
    cv2.fillPoly(img, [pts], (0, 255, 255), 16)
    
    cv2.imshow('draw', img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

效果展示

在这里插入图片描述

绘制文字

putText:绘制文字

    putText(img,text,org,fontFace,fontScale,color,thickness,lineType,bottomLeftOrigin)

参数说明:

  • text要绘制的文字内容

  • org 文字在画布中的左下角坐标

  • fontFace 字体样式

  • fontScale 字体大小

  • lineType 线型

  • bottomLeftOrigin 绘制文字时的方向

代码

    import numpy as np # 导入Python中的numpy模块
    import cv2
    
    # np.zeros():创建了一个画布
    # (100, 300, 3):一个100 x 300,具有3个颜色空间(即Red、Green和Blue)的画布
    # np.uint8:OpenCV中的灰度图像和RGB图像都是以uint8存储的,因此这里的类型也是uint8
    canvas = np.zeros((100, 300, 3), np.uint8)
    # 在画布上绘制文字“mrsoft”,文字左下角的坐标为(20, 70)
    # 字体样式为FONT_HERSHEY_TRIPLEX
    # 字体大小为2,线条颜色是绿色,线条宽度为5
    cv2.putText(canvas, "sorry", (20, 70), cv2.FONT_HERSHEY_TRIPLEX, 2, (0, 255, 0), 5)
    cv2.imshow("Text", canvas) # 显示画布
    cv2.waitKey()
    cv2.destroyAllWindows()

效果展示

在这里插入图片描述

为图像添加边框

copyMakeBorder:为图像添加边框

    cv.copyMakeBorder(src, top, bottom, left, right, borderType, None, value)

参数说明:

  • src: 即将被扩充边界的原始图像

  • top, bottom, left, right: 在图像上、下、左、右分别要扩充的行(列)数

  • borderType: 扩充的边界类型

    • cv2.BORDER_CONSTANT: 用常数像素值填充扩充的边界(0或黑色)

    • cv2.BORDER_REPLICATE: 原始边缘的行或列被复制到扩充的边界

  • value: 当使用cv.BORDER_CONSTANT时,设置的要填充的像素值

代码

    import cv2
    import numpy as np
    from matplotlib import pyplot as plt
    
    BLUE = [255, 0, 0]
    img1 = cv2.imread('test.jpg')
    
    replicate = cv2.copyMakeBorder(img1, 100, 100, 100, 100, cv2.BORDER_REPLICATE)
    reflect = cv2.copyMakeBorder(img1, 100, 100, 100, 100, cv2.BORDER_REFLECT)
    reflect101 = cv2.copyMakeBorder(img1, 100, 100, 100, 100, cv2.BORDER_REFLECT_101)
    wrap = cv2.copyMakeBorder(img1, 100, 100, 100, 100, cv2.BORDER_WRAP)
    constant = cv2.copyMakeBorder(img1, 100, 100, 100, 100, cv2.BORDER_CONSTANT, value=BLUE)
    
    plt.subplot(231), plt.imshow(img1, 'gray'), plt.title('ORIGINAL')
    plt.subplot(232), plt.imshow(replicate, 'gray'), plt.title('REPLICATE')
    plt.subplot(233), plt.imshow(reflect, 'gray'), plt.title('REFLECT')
    plt.subplot(234), plt.imshow(reflect101, 'gray'), plt.title('REFLECT_101')
    plt.subplot(235), plt.imshow(wrap, 'gray'), plt.title('WRAP')
    plt.subplot(236), plt.imshow(constant, 'gray'), plt.title('CONSTANT')
    plt.show()

效果展示

在这里插入图片描述

轮廓检测和画出轮廓

findContours:轮廓检测:

contours,hierarchy =cv2.findContours(image, mode, method[, contours[, hierarchy[, offset ]]])  

参数说明:

  • image:参数是寻找轮廓的图像;

  • mode:参数表示轮廓的检索模式,有四种(本文介绍的都是新的cv2接口):

    • cv2.RETR_EXTERNAL:表示只检测外轮廓

    • cv2.RETR_LIST:检测的轮廓不建立等级关系

    • cv2.RETR_CCOMP:建立两个等级的轮廓,上面的一层为外边界,里面的一层为内孔的边界信息。如果内孔内还有一个连通物体,这个物体的边界也在顶层。

    • cv2.RETR_TREE:建立一个等级树结构的轮廓。

  • method:轮廓的近似办法:

    • cv2.CHAIN_APPROX_NONE:存储所有的轮廓点,相邻的两个点的像素位置差不超过1,即max(abs(x1-x2),abs(y2-y1))==1

    • cv2.CHAIN_APPROX_SIMPLE:压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标,例如一个矩形轮廓只需4个点来保存轮廓信息

    • cv2.CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS:使用teh-Chinl chain 近似算法

返回值:

cv2.findContours()函数返回两个值,一个是轮廓本身,还有一个是每条轮廓对应的属性。

  • contour返回值: 返回一个list,list中每个元素都是图像中的一个轮廓,用numpy中的ndarray表示。

  • hierarchy返回值: 返回一个ndarray,其中的元素个数和轮廓个数相同,每个轮廓 c o n t o u r s [ i ] contours[i] contours[i]对应4个hierarchy元素 h i e r a r c h y [ i ] [ 0 ] h i e r a r c h y [ i ] [ 3 ] hierarchy[i][0] ~hierarchy[i][3] hierarchy[i][0] hierarchy[i][3],分别表示后一个轮廓、前一个轮廓、父轮廓、内嵌轮廓的索引编号,如果没有对应项,则该值为负数

drawContours:画出轮廓

drawContours(image, contours, contourIdx, color, thickness=None, lineType=None, hierarchy=None, maxLevel=None, offset=None):

参数说明:

  • Image:输入原始的图像;

  • Contours:坐标点(这个根据查找轮廓函数即可得到);

  • contourIdx;设置轮廓的顺序号;-1表示绘制所有的轮廓;

  • Color:绘制使用的颜色;

  • Thickness:绘制使用的线宽;-1表示全部填充;

  • lineType:绘制使用的线类型;

  • Hierarchy:设置层级;

  • maxLevel:如果为0,则仅绘制指定的轮廓。

    • 如果为1,则函数将绘制轮廓和所有嵌套轮廓。如果为2,则函数绘制等高线、所有嵌套等高线、所有嵌套到嵌套等高线,等等。这仅当存在可用的层次结构时,才考虑参数。
  • Offset:将所有绘制的轮廓移动指定的量。

代码

    import cv2
    
    img = cv2.imread('test.jpg')
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    ret, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
    
    
    # 检测轮廓
    contours, hierarchy = cv2.findContours(binary,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
    
    # 画轮廓
    cv2.drawContours(img, contours, -1, (0, 0, 255), 3)
    
    cv2.imshow("img", img)
    cv2.waitKey(0)

效果展示



四、实验结果

实验结果已经在实验过程中写出,实验结果的所有截图均可在实验过程中查看,这里不做过多展示

五、实验结论

在本实验中,涵盖了NumPy数组操作和OpenCV图像处理两个重要方面。在NumPy数组操作部分,学到了如何使用 NumPy 创建各种类型的数组,包括一维数组、二维数组等,以及如何访问和修改数组中的元素,了解了数组对象的一些属性,比如形状、大小等,以及数组对象的一些方法,比如求和、平均值、最大值、最小值等,学习了如何改变数组的形状,包括改变维度、转置数组、重塑数组等操作,通过学习 reshape、transpose、rollaxis、swapaxes 等函数实现了这些操作,以及掌握了如何使用索引和切片对数组进行元素的访问和修改,包括基本索引、切片索引、布尔索引等方法。在opencv图像处理部分,了解了如何在OpenCV中实现图像的颜色空间转换,这对于图像处理中很多任务都是必不可少的;学习到如何在图像上绘制基本的几何图形,在图像上添加文字,以及如何为图像添加边框以及使用OpenCV查找图像中的轮廓,对OpenCV图像处理模块的功能和应用有了更深入的理解。通过本实验的学习,深入理解了 NumPy 数组的概念、数组的重塑和操作方法,加深了对数组运算和操作的理解。同时,还学习了OpenCV图像处理模块的功能和应用,掌握了实现颜色变换、绘制基本图形、文字绘制、为图像添加边框以及在图像中查找轮廓等技术。为后续更复杂的数据、图像处理和科学计算打下了良好的基础。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Python】Python读Excel文件生成xml文件

目录 ​前言 正文 1.Python基础学习 2.Python读取Excel表格 2.1安装xlrd模块 2.2使用介绍 2.2.1常用单元格中的数据类型 2.2.2 导入模块 2.2.3打开Excel文件读取数据 2.2.4常用函数 2.2.5代码测试 2.2.6 Python操作Excel官方网址 3.Python创建xml文件 3.1 xml语法…

HCL Domino 12系统管理员考试

大家好,才是真的好。 12月份的某一天,趁着风和日丽,天朗气清, 下了舍弃100多美金的狠心,在Pearson Vue官网上报了HCL Domino 12系统管理员考试的名 。时隔十五年后,骑着电动车风风火火地前往某一当地考试中…

AI Pika 生成进击的巨人动漫分镜案例

背景介绍 Pika 是一个使用 AI 生成和编辑视频的平台。它致力于通过 AI 技术使视频制作变得简单和无障碍。 Pika 1.0 是 Pika 的一个重大产品升级,包含了一个新的 AI 模型,可以在各种风格下生成和编辑视频,如 3D 动画,动漫,卡通和电影风格。…

pytorch中的transpose用法

注意:维数从0开始,0维 1维2维…,负数代表从右往左数,-1代表第一维,以此类推 import torch import numpy as np# 创建一个二维数组 arr torch.tensor([[[1, 2],[3, 4]],[[5, 6],[7, 8]]]) print("原始数组:"…

深入理解 Java 虚拟机(JVM)从入门到精通

目录 一、JVM内存结构1、堆(Heap)(1)特点(2)堆内存分配(3)晋升到老年代的方式(4)堆内存检验方式2、虚拟机栈(VM Stack)(1&…

Vis.js教程(二):基础关系图实现

首先引用所需要的css和js文件 <link href"https://cdn.bootcdn.net/ajax/libs/vis-network/9.1.6/dist/dist/vis-network.min.css" rel"stylesheet"> <script src"https://cdn.bootcdn.net/ajax/libs/vis-network/9.1.6/standalone/umd/vis-…

python+requests+excel 接口测试

1、EXCEL文件接口保存方式&#xff0c;如图。 2、然后就是读取EXCEL文件中的数据方法&#xff0c;如下&#xff1a; 1 import xlrd2 3 4 class readExcel(object):5 def __init__(self, path):6 self.path path7 8 property9 def getSheet(self): 10 …

前端编码中快速填充内容--乱数假文

写前端页面的时候&#xff0c;如果要快速插入图片&#xff0c;可以使用 https://picsum.photos/ 详见笔者这篇博文&#xff1a; 工具网站&#xff1a;随机生成图片的网站-CSDN博客 可是&#xff0c;如果要快速填充文字内容该怎么做呢&#xff1f; 以前&#xff0c;我们都是…

【GAMES101】二维变换和齐次坐标

这几天都在抽空学OpenGL、敲leetcode和看games&#xff0c;这里留点笔记给以后复习 games101第一节课在吹水&#xff0c;第二节课讲了线性代数的入门知识&#xff0c;比较简单&#xff0c;这里稍微回顾一下重点&#xff0c;然后开始讲第三节课的二维变换和齐次坐标 目录 向量…

ACM32F42X系列芯片有何性能?为什么可以应用在工业控制 中等产品上

ACM32F42X 芯片的内核基于 ARMv8-M 架构&#xff0c;支持 Cortex-M33 和 Cortex-M4F 指令集。内核支持一 整套 DSP 指令用于数字信号处理&#xff0c;支持单精度 FPU 处理浮点数据&#xff0c;同时还支持 Memory Protection Unit &#xff08;MPU&#xff09;用于提升应用的安全…

C++[面向对象的程序设计]_基础入门(上)(万字总结)(建议收藏!!!)

目录 1. C基础入门 1.1 变量 1.2 常量 1.3 关键字 1.4 标识符命名规则 1.5 数据类型 1.5.1 整型 1.5.2 sizeof 关键字 1.5.3 实型&#xff08;浮点型&#xff09; 1.5.4 字符型 1.5.5 转义字符 1.5.6 字符串类型 1.5.7 布尔类型 1.5.8 数据的输入 1.6 运算符 …

ps快捷键和常见项目总结

处理以像素构成的位图的软件 Mac笔记本快捷键&#xff1a; 打开文件&#xff1a;commandO 图像缩放&#xff1a;command 多个文件切换&#xff1a;同一桌面中&#xff1a;command (英文状态下输入) 切换屏幕模式&#xff1a;F,全屏模式下Tab键可进行切换 首选项—性能&a…

python/matlab图像去雾/去雨综述

图像去雾和去雨是计算机视觉领域的两个重要任务&#xff0c;旨在提高图像质量和可视化效果。本文将综述图像去雾和去雨的算法、理论以及相关项目代码示例。 一、图像去雾算法 基于暗通道先验的方法&#xff1a; 这是广泛应用于图像去雾的经典算法之一。该方法基于一个观察&…

SpringMVC修炼之旅(2)基础入门

一、第一个程序 1.1环境配置 略 1.2代码实现 package com.itheima.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody;//定义…

MySQL联合查询、最左匹配、范围查询导致失效

服务器版本 客户端&#xff1a;navicat premium16.0.11 联合索引 假设有如下表 联合索引就是同时把多列设成索引&#xff0c;如(empno&#xff0c;ename)在查询的时候就会先按照empno进行查询&#xff0c;再按照ename进行查询其中empno是全局有序&#xff0c;ename是局部有…

【银行测试】支付类测试关注点与异常点+支付平台...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、支付类的测试关…

Django回顾 - 6 Ajax

【1】Ajax 定义&#xff1a; 异步Javscript和XML 作用&#xff1a; Javascript语言与服务器(django)进行异步交互&#xff0c;传输的数据为XML&#xff08;当然&#xff0c;传输的数据不只是XML,现在更多使用json数据&#xff09; 同步交互和异步交互&#xff1a; 1、同步交互&…

Web server failed to start. Port 8081 was already in use.

netstat -aon|findstr "8081" taskkill /pid 20824 /f

现代雷达车载应用——第2章 汽车雷达系统原理 2.1节

经典著作&#xff0c;值得一读&#xff0c;英文原版下载链接【免费】ModernRadarforAutomotiveApplications资源-CSDN文库。 2.1 基本雷达功能 雷达系统通过天线或天线阵列向空间辐射电磁能量。辐射的电磁能量“照亮”周围的目标。“被照亮”的目标拦截一些辐射能量&#xff0…

开发步骤、Java开发工具

目录 一、开发步骤 二、Java开发工具 JDK安装完毕&#xff0c;我们就可以开始开发第一个Java程序了&#xff0c;习惯性的成为HelloWorld。 一、开发步骤 Java程序开发三步骤&#xff1a;编写、编译、运行 -将Java代码编写到扩展名为.java的源文件中 -通过javac.exe命令对…