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')