Python如何裁剪圖片
And how the cropped image transforms the coordinates of the original image
Sliding window is required to crop the image
But after cropping the image
Recognized small box What are the coordinates of the original image?
比如 原圖
1000*1000
裁剪N個小圖
in one of the small images
畫框
But the box in this small picture are the coordinates of the thumbnail
then this box 在 原圖中的 坐標 是什麼


opencv read pictures,是 numpy.ndarray 類型,You can use the slice operation to crop the image img[y1:y2, x1:x2].copy(),也可以直接用 numpy.hsplit 分割圖片,It must be ensured that the width and height can be divided equally
import cv2
import numpy as np
from requests import get
img_url = 'https://avatar-static.segmentfault.com/569/558/569558099-1030000000094051_huge256'
img: np.ndarray = cv2.imdecode(np.frombuffer(get(img_url).content, np.uint8), cv2.IMREAD_COLOR)
h, w = img.shape[:2]
nRows, nCols = 4, 4
sub_h, sub_w = h//nRows, w//nCols
# 分割圖片
sub_imgs = np.array(np.hsplit(np.array(np.hsplit(img, nCols)), nRows))
# 填充矩形
r, c, x1, y1, x2, y2 = 2, 3, 10, 20, 54, 44
sub_imgs[r, c, y1:y2, x1:x2] = (0, 0, 255)
img[sub_h*r+y1:sub_h*r+y2, sub_w*c+x1:sub_w*c+x2] = (0, 0, 255)
# 顯示
div_w, div_color = 16, np.array([222, 222, 222], np.uint8)
img_split = np.ones((h+div_w*(nRows-1), w+div_w*(nCols-1), 3), np.uint8) * div_color
step_y, step_x = sub_h+div_w, sub_w+div_w
for i, row in enumerate(sub_imgs):
for j, sub_img in enumerate(row):
img_split[step_y*i:step_y*i+sub_h, step_x*j:step_x*j+sub_w] = sub_img
cv2.imshow('img', img)
cv2.imshow('img_split', img_split)
cv2.waitKey()

如果不能平分,可以考慮換成 numpy.array_split 分割,it will give the remaining width and height to the left w % nCols row and top h % nRows 行,如 128 * 128 分成 3 行 3 列是
import cv2
import numpy as np
from requests import get
img_url = 'https://avatar-static.segmentfault.com/569/558/569558099-1030000000094051_huge128'
img: np.ndarray = cv2.imdecode(np.frombuffer(get(img_url).content, np.uint8), cv2.IMREAD_COLOR)
nRows, nCols = 3, 3
sub_imgs = [np.array_split(row, nCols, 1) for row in np.array_split(img, nRows, 0)]
print(*([f'{img.shape[1]} * {img.shape[0]}' for img in row] for row in sub_imgs), sep='\n')
# ['43 * 43', '43 * 43', '42 * 43']
# ['43 * 43', '43 * 43', '42 * 43']
# ['43 * 42', '43 * 42', '42 * 42']give another based on pillow 庫 crop Image segmentation function for cropping images
import os
from io import BytesIO
from itertools import chain
import PIL.Image as Images
from PIL.Image import Image
from requests import get
def split_box(box: tuple[int, int, int, int], ncols: int = 1, nrows: int = 1) -> list[list[tuple[int, int, int, int]]]:
subw, extraw = divmod(box[2] - box[0], ncols)
subh, extrah = divmod(box[3] - box[1], nrows)
kx, ky = box[0] + (subw + 1) * extraw, box[1] + (subh + 1) * extrah
lr1, lr2 = range(box[0], kx + 1, subw + 1), range(kx, box[2] + 1, subw)
ul1, ul2 = range(box[1], ky + 1, subh + 1), range(ky, box[3] + 1, subh)
return [[(left, upper, right, lower)
for left, right in chain(zip(lr1[:-1], lr1[1:]), zip(lr2[:-1], lr2[1:]))]
for upper, lower in chain(zip(ul1[:-1], ul1[1:]), zip(ul2[:-1], ul2[1:]))]
def split_image(img: Image, ncols: int = 1, nrows: int = 1) -> list[list[Image]]:
return [[img.crop(box) for box in row] for row in split_box((0, 0, *img.size), ncols, nrows)]
img_url = 'https://avatar-static.segmentfault.com/569/558/569558099-1030000000094051_huge128'
img = Images.open(BytesIO(get(img_url).content))
# 分割圖片
subimgs = split_image(img, 3, 3)
subboxs = split_box((0, 0, *img.size), 3, 3)
# 填充矩形
subimgs[1][2].paste((255, 0, 0), (10, 10, 20, 20))
subx, suby = subboxs[1][2][:2]
img.paste((255, 0, 0), (subx+10, suby+10, subx+20, suby+20))
# 輸出大小
print(*([subimg.size for subimg in row] for row in subimgs), sep='\n')
# 顯示
img_split = Images.new('RGB', (img.width + 16 * 2, img.height + 16 * 2), (222, 222, 222))
for i, row in enumerate(subimgs):
for j, sub_img in enumerate(row):
img_split.paste(sub_img, (subboxs[i][j][0] + 16 * j, subboxs[i][j][1] + 16 * i))
img.show()
img_split.show()
# 保存
# os.makedirs('img', exist_ok=True)
# img.save('img/img.png')
# for i, row in enumerate(subimgs):
# for j, sub_img in enumerate(row):
# sub_img.save(f'img/subimgs[{i}][{j}].png')
