Hình ảnh hộp thư con trăn

Khi chúng ta đang sử dụng mạng thần kinh tích chập, hầu hết thời gian, chúng ta cần sửa kích thước hình ảnh đầu vào để cung cấp cho mạng. Thực tế thông thường là thay đổi kích thước hình ảnh đầu vào thành kích thước nhất định (tỷ lệ khung hình của hình ảnh không còn được giữ nguyên) và sau đó cắt ngẫu nhiên một miếng vá có kích thước cố định từ hình ảnh đã thay đổi kích thước. Thực tiễn này có thể hoạt động tốt để phân loại hình ảnh trong đó các chi tiết nhỏ có thể không cần thiết. Nhưng đối với Truy xuất hình ảnh, chúng tôi muốn giữ nguyên tỷ lệ khung hình của hình ảnh. Trong bài viết này, mình sẽ tổng hợp các cách resize ảnh thành hình vuông với padding và giữ nguyên tỉ lệ ảnh

Ý tưởng chính là trước tiên thay đổi kích thước hình ảnh đầu vào sao cho kích thước tối đa của nó bằng với kích thước đã cho. Sau đó, chúng tôi đệm hình ảnh đã thay đổi kích thước để làm cho hình vuông. Một số gói trong Python có thể dễ dàng đạt được điều này

Sử dụng PIL

PIL là gói xử lý ảnh phổ biến trong Python. Chúng tôi có thể sử dụng mô-đun Image hoặc mô-đun ImageOps để đạt được những gì chúng tôi muốn

Thay đổi kích thước và đệm với mô-đun Image

Đầu tiên chúng ta tạo một hình vuông trống, sau đó chúng ta dán hình ảnh đã thay đổi kích thước vào đó để tạo thành một hình ảnh mới. mã là

from PIL import Image, ImageOps

desired_size = 368
im_pth = "/home/jdhao/test.jpg"

im = Image.open(im_pth)
old_size = im.size  # old_size[0] is in (width, height) format

ratio = float(desired_size)/max(old_size)
new_size = tuple([int(x*ratio) for x in old_size])
# use thumbnail() or resize() method to resize the input image

# thumbnail is a in-place operation

# im.thumbnail(new_size, Image.ANTIALIAS)

im = im.resize(new_size, Image.ANTIALIAS)
# create a new image and paste the resized on it

new_im = Image.new("RGB", (desired_size, desired_size))
new_im.paste(im, ((desired_size-new_size[0])//2,
                    (desired_size-new_size[1])//2))

new_im.show()

Thay đổi kích thước và đệm với mô-đun ImageOps

Mô-đun PIL ImageOps có một expand() function sẽ thêm đường viền vào mặt 4 của hình ảnh. Chúng ta cần tính toán chiều dài phần đệm ở 4 cạnh của hình ảnh đã thay đổi kích thước trước khi áp dụng phương pháp này

delta_w = desired_size - new_size[0]
delta_h = desired_size - new_size[1]
padding = (delta_w//2, delta_h//2, delta_w-(delta_w//2), delta_h-(elta_h//2))
new_im = ImageOps.expand(im, padding)

new_im.show()

Sử dụng OpenCV

Trong OpenCV, chúng tôi có copyMakeBorder tiện dụng trong việc tạo đường viền. Mã đầy đủ để thay đổi kích thước và đệm một hình ảnh như sau