在图像处理任务中,将整张图像划分为多个子块后,获取每个子块的边界顶点是很多后续操作的基础,比如子块标注、区域特征匹配等。接下来我们用Python结合OpenCV库,演示如何完成这个操作。

前置准备
首先需要安装OpenCV库,执行以下命令即可完成安装:
pip install opencv-python
图像分块规则定义
我们采用固定尺寸分块的方式,比如将图像划分为多个宽高为block_w、block_h的子块,不足一个完整子块的部分单独作为一个分块处理。图像的坐标体系以左上角为原点,向右为x轴正方向,向下为y轴正方向。
核心实现步骤
1. 读取图像并获取尺寸
首先读取目标图像,获取图像的高度和宽度,用于后续分块计算:
import cv2
# 读取图像
img = cv2.imread("test.jpg")
# 获取图像高度和宽度
img_h, img_w = img.shape[:2]
print(f"图像尺寸:宽{img_w},高{img_h}")2. 定义分块参数并计算分块数量
设置每个子块的宽度和高度,计算横向和纵向分别能划分出多少个完整子块:
# 分块尺寸
block_w = 100
block_h = 100
# 计算横向和纵向完整分块数量
cols = img_w // block_w
rows = img_h // block_h
print(f"横向完整分块数:{cols},纵向完整分块数:{rows}")3. 遍历分块获取边界顶点
遍历每一个分块,计算每个分块的左上角和右下角两个边界顶点,这两个顶点即可确定整个分块的范围,其他两个顶点可以推导得到:
# 存储所有分块的边界顶点,每个元素为(左上角x,左上角y,右下角x,右下角y)
block_vertices = []
# 遍历完整分块
for row in range(rows):
for col in range(cols):
# 计算左上角坐标
left_x = col * block_w
top_y = row * block_h
# 计算右下角坐标
right_x = left_x + block_w
bottom_y = top_y + block_h
block_vertices.append((left_x, top_y, right_x, bottom_y))
# 处理横向剩余不完整分块
if img_w % block_w != 0:
left_x = cols * block_w
right_x = img_w
for row in range(rows):
top_y = row * block_h
bottom_y = top_y + block_h
block_vertices.append((left_x, top_y, right_x, bottom_y))
# 处理纵向剩余不完整分块
if img_h % block_h != 0:
top_y = rows * block_h
bottom_y = img_h
for col in range(cols):
left_x = col * block_w
right_x = left_x + block_w
block_vertices.append((left_x, top_y, right_x, bottom_y))
# 处理右下角剩余的不完整分块
if img_w % block_w != 0 and img_h % block_h != 0:
left_x = cols * block_w
right_x = img_w
top_y = rows * block_h
bottom_y = img_h
block_vertices.append((left_x, top_y, right_x, bottom_y))
print(f"总共得到{len(block_vertices)}个分块的边界顶点")4. 验证结果
我们可以将分块边界绘制在图像上,验证获取的顶点是否正确:
# 复制原图用于绘制
draw_img = img.copy()
# 遍历所有分块顶点,绘制矩形框
for vertex in block_vertices:
left_x, top_y, right_x, bottom_y = vertex
# 绘制矩形,边框颜色为绿色,线宽为2
cv2.rectangle(draw_img, (left_x, top_y), (right_x, bottom_y), (0, 255, 0), 2)
# 保存结果图像
cv2.imwrite("result.jpg", draw_img)注意事项
- 如果分块尺寸大于图像尺寸,会直接生成一个包含整张图像的分块,顶点为(0,0,img_w,img_h)。
- 顶点坐标都是整数类型,符合OpenCV的图像坐标要求,不需要额外转换。
- 如果需要获取四个顶点而不是两个对角顶点,可以通过已有的两个顶点推导得到,分别是(left_x,top_y)、(right_x,top_y)、(right_x,bottom_y)、(left_x,bottom_y)。
扩展场景
如果分块规则不是固定尺寸,而是按数量均分,只需要调整分块尺寸的计算逻辑即可,比如横向分n块,那么block_w就等于img_w除以n,处理逻辑和上述示例一致。