2016-03-26 4 views
4

Wir haben ein ziemlich komplexes Bildverarbeitungsskript, das in Python geschrieben wurde und PIL und numpy verwendet. Für einen der Schritte haben wir einen sehr sensitiven Mehrkanalgradienten, der eine Nachschlagetabelle ist. Sobald es erstellt wurde, wird es in mehreren verschiedenen kleineren Auflösungen gespeichert. Wenn dies jedoch geschieht, scheint der grüne Kanal, der eine von links nach rechts verlaufende Steigung aufweist, plötzlich seine Präzision zu verlieren. Es soll 1 von 255 Werten alle 50 Pixel oder so verlieren. Stattdessen beginnt es bei Werten von 2 alle 100 Pixel zu fallen. Dies verursacht große Probleme und ich kann nicht herausfinden, warum PIL es tut. Allerdings sehe ich Sprünge von 1 in anderen Teilen der Karte, also denke ich nicht, dass es ein einfaches ist, weil es ein bisschen Genauigkeit fehlt. Ich bemerkte auch auf einem anderen Kanal, es schien, als ob die ganze Karte um 1 Wert verschoben wurde. Das Ganze scheint nach der Skalierung ungenau zu sein, selbst wenn man den Filter "Nearest" verwendet.Bildverläufe werden beim Herunterskalieren mit verschiedenen Methoden ungenau

Für das Bild in voller Größe, schaffen wir es aus unserer numpy Array mit den folgenden:

image = Image.fromarray(imageIn.astype(np.uint8)) 

Wir haben es dann nach unten skalieren:

new_image = image.resize(new_size, scaleFilter) 

Die Skala ist immer die Hälfte der größten und ich habe alle verfügbaren Skalierungsoptionen ausprobiert.

Wir haben es dann zu einer PNG speichern, wie folgt:

new_image.save(file_name, 'PNG') 

wir sowohl die direkt nach dem Schritt großes speichern 1 mit dem gleichen Befehl speichern und es ist in Ordnung. Nach der Skala haben wir das Problem auf dem grünen Kanal. Jede Hilfe wäre großartig!

EDIT:

Es scheint nun, dass es likley ein Problem in SciPy ist. Das Folgende verursacht immer noch das Problem:

new_array = misc.imresize(imageIn, (x_size, y_size, 4), interp='nearest') 
    misc.imsave(file_name,new_array) 

Ich verstehe nicht, wie ich sogar die Verzerrungen mit am nächsten bekomme. Ich Zuteilung dieses Array als float64, aber es hat im Code Rundungsprobleme einzubeziehen

EDIT # 2:

ich weiter diese einen Schritt vor und OSX versuchte Programm gebaut nippt es zum Download und bekam die gleiche Verzerrung! Ich habe es dann mit Adobe After Effects probiert und es hat gut funktioniert. Ich habe dann imagemagick installiert, was jetzt funktioniert. Ich werde immer noch das Kopfgeld an jemanden vergeben, der erklären kann, warum dies bei all diesen Methoden geschieht.

EDIT # 3

Per Antrag, hier ist ein Abschnitt eines Sprites Karte skaliert und unscaled. Während ich diese erstellte, stellte ich fest, dass die eingebaute "Preview" -Anwendung des OSX auch Skalierungsprobleme verursacht, wenn ich herunterskalierte, also musste ich eigentlich Photoshop verwenden, um den ursprünglichen Clip zu erhalten.

Original:

enter image description here

mit Verzerrungen Scaled.Versuchen Sie, den grünen Kanal entlang der horizontalen Achse der Suche

enter image description here

Beachten Sie, dass diese Ausschnitte nicht der exakt gleichen Pixel sind, aber aus dem gleichen Gebiet schneiden, wie Sie durch die Form

EDIT # sehen 4

Ich habe jetzt versucht, diese Skalierung über OpenGL innerhalb der Anwendung zu tun, und ich habe festgestellt, dass es auch dort passiert! Dies hat mit einem grundlegenden Problem zu tun, bilineare Interpolation mit einer festen Anzahl von Bits zu tun?

+0

ist nicht 1/50 das gleiche wie 2/100? Ich bin verwirrt. – Piglet

+0

Es springt um 2 statt um 1, was bedeutet, dass es die halbe Präzision zu haben scheint. – David

+1

Was ist 'scaleFilter'? –

Antwort

2

Der folgende Code erscheint, das Richtige zu tun, wenn um 50% Skalierung mit skimage:

import numpy 
import skimage 
import skimage.io 

img = skimage.io.imread('uY173.png') 

import skimage.transform 

img50_order0 = skimage.img_as_ubyte(skimage.transform.rescale(img, 0.5, order=0, clip=True)) 
img50_order1 = skimage.img_as_ubyte(skimage.transform.rescale(img, 0.5, order=1, clip=True)) 

img50_lm = numpy.rint(skimage.transform.downscale_local_mean(img, (2,2,1), clip=True)) 

import scipy.ndimage.interpolation 

img50_nd = scipy.ndimage.interpolation.zoom(img, (0.5, 0.5, 1)) 

# plot section of green channel along horizontal axis 
plot(img50_order0[50, :, 1]) 
plot(img50_order1[50, :, 1]) 
plot(img50_lm[50, :, 1]) 
plot(img50_nd[50, :, 1]) 

Dies gilt nicht (soweit ich das beurteilen kann) hängen von PIL unter der Haube. Das Quellbild wird als uint8 gelesen, auf jeweils unterschiedliche Weise verarbeitet und gerundet, was zu einer uint8-Ausgabe führt. Der Unterschied zwischen all diesen ist nie mehr als 1, und die Schritte sind nie Größe 2.

Verwandte Themen