2015-05-06 9 views
8

Ich versuche, die Gradient Vector Field eines Bildes mit Python (ähnlich this matlab question) zu bekommen.Bild Verlaufsvektor Feld in Python

Dies ist das Originalbild: http:/ /dcc.fceia.unr.edu.ar/~rbaravalle/gradient/test.png

Hier ist mein Code:

import numpy as np 
import matplotlib.pyplot as plt 
import Image 
from PIL import ImageFilter 

I = Image.open('test.png').transpose(Image.FLIP_TOP_BOTTOM) 
I = I.filter(ImageFilter.BLUR) 
p = np.asarray(I) 
w,h = I.size 
y, x = np.mgrid[0:h:500j, 0:w:500j] 

dy, dx = np.gradient(p) 
skip = (slice(None, None, 3), slice(None, None, 3)) 

fig, ax = plt.subplots() 
im = ax.imshow(I, extent=[x.min(), x.max(), y.min(), y.max()]) 
ax.quiver(x[skip], y[skip], dx[skip], dy[skip]) 

ax.set(aspect=1, title='Quiver Plot') 
plt.show() 

Dies ist das Ergebnis: http://dcc.fceia.unr.edu.ar/~rbaravalle/gradient/result.png

Das Problem ist, dass die Vektoren nicht korrekt zu sein scheinen. Dieser Punkt wird deutlicher, wenn man in dem Bild vergrößern:

http://dcc.fceia.unr.edu.ar/~rbaravalle/gradient/result2.png

Warum einige der Vektoren auf den Mittelpunkt, wie erwartet, während andere dies nicht tun?

Vielleicht gibt es ein Problem mit dem Ergebnis des Anrufs np.gradient?

Antwort

7

Ich denke, Ihre seltsamen Ergebnisse sind, zumindest teilweise, weil p vom Typ uint8 ist. Sogar numpy diff führt zu eindeutig falschen Werten für ein Array dieses dtype. Wenn Sie in vorzeichenbehaftete Ganzzahl umwandeln, indem Sie die Definition durch die folgenden ersetzen: p = np.asarray(I).astype(int8) dann sind die Ergebnisse von diff korrekt. Der folgende Code gibt mir, was wie eine vernünftige Feld aussieht,

import numpy as np 
import matplotlib.pyplot as plt 
import Image 
from PIL import ImageFilter 

I = Image.open('./test.png') 
I = I.filter(ImageFilter.BLUR) 
p = np.asarray(I).astype('int8') 
w,h = I.size 
x, y = np.mgrid[0:h:500j, 0:w:500j] 

dy, dx = np.gradient(p) 
skip = (slice(None, None, 3), slice(None, None, 3)) 

fig, ax = plt.subplots() 
im = ax.imshow(I.transpose(Image.FLIP_TOP_BOTTOM), 
       extent=[x.min(), x.max(), y.min(), y.max()]) 
plt.colorbar(im) 
ax.quiver(x[skip], y[skip], dx[skip].T, dy[skip].T) 

ax.set(aspect=1, title='Quiver Plot') 
plt.show() 

Dies ergibt folgendes:

Solution

und hautnah das sieht aus wie man es erwarten würde,

enter image description here

+0

Großer Haken, '.astype ('int8')' funktioniert genauso gut. Es ist das "u" (unsigned), das Probleme mit negativen Verläufen verursacht (negative Werte werden zu positiven Werten gekappt) – fhdrsdg

+0

Es ist die Lösung, vielen Dank! Tatsächlich habe ich den "transpose" -Aufruf zu im = ax.imshow (I), ieim = ax.imshow (I.transpose (Image.FLIP_TOP_BOTTOM)), und dann habe ich genau das gleiche Ergebnis wie Ihr Bild. Wenn Sie möchten, ändern Sie es, damit die Leute Ihren Code direkt verwenden können. Auch ich stimme zu, dass die Verwendung von np.int8 wahrscheinlich besser ist als float. –

+0

Update: Eine "weichere" Version kann mit einem Gauß-Filter auf den Gradienten erreicht werden. zB: http://dcc.fceia.unr.edu.ar/~rbaravalle/gradient/resultSoft.png Die Code-Ergebnisse: http://dcc.fceia.unr.edu.ar/~rbaravalle/gradient/test3. py –