So ändern Sie die Größe eines Bildes mit OpenCV2.0 und Python2.6

162

Ich möchte OpenCV2.0 und Python2.6 verwenden, um Bilder mit geänderter Größe anzuzeigen. Ich habe das Beispiel unter http://opencv.willowgarage.com/documentation/python/cookbook.html verwendet und übernommen, aber leider ist dieser Code für OpenCV2.1 und scheint nicht mit 2.0 zu funktionieren. Hier mein Code:

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)

Da kann ich nicht benutzen

cv.LoadImageM

ich benutzte

cv.LoadImage

Stattdessen war dies in anderen Anwendungen kein Problem. Trotzdem hat cv.iplimage keine Attributzeilen, Spalten oder Größe. Kann mir jemand einen Hinweis geben, wie man dieses Problem löst? Vielen Dank.

Bastian
quelle
4
Wenn eine der Antworten richtig war, markieren Sie sie bitte, da sie anderen helfen wird.
Michał

Antworten:

340

Wenn Sie CV2 verwenden möchten, müssen Sie die resizeFunktion verwenden.

Dadurch werden beispielsweise beide Achsen um die Hälfte verkleinert:

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

Dadurch wird die Bildgröße auf 100 Spalten (Breite) und 50 Zeilen (Höhe) geändert:

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

Eine andere Option ist die Verwendung des scipyModuls mit:

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

Es gibt offensichtlich mehr Optionen, die Sie in der Dokumentation dieser Funktionen lesen können ( cv2.resize , scipy.misc.imresize ).


Update:
Laut SciPy-Dokumentation :

imresizeist in SciPy 1.0.0 veraltet und wird in 1.2.0 entfernt.
Verwenden Sie skimage.transform.resizestattdessen.

Beachten Sie , dass Sie möglicherweise tatsächlich eine Größenänderung wünschen , wenn Sie die Größe ändern möchten skimage.transform.rescale.

emem
quelle
1
Verliert die Funktion resize () nicht, dass das Bild Informationen über sich selbst verliert?
8
Ja, Sie können das Bild nicht verkleinern, ohne Informationen zu verlieren.
Rafael_Espericueta
1
Die Implementierung von opencv (0,05 ms pro Bild) scheint viel schneller zu sein als die Implementierung von scipy (0,33 ms pro Bild). Ich habe die Größe von 210x160x1 auf 84x84x1 Bilder mit bilinearer Interpolation geändert.
Gizzmole
@gizzmole Interessante Einblicke. Ich habe weder die Effizienz der Implementierungen getestet noch die Ergebnisse verglichen - daher kann das Endergebnis auch geringfügig abweichen. Haben Sie getestet, ob die Größe der Bilder bitweise übereinstimmt?
Emem
Vielen Dank für den Hinweis, dass die Größenänderungsfunktion (W * H) ist, während cv2 als (H * W)
gedruckt wird
59

Beispiel Verdoppelung der Bildgröße

Es gibt zwei Möglichkeiten, die Größe eines Bildes zu ändern. Die neue Größe kann angegeben werden:

  1. Manuell;

    height, width = src.shape[:2]

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

  2. Durch einen Skalierungsfaktor.

    dst = cv2.resize(src, None, fx = 2, fy = 2, interpolation = cv2.INTER_CUBIC)Dabei ist fx der Skalierungsfaktor entlang der horizontalen Achse und fy entlang der vertikalen Achse.

Um ein Bild zu verkleinern, sieht es im Allgemeinen mit der INTER_AREA-Interpolation am besten aus, während es zum Vergrößern eines Bildes im Allgemeinen mit INTER_CUBIC (langsam) oder INTER_LINEAR (schneller, aber immer noch in Ordnung) am besten aussieht.

Beispiel Bild verkleinern, um eine maximale Höhe / Breite zu erreichen (Seitenverhältnis beibehalten)

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

Verwenden Sie Ihren Code mit 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
quelle
Ihre Lösung, die die Skalierungsfaktoren verwendet, gibt einen Fehler in cv2.resize () zurück, der besagt, dass src weder ein Numpy-Array noch ein Skalar ist. Bitte beraten?
BenP
hast du getan: src = cv2.imread('YOUR_PATH_TO_IMG')und das 'YOUR_PATH_TO_IMG' auf den Pfad deines eigenen Bildes bearbeitet?
João Cartucho
tut cv2.resizeautomatisch verwendet Klotzen? Wie groß ist das Fenster, das mit der gewünschten Ausgabegröße erstellt wird (width/10, height/10)?
Seralouk
@ Makaros Sie erhalten ein Bild, das sowohl in der Breite als auch in der Höhe 10x kleiner ist
João Cartucho
@ JoãoCartucho ja ich verstehe das. Wenn jedoch next_neighbors verwendet wird, sollte ein Fenster hinter den Kulissen angewendet werden. Dies ist, was ich
frage
8

Sie können die GetSize-Funktion verwenden, um diese Informationen abzurufen. Cv.GetSize (im) gibt ein Tupel mit der Breite und Höhe des Bildes zurück. Sie können auch im.depth und img.nChan verwenden, um weitere Informationen zu erhalten.

Und um die Größe eines Bildes zu ändern, würde ich einen etwas anderen Prozess verwenden, mit einem anderen Bild anstelle einer Matrix. Es ist besser, mit demselben Datentyp zu arbeiten:

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

Hoffe das hilft ;)

Julien

jlengrand
quelle
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
quelle
tut cv2.resizeautomatisch verwendet Klotzen? Wie groß ist das Fenster, das mit (w, target_height)Argumenten erstellt wird?
Seralouk
4

Hier ist eine Funktion zum Hoch- oder Verkleinern eines Bildes um die gewünschte Breite oder Höhe unter Beibehaltung des Seitenverhältnisses

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

Verwendung

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

Verwenden Sie dieses Beispielbild

Geben Sie hier die Bildbeschreibung ein

Einfach auf width=100(links) verkleinern oder auf width=300(rechts) hochskalieren

Geben Sie hier die Bildbeschreibung ein Geben Sie hier die Bildbeschreibung ein

nathancy
quelle