Cara mengubah ukuran gambar dengan OpenCV2.0 dan Python2.6

163

Saya ingin menggunakan OpenCV2.0 dan Python2.6 untuk menampilkan ukuran gambar. Saya menggunakan dan mengadopsi contoh di http://opencv.willowgarage.com/documentation/python/cookbook.html tapi sayangnya kode ini untuk OpenCV2.1 dan sepertinya tidak dapat digunakan pada 2.0. Ini kode saya:

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)

Karena saya tidak bisa menggunakan

cv.LoadImageM

Saya menggunakan

cv.LoadImage

sebagai gantinya, yang tidak ada masalah di aplikasi lain. Namun demikian cv.iplimage tidak memiliki baris atribut, cols atau ukuran. Adakah yang bisa memberi saya petunjuk, bagaimana mengatasi masalah ini? Terima kasih.

Bastian
sumber
4
Jika ada jawaban yang benar, tandai karena akan membantu orang lain.
Michał

Jawaban:

342

Jika Anda ingin menggunakan CV2, Anda harus menggunakan resizefungsinya.

Misalnya, ini akan mengubah ukuran kedua sumbu setengah:

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

dan ini akan mengubah ukuran gambar menjadi 100 cols (lebar) dan 50 baris (tinggi):

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

Pilihan lain adalah menggunakan scipymodul, dengan menggunakan:

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

Jelas ada lebih banyak opsi yang dapat Anda baca dalam dokumentasi fungsi-fungsi tersebut ( cv2.resize , scipy.misc.imresize ).


Pembaruan:
Menurut dokumentasi SciPy :

imresizetidak digunakan lagi dalam SciPy 1.0.0, dan akan dihapus dalam 1.2.0.
Gunakan skimage.transform.resizesebagai gantinya.

Perhatikan bahwa jika Anda ingin mengubah ukuran berdasarkan faktor , Anda mungkin sebenarnya menginginkannya skimage.transform.rescale.

emem
sumber
1
tidakkah fungsi resize () membuat gambar kehilangan informasi tentang dirinya sendiri?
8
Ya, Anda tidak dapat mengurangi ukuran gambar tanpa kehilangan informasi.
Rafael_Espericueta
1
Implementasi opencv (0,05 ms per gambar) tampaknya jauh lebih cepat daripada implementasi scipy (gambar 0,33 ms). Saya mengubah ukuran gambar 210x160x1 menjadi 84x84x1 dengan interpolasi bilinear.
gizzmole
@gizzmole Wawasan menarik. Saya tidak menguji efisiensi implementasi, atau membandingkan hasilnya - jadi hasil akhirnya juga mungkin sedikit berbeda. Apakah Anda menguji untuk melihat gambar yang diubah ukurannya cocok dengan bitwise?
emem
Thaks untuk menunjukkan bahwa fungsi mengubah ukuran mengambil (W * H) sedangkan cv2 mencetak sebagai (H * W)
Shivam Kotwalia
59

Contoh menggandakan ukuran gambar

Ada dua cara untuk mengubah ukuran gambar. Ukuran baru dapat ditentukan:

  1. Secara manual;

    height, width = src.shape[:2]

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

  2. Dengan faktor penskalaan.

    dst = cv2.resize(src, None, fx = 2, fy = 2, interpolation = cv2.INTER_CUBIC), di mana fx adalah faktor penskalaan sepanjang sumbu horizontal dan fy sepanjang sumbu vertikal.

Untuk mengecilkan gambar, biasanya akan terlihat paling baik dengan interpolasi INTER_AREA, sedangkan untuk memperbesar gambar, biasanya akan terlihat lebih baik dengan INTER_CUBIC (lambat) atau INTER_LINEAR (lebih cepat tapi tetap terlihat OK).

Contoh menyusutkan gambar agar sesuai dengan tinggi / lebar maks (menjaga aspek rasio)

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

Menggunakan kode Anda dengan 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()
João Cartucho
sumber
solusi Anda menggunakan faktor penskalaan mengembalikan kesalahan pada cv2.resize () mengatakan 'src bukan array numpy, juga skalar.' mohon saran?
BenP
apakah Anda melakukannya: src = cv2.imread('YOUR_PATH_TO_IMG')dan mengedit 'YOUR_PATH_TO_IMG' ke jalur gambar Anda sendiri?
João Cartucho
apakah cv2.resizesecara otomatis menggunakan bantalan? berapa ukuran jendela yang dibuat menggunakan ukuran output yang diinginkan (width/10, height/10)?
seralouk
@makaros Anda mendapatkan gambar yang 10x lebih kecil baik lebar dan tinggi
João Cartucho
@ JoãoCartucho ya saya mengerti ini. Tetapi ketika terdekat_neighbors digunakan maka jendela harus diterapkan di belakang layar. Inilah yang saya tanyakan ..
seralouk
8

Anda bisa menggunakan fungsi GetSize untuk mendapatkan informasi itu, cv.GetSize (im) akan mengembalikan tuple dengan lebar dan tinggi gambar. Anda juga dapat menggunakan im.depth dan img.nChan untuk mendapatkan informasi lebih lanjut.

Dan untuk mengubah ukuran gambar, saya akan menggunakan proses yang sedikit berbeda, dengan gambar lain, bukan matriks. Lebih baik mencoba bekerja dengan tipe data yang sama:

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

Semoga ini membantu ;)

Julien

jlengrand
sumber
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)
AndyP
sumber
apakah cv2.resizesecara otomatis menggunakan bantalan? berapa ukuran jendela yang dibuat menggunakan (w, target_height)argumen?
seralouk
4

Berikut adalah fungsi untuk memperbesar atau memperkecil skala gambar dengan lebar atau tinggi yang diinginkan sambil mempertahankan rasio aspek

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

Pemakaian

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

Menggunakan contoh gambar ini

masukkan deskripsi gambar di sini

Cukup turunkan ke width=100(kiri) atau naik ke width=300(kanan)

masukkan deskripsi gambar di sini masukkan deskripsi gambar di sini

nathancy
sumber