2014-10-29 15 views
9

Zauważyłem coś dziwnego w scipy.misc.resize - wygląda na to, że za pomocą dowolnej metody interpolacji innej niż "najbliższa" uzyskuje się przesunięcie o około 1x1 piksela z (0,0) w wynikowym obrazie.Zmiana rozmiaru obrazu SciPy - oczekiwane zachowanie lub błąd?

Oto całkowicie syntetyczny przykład biorąc obraz 3x3 do 6x6:

>>> src 
array([[ 0., 0., 0.], 
     [ 0., 64., 0.], 
     [ 0., 0., 0.]]) 

>>> imresize(src, (6, 6), interp='bicubic',mode='F') 
array([[ 1., 0., -5., -8., -5., 0.], 
     [ 0., 0., 0., 0., 0., 0.], 
     [ -5., 0., 25., 40., 25., 0.], 
     [ -8., 0., 40., 64., 40., 0.], 
     [ -5., 0., 25., 40., 25., 0.], 
     [ 0., 0., 0., 0., 0., 0.]], dtype=float32) 
>>> imresize(src, (6, 6), interp='bilinear',mode='F') 
array([[ 0., 0., 0., 0., 0., 0.], 
     [ 0., 0., 0., 0., 0., 0.], 
     [ 0., 0., 16., 32., 16., 0.], 
     [ 0., 0., 32., 64., 32., 0.], 
     [ 0., 0., 16., 32., 16., 0.], 
     [ 0., 0., 0., 0., 0., 0.]], dtype=float32) 
>>> imresize(src, (6, 6), interp='nearest',mode='F') 
array([[ 0., 0., 0., 0., 0., 0.], 
     [ 0., 0., 0., 0., 0., 0.], 
     [ 0., 0., 64., 64., 0., 0.], 
     [ 0., 0., 64., 64., 0., 0.], 
     [ 0., 0., 0., 0., 0., 0.], 
     [ 0., 0., 0., 0., 0., 0.]], dtype=float32) 

Teraz wydaje się, że środek ciężkości przesuwa się na bilinear i bicubic interpolacji, ale nie przesuwa się do najbliższego interpolacji. Dotyczy to zarówno wielkości parzystych, jak i nieparzystych.

Zdaję sobie sprawę, że różne definicje współrzędnych będących pikselowymi środkami lub pikselami lub traktujące piksele jako próbki punktowe lub prostokąty dadzą nieco inne wyniki podczas resamplingu, ale wydaje się, że jest to poważny problem (chyba że czegoś mi brakuje) .

Oto kolejny przykład, który pokazuje zmiany jaśniej:

>>> imresize(src, (7, 3), interp='bilinear',mode='F') 
array([[ 0.  , 0.  , 0.  ], 
     [ 0.  , 0.  , 0.  ], 
     [ 0.  , 11.4285717, 11.4285717], 
     [ 0.  , 25.1428566, 25.1428566], 
     [ 0.  , 25.1428566, 25.1428566], 
     [ 0.  , 11.4285717, 11.4285717], 
     [ 0.  , 0.  , 0.  ]], dtype=float32) 

Ponieważ nie pozioma zmiana rozmiaru wystąpił, nie spodziewałbym współrzędna pozioma mojego środka masy poruszać w ogóle, ale to wyraźnie przesuwa się od od 1,0 do 1,5.

Czy to błąd, czy coś mi brakuje?

+1

To jest bardzo interesujące. Obserwowałem podobne rzeczy nawet w "PIL", ale nie mam natychmiastowego wyjaśnienia. Twoje rozumowanie dotyczące "centrum pikseli" i "krawędzi pikseli" może być wiodącym (chociaż sugeruje to, że piksele są kwadratami zamiast punktami 0d), a także rozważaniami granicznymi i dodatkowymi efektami z niecałkowitą wielokrotną zmianą rozmiaru. Bardzo zainteresowany wszystkim, co może rzucić światło tutaj. – eickenberg

+1

Okazuje się, że scipy faktycznie używa 'PIL' (zobacz funkcję' toimage' w innym miejscu [tego pliku] (https://github.com/scipy/scipy/blob/master/scipy/misc/pilutil.py#L392)) – eickenberg

Odpowiedz

0

Wygląda na to, że jest to błąd. Napisałem następujący krótki fragment:

from scipy.misc import * 
from scipy.ndimage import measurements 
import numpy as np 

src = imread("src.png") 
cbc = src 
lnr = src 
nrs = src 

for idx in xrange(0, 128): 
    cbc = imresize(cbc, tuple(2 * i for i in cbc.shape), interp='bicubic', mode='F') 
    cbc = imresize(cbc, src.shape, interp='bicubic', mode='F') 

    lnr = imresize(lnr, tuple(2 * i for i in lnr.shape), interp='bilinear', mode='F') 
    lnr = imresize(lnr, src.shape, interp='bicubic', mode='F') 

    nrs = imresize(nrs, tuple(2 * i for i in nrs.shape), interp='nearest', mode='F') 
    nrs = imresize(nrs, src.shape, interp='nearest', mode='F') 

    imsave("nrs_%03d.png" % (idx), nrs) 
    imsave("lnr_%03d.png" % (idx), lnr) 
    imsave("cbc_%03d.png" % (idx), cbc) 

a dwuliniowe/Bicubic obrazy dosłownie odejść od (0,0) każdego obrazu, natomiast najbliższy pozostaje wyrównany.

Sprawdzę z osobami z PIL/SciPy, czy nie jest już poprawiona czy nie.

+0

Czy doszło do zgłoszenia zgłoszenia błędu w PIL i/lub SciPy? Mam teraz problem z tym zachowaniem. – aganders3

+2

Tak: https://github.com/scipy/scipy/issues/4112 –