目錄
- 1. Numpy切片
- 1.1 注意事項
- 1.2 代碼示例
- 2. cv2.selectROI()
- 2.1 語法結構
- 2.2 注意事項
- 2.3 代碼示例
- 3. Pillow.crop
- 3.1 語法結構
- 3.2 注意事項
- 3.3 代碼示例
- 4. 擴展示例:單張大圖裁切成多張小圖
- 5. 總結
1. Numpy切片
語法結構:
retval = img[y:y+h, x:x+w] #對圖像 img 裁剪并返回指定的矩陣區域圖像。
img
:圖像數據,nparray 多維數組x, y
:整數,像素值,裁剪矩形區域左上角的坐標值w, h
:整數,像素值,裁剪矩形區域的寬度、高度retval
:裁剪后獲得的 OpenCV 圖像,nparray 多維數組
1.1 注意事項
- Numpy 多維數組的切片是原始數組的淺拷貝,切片修改后原始數組也會改變。推薦采用 .copy() 進行深拷貝,得到原始圖像的副本。
- Numpy 數組切片,當上界或下界為數組邊界時可以省略,如:img[y:, :x] 表示高度方向從 y 至圖像底部(像素ymax),寬度方向從圖像左側(像素 0)至 x。
1.2 代碼示例
import cv2imgFile = "./img/lena.jpg"
img1 = cv2.imread(imgFile, flags=1) # flags=1 讀取彩色圖像(BGR)
xmin, ymin, w, h = 200, 200, 200, 200 # 矩形裁剪區域 (ymin:ymin+h, xmin:xmin+w) 的位置參數
imgCrop = img1[ymin:ymin + h, xmin:xmin + w].copy() # 切片獲得裁剪后保留的圖像區域
cv2.imshow("CropDemo", imgCrop) # 在窗口顯示 彩色隨機圖像
cv2.waitKey(0)
cv2.destroyAllWindows()
2. cv2.selectROI()
2.1 語法結構
cv2.selectROI(windowName, img, showCrosshair=None, fromCenter=None):#可以通過鼠標選擇感興趣的矩形區域(ROI)
windowName
:選擇的區域被顯示在的窗口的名字img
:要在什么圖片上選擇ROIshowCrosshair
:是否在矩形框里畫十字線.fromCenter
:是否是從矩形框的中心開始畫
2.2 注意事項
- 由于
cv2.selectROI
是一個交互式的函數,它可能不適合用于自動化腳本或沒有圖形用戶界面的環境。在這種情況下,你可能需要尋找其他方法來選擇圖像中的 ROI,例如使用固定坐標、圖像分割算法等。
2.3 代碼示例
import cv2imgFile = "img/lena.jpg"
img1 = cv2.imread(imgFile, flags=1) # flags=1 讀取彩色圖像(BGR)
roi = cv2.selectROI(img1, showCrosshair=True, fromCenter=False)
xmin, ymin, w, h = roi # 矩形裁剪區域 (ymin:ymin+h, xmin:xmin+w) 的位置參數
imgROI = img1[ymin:ymin + h, xmin:xmin + w].copy() # 切片獲得裁剪后保留的圖像區域
cv2.imshow("RIODemo", imgROI)
cv2.waitKey(0)
cv2.destroyAllWindows()
3. Pillow.crop
3.1 語法結構
retval = Image.crop(left, up, right, lower) #可以通過鼠標選擇感興趣的矩形區域(ROI)
left
: 整數,表示裁剪區域左上角的 x 坐標。up
:整數,表示裁剪區域左上角的 y 坐標。right
:整數,表示裁剪區域右下角的 x 坐標。這個值通常大于 left。below
:整數,表示裁剪區域右下角的 y 坐標。這個值通常大于 upper。retval
:一個新的 Image 對象,原始圖像中被裁剪出來的矩形區域
3.2 注意事項
crop()
函數接受一個包含四個數字的元組參數,表示裁剪區域的左上角和右下角的坐標。這個元組的格式是(left, upper, right, lower),其中left和upper是裁剪區域的左上角坐標,right和lower是右下角坐標。坐標的原點(0,0)通常在圖像的左上角。Pillow
庫使用坐標系的原點在左上角,x軸向右增加,y軸向下增加。這與一些其他圖像處理庫(如OpenCV)的坐標系原點在左下角的約定不同,需要注意坐標的順序和方向。- 裁剪區域的坐標必須在圖像的邊界內。如果裁剪區域的坐標超出了圖像的邊界,將會引發一個ValueError異常。因此,在調用crop()函數之前,最好先檢查裁剪區域的坐標是否有效。
crop()
函數不會修改原始圖像,而是返回一個新的裁剪后的圖像對象。原始圖像保持不變,如果需要保存裁剪后的圖像,需要將其保存到文件或進行其他操作。
3.3 代碼示例
from PIL import Image
import matplotlib.pyplot as pltimgFile = "./img/lena.jpg"
img = Image.open(imgFile) # W*H
plt.rcParams['font.sans-serif'] = ['FangSong'] # 支持中文標簽
plt.subplot(221), plt.title("原圖"), plt.axis('off')
plt.imshow(img)
img_c = img.crop([img.size[0] / 4, img.size[1] / 4, img.size[0] * 3 / 4, img.size[1] * 3 / 4])
plt.rcParams['font.sans-serif'] = ['FangSong'] # 支持中文標簽
plt.subplot(222), plt.title("裁切之后"), plt.axis('off')
plt.imshow(img_c)
plt.show()
4. 擴展示例:單張大圖裁切成多張小圖
from PIL import ImageimgFile = "./img/lena.jpg"
img = Image.open(imgFile)
size = img.size
print(size)
# 準備將圖片切割成9張小圖片
weight = int(size[0] // 3)
height = int(size[1] // 3)
# 切割后的小圖的寬度和高度
print(weight, height)
for j in range(3):for i in range(3):box = (weight * i, height * j, weight * (i + 1), height * (j + 1))region = img.crop(box)region.save('{}{}.png'.format(j, i))
5. 總結
Numpy
切片和Pillow.crop()
都是非交互式的裁剪方法,適用于在代碼中直接指定裁剪區域。cv2.selectROI()
是一個交互式的裁剪方法,允許用戶通過圖形界面選擇ROI。