OpenCV中使用NumPy模块操作像素讲解及实战(附源码 超详细)

觉得有帮助请点赞关注收藏~~~

图像在OpenCV中以二维或三维数组表示,数组中的每一个值就是图像的像素值,善于操作数组的NumPy模块就成了OpenCV的依赖包,OpenCV中很多操作都要依赖Numpy模块,例如创建纯色图像,创建掩膜和创建卷积核等等。下面先简单介绍NumPy模块的常用操作方法和演示如何使用NumPy模块创建图像

一、NumPy常用操作

NumPy更像是一个魔方,它是Python数组计算 矩阵运算和科学计算的核心库,它提供了一个高性能的数组对象,以及可以轻松的创建一维数组,二维数组和多维数组等大量实用方法,帮助开发者轻松的进行数组计算。

NumPy创建简单的数组主要使用array()方法,通过传递列表,元组来创建NumPy数组,其中的元素可以是任何对象 语法如下

numpy.array(object,dtype,copy,order,subok,ndmin)

参数说明

object:任何具有数组接口方法的对象

dtype:数据类型

copy:可选参数 布尔型

order:元素在内存中的出现顺序

subok:布尔型 如果值为true 则传递子类

ndmin:指定生成数组的最小维数 

示例如下

创建浮点型数组

import numpy as np  # 导入numpy模块

list = [1, 2, 3]  # 列表
# 创建浮点型数组
n1 = np.array(list, dtype=np.float_)
# 或者
n1 = np.array(list, dtype=float)
print(n1)
print(n1.dtype)
print(type(n1[0]))

 

创建三维数组是将ndmin参数值设置为3即可得到三维数组

import numpy as np
nd1 = [1, 2, 3]
nd2 = np.array(nd1, ndmin=3) #三维数组
print(nd2)

 创建维度和数据类型未初始化的数组主要使用empty方法,数组元素因为未被初始化会自动取随机值  如果要改变数组类型 可以使用dtype参数

import numpy as np
n = np.empty([2, 3])
print(n)

创建用0填充的数组需要使用zeros()方法,该方法创建的元素均为0,OpenCV经常使用该方法创建纯黑图像

import numpy as np
n = np.zeros((3, 3), np.uint8)
print(n)

创建用1填充的数组需要使用ones()方法,该方法创建的数组元素均为1,OpenCV经常使用该方法创建纯掩膜,卷积核等用于计算的二维数据

import numpy as np
n = np.ones((3, 3), np.uint8)
print(n)

索引和切片

NumPy数组元素是通过数组的索引和切片来访问和修改的,因此索引和切片是NumPy中最重要和最常用的操作

查找一维数组索引为0的元素

import numpy as np
n1=np.array([1,2,3])  #创建一维数组
print(n1[0])

切片式索引

数组的切片可以理解为对数组的分割,按照等分或者不等分,将一个数组切割为多个片段,与Python中列表的切片一样 NumPy中用冒号分割切片参数来进行切片操作

[start:stop:step]

参数说明

start 起始索引 若不写任何值 则表示从0开始 

stop 终止索引 若不写任何值 则表示到末尾

stop 步长

索引是左闭右开区间

 

import numpy as np
n1=np.array([1,2,3])  #创建一维数组
print(n1[0])
print(n1[1])
print(n1[0:2])
print(n1[1:])
print(n1[:2])

 二维数组索引示意图如下

二维数组切片式索引示意图

 

import numpy as np

# 创建3行3列的二维数组
n = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(n[:2, 1:])
print(n[1, :2])
print(n[:2, 2])
print(n[:, :1])

二、利用NumPy创建图像

在OpenCV中,黑白图像实际上就是一个二维数组,彩色图像是一个三维数组,数组中每个元素就是图像对应位置的像素值,因此修改图像像素的操作实际上就是修改数组的操作,下面介绍几个OpenCV中常用的操作

1:创建纯黑图像

创建一个一百行,两百列的数组,用0填充,将该数组当作图像显示出来

import cv2
import numpy as np

width = 200  # 图像的宽
height = 100  # 图像的高
# 创建指定宽高、单通道、像素值都为0的图像
img = np.zeros((height, width), np.uint8)
cv2.imshow("img", img)  # 展示图像
cv2.waitKey()  # 按下任何键盘按键后
cv2.destroyAllWindows()  # 释放所有窗体

 2:创建纯白图像

创建纯白图像有两种方式:第一种是先纯黑图像,然后将图像中所有的像素值改为255,第二种使用numpy的ones方法创建一个像素值均为1的数组,然后让数组乘以255

import cv2
import numpy as np

width = 200  # 图像的宽
height = 100  # 图像的高
# 创建指定宽高、单通道、像素值都为1的图像
img = np.ones((height, width), np.uint8) * 255
cv2.imshow("img", img)  # 展示图像
cv2.waitKey()  # 按下任何键盘按键后
cv2.destroyAllWindows()  # 释放所有窗体

 3:在黑图像内部绘制白色矩形

通过切片式索引操作可以修改图像中指定区域内的像素,从而达到修改图像内容的效果

先绘制纯黑图像作为背景,然后使用切片式索引操作将图像中横坐标为50-100,纵坐标为25-75的矩形区域颜色改为纯白色

 

import cv2
import numpy as np

width = 200  # 图像的宽
height = 100  # 图像的高
# 创建指定宽高、单通道、像素值都为0的图像
img = np.zeros((height, width), np.uint8)
# 图像纵坐标25~75、横坐标50~100之间的区域变为白色
img[25:75, 50:100] = 255
cv2.imshow("img", img)  # 展示图像
cv2.waitKey()  # 按下任何键盘按键后
cv2.destroyAllWindows()  # 释放所有窗体

4:创建黑白相间的图像

先绘制纯黑图像作为背景,然后在循环中使用切片式索引操作绘制黑白间隔图像

import cv2
import numpy as np

width = 200  # 图像的宽
height = 100  # 图像的高
# 创建指定宽高、单通道、像素值都为0的图像
img = np.zeros((height, width), np.uint8)
for i in range(0, width, 40):
    img[:, i:i + 20] = 255  # 白色区域的宽度为20像素
cv2.imshow("img", img)  # 展示图像
cv2.waitKey()  # 按下任何键盘按键后
cv2.destroyAllWindows()  # 释放所有窗体

 5:创建彩色图像

OpenCV中彩色图像默认为BGR格式,彩色图像的第三个索引表示的就是蓝绿红三种颜色的分量

创建彩色图像数组时要将数组创建成三维数组,然后复制出三个副本,三个副本分别修改最后一个索引代表的元素值,索引0表示蓝色分量,索引1表示绿色分量,索引2表示红色分量

 

import cv2
import numpy as np

width = 200  # 图像的宽
height = 100  # 图像的高
# 创建指定宽高、3通道、像素值都为0的图像
img = np.zeros((height, width, 3), np.uint8)
blue = img.copy()  # 复制图像
blue[:, :, 0] = 255  # 1通道所有像素都为255
green = img.copy()
green[:, :, 1] = 255  # 2通道所有像素都为255
red = img.copy()
red[:, :, 2] = 255  # 3通道所有像素都为255
cv2.imshow("blue", blue)  # 展示图像
cv2.imshow("green", green)
cv2.imshow("red", red)
cv2.waitKey()  # 按下任何键盘按键后
cv2.destroyAllWindows()  # 释放所有窗体

6:创建随机图像

随机图像指的是图像中每一个像素值都是随机生成的,因为像素之间不会组成有效的视觉信息,所以看上去像杂乱无章的啥子,但是可以作为噪声和图像加密的密匙使用

import cv2
import numpy as np

width = 200  # 图像的宽
height = 100  # 图像的高
# 创建指定宽高、单通道、随机像素值的图像,随机值在0~256之间,数字为无符号8位格式
img = np.random.randint(256, size=(height, width), dtype=np.uint8)
cv2.imshow("img", img)  # 展示图像
cv2.waitKey()  # 按下任何键盘按键后
cv2.destroyAllWindows()  # 释放所有窗体

 这样演示的是黑白图像,如果创建的是三维数组,那么可以获得随机彩色图像

拼接图像

 Numpy提供了两种拼接数组的方法 分别是hstack和vstack方法,这两种方法同样可以用于拼接图像

hstack可以对数组进行水平拼接

vstack可以对数组进行垂直拼接

在OpenCV中,图像就是一个二维或三维的像素数组,这些数组同样可以被NumPy拼接,下面通过一个实例展示图像拼接的效果

下面对博主的头像进行水平和垂直拼接 效果如下

 

 

代码如下

import cv2
import numpy as np

img = cv2.imreadqq.jpg")  # 读取原始图像

img_h = np.hstack((img, img))  # 水平拼接两个图像
img_v = np.vstack((img, img))  # 垂直拼接两个图像

cv2.imshow("img_h", img_h)  # 展示拼接之后的效果
cv2.imshow("img_v", img_v)
cv2.waitKey()  # 按下任何键盘按键后
cv2.destroyAllWindows()  # 释放所有窗体

 创作不易 觉得有帮助请点赞关注收藏~~~

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

showswoller

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值