1.像素
1.像素知识
像素是构成数字图像的基本单位
如图所示的图像是由许多个小方块组成的,通常把一个小方块称作一个像素(像素的形状不固定,大多数情况下被认为是方形的)
1.2 确定像素位置
水平方向上的像素个数是218个,对应的x轴取值范围为0~217;
垂直方向上的像素个数是292个,对应的y轴取值范围为0~291;
在OpenCV中像素坐标的表达方式为(y, x),例如本图右下角的像素坐标位置为(291, 217)。
2.像素的BGR值
刚刚了解了像素的基础知识,下面我们来学习如何查看图片中的指定像素的BGR值吧!!!
2.1 获取像素的BGR值
首先我们来学习如何表示像素
import cv2
image = cv2.imread(r"C:\Users\cgs\Desktop\pictures\1.4.jpg")
px = image[291, 217]
接着我们添加代码来获取图像的BGR值(方法一)
import cv2
image = cv2.imread(r"C:\Users\cgs\Desktop\pictures\1.4.jpg")
px = image[291, 217] # 坐标(291, 217)上的像素 opencv使用的是(y, x)
print("坐标(291, 217)上的像素BGR值为", px)
方法二:
import cv2
image = cv2.imread(r"C:\Users\cgs\Desktop\pictures\1.4.jpg")
b = image[291, 217, 0] # 单独读取B(蓝色)通道的值,0表示B通道
g = image[291, 217, 1] # 单独读取G(绿色)通道的值, 1表示G通道
r = image[291, 217, 2] # 单独读取R(红色)通道的值, 2表示R通道
print(b, g, r)
打印出来的结果如下
在RGB色彩空间中存在R(Red红色)、G(Green绿色)、B(Blue蓝色)三个通道, 每个色彩通道都在[0, 255]区间取值,通常使用 一个三维数组来表示一幅图像上某个三维数组的RGB值
2.2 修改像素的BGR值
import cv2
image = cv2.imread(r"C:\Users\cgs\Desktop\pictures\1.4.jpg")
px = image[291, 217]
print("坐标(291, 217)上像素的初始值是", px)
px = [255, 255, 255] # 修改像素的BGR值
print("修改后的BGR值为", px)
学习了修改像素后=, 我们来实战一下吧!
import cv2
image = cv2.imread(r"C:\Users\cgs\Desktop\pictures\1.4.jpg")
# cv2.imshow("original", image)
for i in range(241, 292):
for j in range(168, 218):
image[i, j] = [255, 255, 255]
cv2.imshow("last", image)
cv2.waitKey()
cv2.destroyWindows()
3.GRAY色彩空间
3.1 什么是GRAY色彩空间
GRAY色彩空间是一种只有一个通道的色彩空间,用于表示图像的灰度等级。每个像素通过一个灰度值来表示其亮度,从黑到白的不同灰色级别。此色彩空间简化了图像处理和分析,因为它不涉及颜色信息,仅关注亮度。每一个像素都是从黑到白,被处理为256个灰度级别的单色图像,分别用区间[0, 255]中的数值表示,其中“0”表示纯黑色, “255”表示纯白色。
3.2 色彩空间转换(BGR->GRAY)
本图像转换使用cvtColor()方法,语法格式如下:
dst = cv2.cvtColor(src, code)
# dst:转换后的图像
# src:转换前的初始图像
# code:色彩空间转换码
# cv2.COLOR_BGR2GRAY 从BGR色彩空间转换到GRAY色彩空间
# cv2.COLOR_RGB2GRAY 从RGB色彩空间转换到GRAY色彩空间
实现代码如下:
import cv2
image = cv2.imread(r"C:\Users\cgs\Desktop\pictures\1.4.jpg")
gray_image= cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
cv2.imshow("last", gray_image)
cv2.waitKey()
cv2.destroyWindows()
思考:可以将灰度图像转换成彩色图像吗?
4.HSV色彩空间
4.1什么是HSV色彩空间
HSV色彩空间是一种用于表示颜色的模型,通常用于图像处理和计算机图形学。HSV代表色相(Hue)、饱和度(Saturation)和明度(Value)。
1色相(Hue):
描述颜色的基本类型,如红色、绿色、蓝色等。它通常表示为一个角度值(0°到360°),代表色轮上的位置。
2.饱和度(Saturation):
描述颜色的纯度或强度。饱和度从0%(灰色,即没有颜色)到100%(纯色)不等。
3.明度(Value):
描述颜色的亮度或强度,从0%(黑色)到100%(最亮的颜色)不等。
HSV色彩空间更符合人们对颜色的感知,使得在调整图像颜色时比RGB模型更直观
4.2色彩空间转换(BGR->HSV)
cv2.COLOR_BGR2HSV # BGR->HSV
cv2.COLOR_BGR2HSV # RGB->HSV
实现代码如下:
import cv2
image = cv2.imread(r"C:\Users\cgs\Desktop\pictures\1.4.jpg")
hsv_image= cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
cv2.imshow("last", hsv_image)
cv2.waitKey()
cv2.destroyWindows()
5. 通道
5.1 拆分通道
shiyongspilt()方法拆分通道:语法如下
b, g, r = cv2.split(bgr_iamge)
b:B通道图像
g:G通道图像
r:R通道图像
bgr_image:一幅BGR图像
5.1.1 拆分BGR图像
实现代码:
import cv2
bgr_image = cv2.imread(r"C:\Users\cgs\Desktop\pictures\1.4.jpg")
b, g, r = cv2.split(bgr_image)
cv2.imshow("B", b)
cv2.imshow("G", g)
cv2.imshow("R", r)
cv2.waitKey()
cv2.destroyWindows()
5.1.2 拆分HSV图像
实现代码:
import cv2
bgr_image = cv2.imread(r"C:\Users\cgs\Desktop\pictures\1.4.jpg")
hsv_image = cv2.cv2.cvtColor(bgr_image, cv2.COLOR_BGR2HSV)
h, s, v = cv2.split(hsv_image)
cv2.imshow("H", h)
cv2.imshow("S", s)
cv2.imshow("V", v)
cv2.waitKey()
cv2.destroyWindows()
5.2 合并图像
5.2.1 合并BGR图像
语法格式如下;
bgr = cv2.merge([b, g, r]) # B->G->R顺序合并
rgb = cv2.merge([r, g, b]) # R->G->B顺序合并
实现代码如下:
import cv2
bgr_image = cv2.imread(r"C:\Users\cgs\Desktop\pictures\1.4.jpg")
b, g, r = cv2.split(bgr_image)
bgr = cv2.merge([b ,g, r])
cv2.imshow("BGR", bgr)
rgb = cv2.merge([r, g, b])
cv2.imshow("RGB", rgb)
cv2.waitKey()
cv2.destroyWindows()
5.2.2 合并HSV图像
实现代码如下:
import cv2
bgr_image = cv2.imread(r"C:\Users\cgs\Desktop\pictures\1.4.jpg")
hsv_image = cv2.cvtColor(bgr_image, cv2.COLOR_BGR2HSV)
h, s, v = cv2.split(hsv_image)
hsv = cv2.merge([h ,s, v])
cv2.imshow("HSV", hsv)
cv2.waitKey()
cv2.destroyWindows()
5.3 综合运用
实现代码如下:
import cv2
bgr_image = cv2.imread(r"C:\Users\cgs\Desktop\pictures\1.4.jpg")
hsv_image = cv2.cvtColor(bgr_image, cv2.COLOR_BGR2HSV) # 色彩空间转换
h, s, v = cv2.split(hsv_image)
# h[:, :] = 180 # H通道的值调整为180
# s[:, :] = 180 # S通道的值调整为180
v[:, :] = 230 # V通道的值调整为230
hsv = cv2.merge([h ,s, v]) # 合并
n_image = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR) # 色彩空间转换
cv2.imshow("NEW", n_image)
cv2.waitKey()
cv2.destroyWindows()
自己也动手试试吧!!
5. 使用Numpy模块操作像素
5.1 Numpy概述
NumPy 是一个用于科学计算的 Python 库,提供了支持大规模多维数组和矩阵运算的功能。它的核心特性包括:
1.ndarray 对象:用于存储和操作多维数组。
2.广播:用于简化不同形状数组之间的运算。
3.线性代数:提供矩阵操作和数学计算功能。
4.随机数生成:用于生成随机数和随机分布。
5.高效的数值计算:通过 C 和 Fortran 实现高效的计算性能。
NumPy 是许多数据科学和机器学习库(如 pandas、scikit-learn)的基础。
5.2 数组类型
-
整数类型:
np.int8
:8-bit 整数np.int16
:16-bit 整数np.int32
:32-bit 整数np.int64
:64-bit 整数np.uint8
:8-bit 无符号整数np.uint16
:16-bit 无符号整数np.uint32
:32-bit 无符号整数np.uint64
:64-bit 无符号整数np.intp
:平台上整型,通常为np.int32
或np.int64
np.uintp
:平台上无符号整型,通常为np.uint32
或np.uint64
-
浮点类型:
np.float16
:16-bit 浮点数np.float32
:32-bit 浮点数np.float64
:64-bit 浮点数np.float128
:128-bit 浮点数(可能不可用,取决于平台)
-
复数类型:
np.complex64
:64-bit 复数(32-bit 实部 + 32-bit 虚部)np.complex128
:128-bit 复数(64-bit 实部 + 64-bit 虚部)np.complex256
:256-bit 复数(128-bit 实部 + 128-bit 虚部,可能不可用)
-
布尔类型:
np.bool_
:布尔值(True 或 False)
-
字符串和字符类型:
np.str_
:字符串np.unicode_
:Unicode 字符串np.bytes_
:字节字符串
-
对象类型:
np.object_
:对象类型,用于存储任意 Python 对象
-
其他类型:
np.void
:用于处理自定义数据结构(结构化数组
下面是一些示例:
import numpy as np
number_1 = np.int8(3.141)
number_2 = np.float64(8)
print(number_1)
print(number_2)
5.3 创建数组
5.3.1 一维和二维数组
array()方法,语法结构如下:
numpy.array(object, dtype, copy, order, subok, ndmin)
# object: 任何具有数组接口方法的对象
# dtype: 数据类型
# copy: 可选参数布尔型, 默认值为True, object对象被复制
# order: 元素在内存中的出现顺序, 值为K, A, C, F
若object不是数组, 新创建的数组按行排列(C), 按列排列(F)
若object是数组, 按行(C), 按列(F), 原顺序(A), 元素在内存中出现的顺序(K)
# subok: 布尔型, 如果值为True, 则传递子类, 否则强制返回为基类数组(默认值)
# ndmin: 指定数组的最小维数
import numpy as np
n1 = np.array([1, 2, 3])
n2 = np.array([0.1, 0.2, 0.3])
n3 = np.array([[1, 2], [3, 4]])
print(n1)
print(n2)
print(n3)
结果如下:
[1 2 3]
[0.1 0.2 0.3]
[[1 2]
[3 4]]
5.3.2 浮点型
import numpy as np
list = [1, 2, 3]
# 创建浮点型数组
n1 = np.array(list, dtype=np.float_)
# 或者
n2 = np.array(list, dtype=float)
print(n1)
print(n1.dtype)
print(type(n1[0]))
打印结果如下:
[1. 2. 3.]
float64
<class 'numpy.float64'>
5.3.3 三维数组
创建指定维度和数据类型未初始化数组主要使用empty()方法。
5.3.4 2行3列未初始化数组
import numpy as np
n = np.empty([3, 3])
print(n)
结果如下:
[[0.00000000e+000 0.00000000e+000 0.00000000e+000]
[0.00000000e+000 0.00000000e+000 3.47822215e-321]
[2.41079362e+198 1.88891968e+219 5.98150398e-154]]
5.3.5 纯0数组
import numpy as np
n = np.zeros((3, 3), np.uint8)
print(n)
结果如下:
[[0 0 0]
[0 0 0]
[0 0 0]]
5.3.6 纯1数组
import numpy as np
n = np.ones((3, 3), np.uint8)
print(n)
结果如下:
[[1 1 1]
[1 1 1]
[1 1 1]]
5.3.7 随机数组
使用randint()方法创建一定范围内的随机整数数组, 左闭右开([low, height])
语法结构如下:
numpy.random.randint(low, height, size)
# low: 随机数最小取值范围
# high: 随机数最大取值范围, 若high为空, 则取值范围为(0, low),若high不为空,则high必须大于low
# size: 可选参数, 数组维数
import numpy as np
n1 = np.random.randint(1, 3, 10)
print("随机生成10个从1到3之间不包括3的整数:", n1)
n2 = np.random.randint(5, 10)
print("size数组大小为空随机返回一个整数:", n2)
n3 = np.random.randint(5, size=(2, 5))
print("随机生成5以内的二维数组", n3)
打印结果如下:
随机生成10个从1到3之间不包括3的整数: [2 2 2 1 2 1 2 2 1 1]
size数组大小为空随机返回一个整数: 8
随机生成5以内的二维数组 [[3 4 3 3 1]
[1 3 0 1 4]]
5.4 操作数组
5.4.1 加、加减乘除法运算
import numpy as np
n1 = np.array([1, 2])
n2 = np.array([3, 5])
print(n1 + n2)
print(n1 - n2)
print(n1 * n2)
print(n1 / n2)
运行结果如下:
[4 7]
[-2 -3]
[ 3 10]
[0.33333333 0.4 ]
5.4.2 幂运算
import numpy as np
n1 = np.array([1, 2])
n2 = np.array([3, 5])
print(n1 ** n2)
# 运行结果:[ 1 32]
5.4.3 使用运算逻辑符比较数组
import numpy as np
n1 = np.array([1, 2])
n2 = np.array([3, 5])
print(n1 >= n2)
print(n1 == n2)
print(n1 <= n2)
print(n1 != n2)
# 运行结果如下:
# [False False]
# [False False]
# [ True True]
# [ True True]
5.4.4 比较复制数据和原始数组
使用如下语法复制数据:
n2 = np.array(n1, copy=True)
n2 = n1.copy() # 更常用
import numpy as np
n1 = np.array([1, 2])
# n2 = np.array(n1, copy=True)
n2 = n1.copy()
print(n1 == n2)
n2[0] = 9 # 修改副本数组第一个元素
print(n1)
print(n2)
print(n1 == n2)
# 运行结果如下
# [ True True]
# [1 2]
# [9 2]
# [False True]
5.5 数组的索引和切片
5.5.1 查找一维数组中的元素
索引从0开始,代表第一个元素
import numpy as np
n1 = np.array([1, 2, 3])
print(n1[0])
# 结果如下
# 1
5.5.2 获取数组中某个范围的数组(切片式索引)
切片式索引:
[start:stop:step]
# start:起始索引, 若不写任何值,表示从零开始的全部索引
# stop:终止索引, 若不写任何值,表示到末尾为止的全部索引
# step:步长
示例如下:
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])
print(n1[::-1])
# 结果如下
# 1
# 2
# [1 2]
# [2 3]
# [1 2]
# [3 2 1]
关于切片式索引如果不熟的话可以去复习一下python 中的相关内容。
5.5.3 获取二维数组中元素的三种不同方式
import numpy as np
n1 = np.array([[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]])
print(n1)
print(n1[1, 2]) # 第二行第三列
print(n1[-1])
# 结果如下
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
# 6
# [ 8 9 10 11]
5.5.4 对二维数组进行切片式索引操作
import numpy as np
n1 = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
print(n1[:2, 1:]) # 行数[0, 2), 列数从1到最后一列
print(n1[1, :2]) # 第2行,第[0, 2)列
print(n1[:2, 2])
print(n1[:, :1])
# 结果如下
# [[2 3]
# [5 6]]
# [4 5]
# [3 6]
# [[1]
# [4]
# [7]]
5.6 创建图像
像素行索引 = 像素所在行数 - 1 = 像素纵坐标
像素列索引 = 像素所在列数 - 1 = 像素纵坐标
5.6.1 纯黑色图像
import cv2
import numpy as np
width = 250
height = 120
# 创建指定宽高, 像素值都为0的图像
img = np.zeros((height, width), np.uint8)
cv2.imshow("img", img)
cv2.waitKey()
cv2.destroyAllWindows()
5.6.2 纯白色图像
import cv2
import numpy as np
width = 250
height = 120
# 创建指定宽高, 像素值都为1的图像
img = np.ones((height, width), np.uint8) * 255
cv2.imshow("img", img)
cv2.waitKey()
cv2.destroyAllWindows()
5.6.3 黑色图像内部绘制白色矩形
import cv2
import numpy as np
width = 250
height = 120
# 创建指定宽高, 像素值都为0的图像
img = np.zeros((height, width), np.uint8)
img[15:85, 65:120] = 255 # 绘制白色区域
cv2.imshow("img", img)
cv2.waitKey()
cv2.destroyAllWindows()
5.6.4 创建黑白相间的图像
import cv2
import numpy as np
width = 250
height = 120
# 创建指定宽高, 像素值都为0的图像
img = np.ones((height, width), np.uint8)
for i in range(0, width, 40):
for j in range(0, width, 40):
img[j:j + 20, i:i + 20] = 255 # 绘制白色区域
cv2.imshow("img", img)
cv2.waitKey()
cv2.destroyAllWindows()
5.6.5 创建彩色图像
import cv2
import numpy as np
width = 250
height = 120
# 创建指定宽高, 像素值都为0的图像
img = np.zeros((height, width, 3), np.uint8)
blue = img.copy()
blue[:, :, 0] = 255 # 0表示1(B)通道
cv2.imshow("blue", blue)
cv2.waitKey()
cv2.destroyAllWindows()
快去试试如何创建绿色和红色图像吧!!!
5.6.6 创建雪花点图像
import cv2
import numpy as np
width = 250
height = 120
img = np.random.randint(256, size=(height, width), dtype=np.uint8)
cv2.imshow("snow", img)
cv2.waitKey()
cv2.destroyAllWindows()
快去试试如何创建随机彩色图像吧!!
img = np.random.randint(256, size=(height, width, 3), dtype=np.uint8)
5.7 拼接图像
# 语法结构如下:
array = numpy.hstack(tup) # 水平拼接
array = numpy.vstack(tup) # 竖直拼接
# tup: 要拼接的数组元素
# array: 拼接后生成的新数组
# 拼接数组的行数和列数必须相同
# 水平拼接
import numpy as np
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
c = np.array([7, 8, 9])
result = np.hstack((a, b, c))
print(result)
# 竖直拼接
import numpy as np
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
c = np.array([7, 8, 9])
result = np.vstack((a, b, c))
print(result)
结果如下:
下面我们进行实例演示:
import cv2
import numpy as np
img = cv2.imread(r"C:\Users\cgs\Desktop\pictures\5(1).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.destoryAllWindows()
那么第二章到这里就结束了!!!!