1. 深浅拷贝
opencv用mat这种数据结构来表示图片,C++中是用mat来保存图片,python中把mat转化成了numpy的ndarray。
1.1 Mat属性
字段 | 说明 | 字段 | 说明 |
---|---|---|---|
dims | 维度 | channels | 通道数RGB是3 |
rows | 行数 | size | 矩阵大小 |
cols | 列数 | type | dep+dt+chs CV_8UC3 |
depth | 像素的位深 | data | 存放数据 |
1.2 ndarray的四种常见属性
字段 | 说明 | 代码 |
---|---|---|
size | 元素的总个数 | img.size |
dtype | 图片的种类 | img.dtype |
shape | 图片的形状 | img.shape |
ndim | 图片的通道数 | img.ndim |
1.3 对图片的某段部位进行截取
使用NumPy数组切片image[y1:y2, x1:x2]
,其中:y1
和y2
是垂直方向的起始和结束位置(高度方向)。x1
和x2
是水平方向的起始和结束位置(宽度方向)。
import cv2
img = cv2.imread("car.jpg") # 将这里的路径换成你图片的路径
# 定义截取区域的坐标 (x1, x2, y1, y2)
x1, x2 = 900, 1200 # 水平方向:从100到300(不包括300)
y1, y2 = 600, 800 # 垂直方向:从50到200(不包括200)
# 执行切片操作(注意OpenCV的数组顺序是[高度, 宽度])
cropped = img[y1:y2, x1:x2]
# 显示结果
cv2.imshow('Original Image', img)
cv2.imshow('Cropped Image', cropped)
cv2.waitKey(0)
cv2.destroyAllWindows()
注意事项:
-
坐标顺序:
-
OpenCV使用**先行(高度)后列(宽度)**的索引,即
image[height, width]
。 -
因此,切片时应写为
image[y1:y2, x1:x2]
,而非x1,x2,y1,y2
的直接顺序。
-
-
左闭右开区间:
-
截取区域的实际范围是
[x1, x2)
和[y1, y2)
。例如,x1=100, x2=300
会截取宽度为200像素(300-100)的区域。
-
-
坐标值有效性:
-
确保
x2 > x1
且y2 > y1
,否则切片结果为空。 -
坐标不应超过原图尺寸,可用
image.shape
获取原图的(高度, 宽度, 通道数)。
-
2. 颜色通道的分离和合并
2.1 split(mat)分割图像的通道
# 图像的分割与融合
import cv2
import numpy as np
img = np.zeros((200, 200, 3), np.uint8)
# img = cv2.resize(img,(880,640),interpolation=cv2.INTER_CUBIC)
# 分割通道
b, g, r = cv2.split(img)
2.2 merge((ch1,ch2,ch3))融合多个通道
# 图像的分割与融合
import cv2
import numpy as np
img = np.zeros((200, 200, 3), np.uint8)
# img = cv2.resize(img,(880,640),interpolation=cv2.INTER_CUBIC)
# 分割通道
b, g, r = cv2.split(img)
# 修改一些颜色
b[10:100, 10:100] = 255
g[10:100, 10:100] = 255
# 合并通道
img_2 = cv2.merge((b, g, r))
cv2.imshow('img_1', np.hstack((b, g)))
cv2.imshow('img_2', np.hstack((img, img_2)))
cv2.waitKey(0)
cv2.destroyAllWindows()