Cách thay đổi kích thước hình ảnh với OpenCV2.0 và Python2.6


163

Tôi muốn sử dụng OpenCV2.0 và Python2.6 để hiển thị hình ảnh đã thay đổi kích thước. Tôi đã sử dụng và chấp nhận ví dụ tại http: //opencv.wvelgarage.com/documentation/python/cookbook.html nhưng không may là mã này dành cho OpenCV2.1 và dường như không hoạt động trên 2.0. Đây là mã của tôi:

import os, glob
import cv

ulpath = "exampleshq/"

for infile in glob.glob( os.path.join(ulpath, "*.jpg") ):
    im = cv.LoadImage(infile)
    thumbnail = cv.CreateMat(im.rows/10, im.cols/10, cv.CV_8UC3)
    cv.Resize(im, thumbnail)
    cv.NamedWindow(infile)
    cv.ShowImage(infile, thumbnail)
    cv.WaitKey(0)
    cv.DestroyWindow(name)

Vì tôi không thể sử dụng

cv.LoadImageM

Tôi đã sử dụng

cv.LoadImage

thay vào đó, không có vấn đề trong các ứng dụng khác. Tuy nhiên, cv.iplimage không có hàng thuộc tính, cols hoặc kích thước. Bất cứ ai có thể cho tôi một gợi ý, làm thế nào để giải quyết vấn đề này? Cảm ơn.


4
Nếu bất kỳ câu trả lời nào là đúng, vui lòng đánh dấu nó vì nó sẽ giúp người khác.
Michał

Câu trả lời:


342

Nếu bạn muốn sử dụng CV2, bạn cần sử dụng resize chức năng.

Ví dụ: điều này sẽ thay đổi kích thước cả hai trục bằng một nửa:

small = cv2.resize(image, (0,0), fx=0.5, fy=0.5) 

và điều này sẽ thay đổi kích thước hình ảnh để có 100 cols (chiều rộng) và 50 hàng (chiều cao):

resized_image = cv2.resize(image, (100, 50)) 

Một tùy chọn khác là sử dụng scipymô-đun, bằng cách sử dụng:

small = scipy.misc.imresize(image, 0.5)

Rõ ràng có nhiều tùy chọn hơn mà bạn có thể đọc trong tài liệu về các chức năng đó ( cv2.resize , scipy.misc.imresize ).


Cập nhật:
Theo tài liệu SciPy :

imresizeđang bị phản đối trong scipy 1.0.0, và sẽ được loại bỏ trong 1.2.0.
Sử dụng skimage.transform.resizethay thế.

Lưu ý rằng nếu bạn đang tìm kiếm thay đổi kích thước theo một yếu tố , bạn thực sự có thể muốn skimage.transform.rescale.


1
không phải hàm resize () làm cho hình ảnh mất thông tin về chính nó?

8
Có, bạn không thể giảm kích thước của hình ảnh mà không mất thông tin.
Rafael_Espericueta

1
Việc triển khai opencv (0,05ms trên mỗi hình ảnh) dường như nhanh hơn nhiều so với triển khai scipy (hình ảnh 0,33ms). Tôi thay đổi kích thước hình ảnh 210x160x1 thành 84x84x1 với phép nội suy song tuyến tính.
gizzmole

@gizzmole Cái nhìn sâu sắc thú vị. Tôi đã không kiểm tra hiệu quả của việc thực hiện, cũng không so sánh kết quả - vì vậy kết quả cuối cùng cũng có thể hơi khác nhau. Bạn đã kiểm tra để xem hình ảnh thay đổi kích thước phù hợp với bit?
emem

Thaks vì đã chỉ ra rằng chức năng thay đổi kích thước mất (W * H) trong khi cv2 in thành (H * W)
Shivam Kotwalia

59

Ví dụ nhân đôi kích thước hình ảnh

Có hai cách để thay đổi kích thước hình ảnh. Kích thước mới có thể được chỉ định:

  1. Thủ công;

    height, width = src.shape[:2]

    dst = cv2.resize(src, (2*width, 2*height), interpolation = cv2.INTER_CUBIC)

  2. Bằng một hệ số tỷ lệ.

    dst = cv2.resize(src, None, fx = 2, fy = 2, interpolation = cv2.INTER_CUBIC), trong đó fx là hệ số tỷ lệ dọc theo trục ngang và fy dọc theo trục dọc.

Để thu nhỏ hình ảnh, nhìn chung sẽ trông đẹp nhất với phép nội suy INTER_AREA, trong khi để phóng to hình ảnh, nhìn chung sẽ trông đẹp nhất với INTER_CUBIC (chậm) hoặc INTER_LINEAR (nhanh hơn nhưng vẫn ổn).

Ví dụ thu nhỏ hình ảnh để phù hợp với chiều cao / chiều rộng tối đa (giữ tỷ lệ khung hình)

import cv2

img = cv2.imread('YOUR_PATH_TO_IMG')

height, width = img.shape[:2]
max_height = 300
max_width = 300

# only shrink if img is bigger than required
if max_height < height or max_width < width:
    # get scaling factor
    scaling_factor = max_height / float(height)
    if max_width/float(width) < scaling_factor:
        scaling_factor = max_width / float(width)
    # resize image
    img = cv2.resize(img, None, fx=scaling_factor, fy=scaling_factor, interpolation=cv2.INTER_AREA)

cv2.imshow("Shrinked image", img)
key = cv2.waitKey()

Sử dụng mã của bạn với cv2

import cv2 as cv

im = cv.imread(path)

height, width = im.shape[:2]

thumbnail = cv.resize(im, (round(width / 10), round(height / 10)), interpolation=cv.INTER_AREA)

cv.imshow('exampleshq', thumbnail)
cv.waitKey(0)
cv.destroyAllWindows()

giải pháp của bạn bằng cách sử dụng các hệ số tỷ lệ sẽ trả về lỗi trên cv2.resize () nói rằng 'src không phải là một mảng numpy, cũng không phải là vô hướng.' Xin tư vấn?
BenP

bạn đã làm: src = cv2.imread('YOUR_PATH_TO_IMG')và chỉnh sửa 'YOU_PATH_TO_IMG' theo đường dẫn của hình ảnh của chính bạn?
João Cartucho

không cv2.resizetự động sử dụng đệm? kích thước của cửa sổ được tạo bằng kích thước đầu ra mong muốn là (width/10, height/10)gì?
seralouk

@makaros bạn nhận được một hình ảnh nhỏ hơn gấp 10 lần cả về chiều rộng và chiều cao
João Cartucho

@ JoãoCartucho vâng tôi hiểu điều này. Nhưng khi Recent_neighbor được sử dụng thì một cửa sổ sẽ được áp dụng phía sau hậu trường. Đây là những gì tôi đang hỏi ..
seralouk

8

Bạn có thể sử dụng chức năng GetSize để lấy các thông tin đó, cv.GetSize (im) sẽ trả về một tuple với chiều rộng và chiều cao của hình ảnh. Bạn cũng có thể sử dụng im.depth và img.nChan để có thêm thông tin.

Và để thay đổi kích thước một hình ảnh, tôi sẽ sử dụng một quy trình hơi khác, với một hình ảnh khác thay vì ma trận. Tốt hơn là nên thử làm việc với cùng loại dữ liệu:

size = cv.GetSize(im)
thumbnail = cv.CreateImage( ( size[0] / 10, size[1] / 10), im.depth, im.nChannels)
cv.Resize(im, thumbnail)

Hi vọng điêu nay co ich ;)

Julien


6
def rescale_by_height(image, target_height, method=cv2.INTER_LANCZOS4):
    """Rescale `image` to `target_height` (preserving aspect ratio)."""
    w = int(round(target_height * image.shape[1] / image.shape[0]))
    return cv2.resize(image, (w, target_height), interpolation=method)

def rescale_by_width(image, target_width, method=cv2.INTER_LANCZOS4):
    """Rescale `image` to `target_width` (preserving aspect ratio)."""
    h = int(round(target_width * image.shape[0] / image.shape[1]))
    return cv2.resize(image, (target_width, h), interpolation=method)

không cv2.resizetự động sử dụng đệm? kích thước của cửa sổ được tạo bằng các (w, target_height)đối số là gì?
seralouk

4

Đây là một chức năng để nâng cấp hoặc thu nhỏ hình ảnh theo chiều rộng hoặc chiều cao mong muốn trong khi duy trì tỷ lệ khung hình

# Resizes a image and maintains aspect ratio
def maintain_aspect_ratio_resize(image, width=None, height=None, inter=cv2.INTER_AREA):
    # Grab the image size and initialize dimensions
    dim = None
    (h, w) = image.shape[:2]

    # Return original image if no need to resize
    if width is None and height is None:
        return image

    # We are resizing height if width is none
    if width is None:
        # Calculate the ratio of the height and construct the dimensions
        r = height / float(h)
        dim = (int(w * r), height)
    # We are resizing width if height is none
    else:
        # Calculate the ratio of the width and construct the dimensions
        r = width / float(w)
        dim = (width, int(h * r))

    # Return the resized image
    return cv2.resize(image, dim, interpolation=inter)

Sử dụng

import cv2

image = cv2.imread('1.png')
cv2.imshow('width_100', maintain_aspect_ratio_resize(image, width=100))
cv2.imshow('width_300', maintain_aspect_ratio_resize(image, width=300))
cv2.waitKey()

Sử dụng hình ảnh ví dụ này

nhập mô tả hình ảnh ở đây

Đơn giản chỉ cần hạ cấp xuống width=100(trái) hoặc nâng cấp lên width=300(phải)

nhập mô tả hình ảnh ở đây nhập mô tả hình ảnh ở đây

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.