Windows下Python-openCV学习(三)-------像素获取和NumPy模块

本文介绍了在Windows下使用Python的OpenCV库获取和操作图像像素的方法,探讨了如何利用NumPy模块进行高效数组操作,并通过实例展示了创建、修改像素点、数组运算、数组索引及图片创建等操作。
摘要由CSDN通过智能技术生成

本章简明

像素获取:
			确定像素的位置
			获取像素的BGR值
			修改像素的BGR值

使用NumPy模块操作像素:

			NumPy模块概述
			数组的类型
			创建数组:array()方法
			操作数组
			数组的索引和切片
			创建图像
			拼接图像

讲解

像素点的获取
我们要如何获取图片中指定位置的像素点信息呢?在Windows下Python-openCV学习(二)-------图像处理基本操作中我们使用cv2.imread方法打开一个图像,其返回值就是图片的相关信息。
我们用画图打开一张图片,可以看到长像素范围为(0,1913),宽像素范围为(0,874)
在这里插入图片描述
我们可以建立这样一个坐标系来表示每一个像素点。
在这里插入图片描述
Y轴(0,1913),X轴(0,874),那么像素点的位置就可表示为 (Y,X)。我们选取(1913,974)点作为目标点。
下面看一下如何获取这个像素点的信息:

import cv2
image = cv2.imread("D:/python_learn/opencv_learn/2.png",1)
px=image[1913,974]
print(px)

运行:
在这里插入图片描述
报错提示超出315长度限制,这说明我们使用画图软件打开的图片得到的图片像素大小是不准确的。
我们直接查看图片的文件属性
在这里插入图片描述
Y轴(0,314),X轴(0,235),那么像素点的位置就可表示为 (Y,X)。我们选取(314,235)点作为目标点。
再测试一下:

import cv2
image = cv2.imread("D:/python_learn/opencv_learn/2.png",1)
px=image[314,235]
print(px)

输出
在这里插入图片描述
我们得到一个数组,[ 9 10 6]。这就是这个像素点的BGR值(就是RGB值,只是顺序翻了)。


还记得上章的这一段代码嘛:

import cv2
image = cv2.imread("D:/python_learn/opencv_learn/2.png",1)
print("图像的shape属性",image.shape)
print("图像的size属性",image.size)
print("图像的数据类型",image.dtype)

输出:

图像的shape属性 (315, 236, 3)
图像的size属性 223020
图像的数据类型 uint8

可以看到shape属性中第一个就是垂直像素,第二个水平像素,第三个通道数目。这里通道数为3是因为彩色图片都是由三基色(红绿蓝)构成,每种颜色表示一个通道,所以彩色图片通道数为3。openCV中是三基色的排列顺序是蓝绿红,既是BGR。按顺序存放在列表中,因此我们可以对获取像素点BGR的代码如下优化,读取指定颜色通道的数值。

import cv2
image = cv2.imread("D:/python_learn/opencv_learn/2.png",1)
bx=image[314,235,0]
gx=image[314,235,1]
rx=image[314,235,2]
print(f'像素点B值 {bx}')
print(f'像素点G值 {gx}')
print(f'像素点R值 {rx}')

输出:

像素点B值 9
像素点G值 10
像素点R值 6

操作像素点
上面我们已经学习了如何获取像素点信息,下面我们看看如何来操作像素点,实质就是修改图片像素点的RGB数值。
在这里插入图片描述

修改一个像素点的信息比较难以观察,我们修改上图中那个矩形中的像素点信息。

对于BGR色彩空间的图像,BGR三通道数值相等时就可以得到灰度图像
其中三通道都为0为纯黑色,三通道都为255为纯白色

import cv2
image = cv2.imread("D:/python_learn/opencv_learn/2.png",1)
for i in range(image.shape[0]-20,image.shape[0]):
    for j in range(image.shape[1]-20,image.shape[1]):
        image[i,j]=[255,255,255]
cv2.imshow("text",image)
cv2.waitKey()
cv2.destroyAllWindows()

运行:
在这里插入图片描述

使用NumPy模块操作像素

什么是NumPy?

NumPy 是一个 Python 包。 它代表 “Numeric Python”。 它是一个由多维数组对象和用于处理数组的例程集合组成的库。
Numeric,即 NumPy 的前身,是由 Jim Hugunin 开发的。 也开发了另一个包 Numarray ,它拥有一些额外的功能。 2005年,Travis Oliphant 通过将 Numarray 的功能集成到 Numeric 包中来创建 NumPy 包。 这个开源项目有很多贡献者。

在这里插入图片描述
NumPy是C语言实现的,所以其运算速度非常快。具体功能如下:

1、有一个强大的N维数组对象ndarray
2、广播功能方法
3、线性代数、傅里叶变换、随机数生成、图形操作等
4、整合C/C++/Fortran代码工具

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_	
float_ 是float64 类型的简写
---------------------------------------------------------------------------------------------
float16
半精度浮点数,包括:1 个符号位,5 个指数位,10 个尾数位
float32
单精度浮点数,包括:1 个符号位,8 个指数位,23 个尾数位
float64
双精度浮点数,包括:1 个符号位,11 个指数位,52 个尾数位
complex_
complex128 类型的简写,即 128 位复数
complex64
复数,表示双 32 位浮点数(实数部分和虚数部分)
complex128
复数,表示双 64 位浮点数(实数部分和虚数部分)

使用NumPy创建数组
1、常规array方法

numpy.array(object,dtype,copy,order,subok,ndmin)
参数:
		object :任何具有数组接口方法的对象
		dtype : 数据类型
		copy : 布尔型,可选参数。默认值为True,object参数被复制;否则,只有当__array__返回副本,
				object参数为嵌套序列,或者需要副本满足数据类型和顺序要求时,才会生成副本。
		order : 元素在内存中出现的顺序,其值为K,A,C,F。如果object参数不是数组,则新创建的数组将按行排
		         列(C),如果值为F,按列排列;如果object参数是一个数组,则以下顺序成立:
		         C(按行)  F(按列)  A(原顺序)  F(元素在内存中出现的位置)。
	    subok : 默认情况下,返回的数组被强制为基类数组。 如果为true,则返回子类。
	    ndmin : 指定生成数组的最小维数

下面我们来看几个小例子:

1.1 创建一维数组和二维数组

import numpy as np
n1=np.array([1,2,3])
n2=np.array([[1,2],[3,4]])
print("一维数组")
print(n1)
print("二维数组")
print(n2)

输出:

一维数组
[1 2 3]
二维数组
[[1 2]
 [3 4]]

1.2 创建指定类型数组

#创建浮点类型数组
import numpy as np
stl=[1,2,3]
n1=np.array(stl,dtype=np.float_)
print(n1)

输出

[1. 2. 3.]

1.2 创建三维数组
方法一

import numpy as np
n1=np.array([[[1,2,3],[4,5,6]]])
print(n1)

方法二

import numpy as np
n1=np.array([1,2,3],ndmin=3)
print(n1)

输出

[[[1 2 3]]]

2、创建指定维度和数据类型未初始化数组

numpy.empty(shape, dtype, order)
参数:
			
		shape :intinttuple
				空数组的Shape,例如,(2, 3)2

		dtype :data-type, 可选

				数组所需的输出数据类型,例如, numpy.int8 默认值为numpy.float64.

		order :{‘C’, ‘F’}, 可选, 默认: ‘C’

				是否以行优先(C样式)或列优先(Fortran样式)的顺序存储多维数据在内存中。

创建一个未初始化的,两行三列未初始化,int类型数组

import numpy as np
n1=np.empty((2,3),dtype=np.int_)
print(n1)

输出

[[-707327008      32764 -707322496]
 [     32764          0          0]]

3、创建纯0填充的数组

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

参数:
			
		shape:intint元组

			新阵列的形状,例如,或。(2, 3)2

		dtype:数据类型,可选

			数组的所需数据类型,例如numpy.int8。默认是 numpy.float64。

		order : {'C''F'},可选,默认:'C'

			是否在内存中以行主(C风格)或列主(Fortran风格)顺序存储多维数据。

创建三行三列数据类型为无符号整形的纯0数组

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

输出:

[[0 0 0]
 [0 0 0]
 [0 0 0]]

4、创建纯1填充数组

numpy.ones(shape, dtype=float, order='C')
	
		shape : intint的序列

			新数组的形状,例如,(2, 3)2

		dtype : 数据类型,可选

			数组的所需数据类型,例如numpy.int8。默认是 numpy.float64。

		order : {'C''F'},可选,默认值:C

			是否在内存中以行主(C-风格)或列主(Fortran-风格)顺序存储多维数据。

创建三行三列数据类型为无符号整形的纯1数组

import numpy as np
n1=np.ones([3,3],dtype=np.uint8)
print(n1)

输出

[[1 1 1]
 [1 1 1]
 [1 1 1]]

5、创建随机数组

np.random.randint(low,high,size)

参数:
		low:随机数最小取值范围
		high:可选参数,随机数最大取值范围,若high为空,取值范围为(0,low),不为空为(low,high).
		      high>low
		size:可选参数,数组维度

随机生成10个1~3且不包括3的整数

import numpy as np
n1=np.random.randint(1,3,10)
print(n1)

输出

[2 1 1 2 2 2 1 1 1 2]

随机生成1~3,以内的二维数组

import numpy as np
n1=np.random.randint(1,3,size=(2,3))#两行三列
print(n1)

输出:

[[1 2 2]
 [2 2 1]]

操作数组
1、加减乘除幂运算

import numpy as np
n1=np.array([1,2],dtype=np.float_)
n2=np.array([3,4],dtype=np.float_)
print(f'n1:\n{n1}')
print(f'n2:\n{n2}')
print('----')
print(f'n1+n2 \n{n1+n2}')
print('----')
print(f'n2-n1 \n{n2-n1}')
print('----')
print(f'n1*n2 \n{n1*n2}')
print('----')
print(f'n2/n1 \n{n2/n1}')
print('----')
print(f'n1**n2 \n{n1**n2}')

输出

n1:
[1. 2.]
n2:
[3. 4.]
----
n1+n2 
[4. 6.]
----
n2-n1 
[2. 2.]
----
n1*n2 
[3. 8.]
----
n2/n1 
[3. 2.]
----
n1**n2 
[ 1. 16.]

2、比较运算

import numpy as np
n1=np.array([1,2,3])
n2=np.array([4,5,6])
print(n1>=n2)
print(n1<=n2)
print(n1==n2)
print(n1!=n2)

输出

[False False False]
[ True  True  True]
[False False False]
[ True  True  True]

3、数组的复制

import numpy as np
n1=np.array([1,2,3])
n2=np.array(n1,copy=True)
print(n2==n1)
n2[1]=0
print(n1)
print(n2)
n2=n1.copy()#这种方法比较常用
print(n1==n2)

输出

[ True  True  True]
[1 2 3]
[1 0 3]
[ True  True  True]

数组的索引
1、一维数组索引

import numpy as np
n1=np.array([1,2,3])
n2=n1[0]
print(n2)

输出

1

2、一维数组切片索引

[起始索引,终止索引,步长]

起始索引 :不写任何值表示从0开始
终止索引 :不写任何值表示到末尾全部索引

[起始索引,终止索引),注意是左闭右开

示例

import numpy as np
n1=np.array([0,1,2,3,4,5,6,7,8,9])
print(n1)
print(n1[:3])
print(n1[3:6])
print(n1[5:])
print(n1[3:6:2])
print(n1[::])
print(n1[:])
print(n1[::2])
print(n1[2::2])
print(n1[::-1])
print(n1[-1:-4:-1])#n1[-1:-4]这种写法是错误的,步长默认是1不是-1
print(n1[-3::-1])

输出

[0 1 2 3 4 5 6 7 8 9]
[0 1 2]
[3 4 5]
[5 6 7 8 9]
[3 5]
[0 1 2 3 4 5 6 7 8 9]
[0 1 2 3 4 5 6 7 8 9]
[0 2 4 6 8]
[2 4 6 8]
[9 8 7 6 5 4 3 2 1 0]
[9 8 7]
[7 6 5 4 3 2 1 0]

3、二维数组索引

arry[n,m]
n:行
m:

示例

import numpy as np
n1=np.array([[0,1,2,3],[4,5,6,7],[8,9,10,11]])
print(n1)
print('-------')
print(n1[1])
print(n1[1,2])
print(n1[-1])
print(n1[-1,-1])
print('-------')
print(n1[:2,1:])
print('-------')
print(n1[1,:2])
print('-------')
print(n1[:2,2])
print('-------')
print(n1[:,:1])

输出

[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
-------
[4 5 6 7]
6
[ 8  9 10 11]
11
-------
[[1 2 3]
 [5 6 7]]
-------
[4 5]
-------
[2 6]
-------
[[0]
 [4]
 [8]]

创建图片
创建纯色图片,黑色

import cv2
import numpy as np

width=200
high=150
n1=np.ones((width,high),dtype=np.uint8)
cv2.imshow("text",n1)
cv2.waitKey()
cv2.destroyAllWindows()

输出

在这里插入图片描述
白色

import cv2
import numpy as np

width=200
high=150
n1=np.zeros((width,high),dtype=np.uint8)
print(n1)
n1[:,:]=255
cv2.imshow("text",n1)
cv2.waitKey()
cv2.destroyAllWindows()

在这里插入图片描述
创建黑白相间图像

import cv2
import numpy as np
high=500
width=500
n1=np.zeros((width,high),dtype=np.uint8)
print(n1)
for i in range(0,high,40):
    n1[0:,i:i+20]=255
    print(n1)
cv2.imshow("text",n1)
cv2.waitKey()
cv2.destroyAllWindows()

运行
在这里插入图片描述
创建彩色图片
以上例子我们可以发现,黑白图像都是二维数组:
如下图:
在这里插入图片描述
在对应的点位设置对应的色彩值(0~255)即是黑白图像,也可以说灰度。毕竟只有一个通道。

那么彩色来说一个像素点包含三个通道,那么二维数组就无法满足要求。毕竟二维数组里面(x,y)确定的位置只有一个色彩值,那么我们就需要三维数组来表示彩色图片中的像素。
在这里插入图片描述
记住图像中像素的位置是二维坐标,(X,Y)。但是加上图片通道就是三维了。举个例子:
一个图片像素点坐标是(X,Y),那么他在三维坐标轴中表示的点有(X,Y,0)、(X,Y,1)、(X,Y,2)三个点
分别是0,1,2分别对应BGR三通道。

示例:随机彩色图片

import cv2
import numpy as np
high = 255
width = 255
n1 = np.random.randint(0,256,size=(width,high,3),dtype=np.uint8)

cv2.imshow("text", n1)
cv2.waitKey()
cv2.destroyAllWindows()

输出:
在这里插入图片描述
图片的拼接
1、水平拼接图像

array=numpy.hstack(tup)
参数:
		tup:图片元组
返回值:拼接后新的图片数组

示例:
将两个图片水平拼接在一起

import cv2
import numpy as np
image = cv2.imread("D:/python_learn/opencv_learn/2.png",1)
image2=image.copy()
image3=np.hstack((image,image2))
cv2.imshow("text",image3)
cv2.waitKey()
cv2.destroyAllWindows()
print("text")

输出:
在这里插入图片描述
2、垂直拼接

array=numpy.vstack(tup)
参数:
		tup:图片元组
返回值:拼接后新的图片数组

示例:
两张图片垂直拼接

import cv2
import numpy as np
image = cv2.imread("D:/python_learn/opencv_learn/2.png",1)
image2=image.copy()
image3=np.vstack((image,image2))
cv2.imshow("text",image3)
cv2.waitKey()
cv2.destroyAllWindows()
print("text")

输出:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值