2009-12-22 18 views
7

Piszę bibliotekę do przetwarzania śledzenia spojrzeń w Pythonie i jestem raczej nowy w całym świecie numpy/scipy. Zasadniczo, zamierzam wziąć tablicę wartości (x, y) w czasie i "pomalować" jakiś kształt na płótnie o tych współrzędnych. Na przykład kształt może być niewyraźnym kołem."Malowanie" jednej tablicy na inną przy użyciu python/numpy

Operacja, którą mam na myśli, jest mniej więcej taka sama jak użycie narzędzia do malowania pędzlem w programie Photoshop.

Mam interative algorytm, który przycina mój "pędzel", aby znalazł się w granicach mojego obrazu i dodaje każdy punkt do obrazu akumulatora, ale jest powolny (!), I wydaje się, że prawdopodobnie jest znacznie łatwiejsze sposób, aby to zrobić.

Jakieś wskazówki, od czego zacząć szukać?

+0

Wygląda na to, że chcesz jakąś formę szybkiego blitu. Jednak brakuje mi wiedzy na temat Pythona, aby zasugerować dobrą odpowiedź. – Sekhat

Odpowiedz

7

W swoim pytaniu opisujesz filtr Gaussa, dla którego scipy ma wsparcie przez package. Na przykład:

from scipy import * # rand 
from pylab import * # figure, imshow 
from scipy.ndimage import gaussian_filter 

# random "image" 
I = rand(100, 100) 
figure(1) 
imshow(I) 

# gaussian filter 
J = gaussian_filter(I, sigma=10) 
figure(2) 
imshow(J) 

Oczywiście, można zastosować to na całego obrazu, lub po prostu na plastrze, używając krojenie:

J = array(I) # copy image 
J[30:70, 30:70] = gaussian_filter(I[30:70, 30:70], sigma=1) # apply filter to subregion 
figure(2) 
imshow(2) 

Do podstawowych manipulacji obrazu, Python Library obrazu (PIL) jest prawdopodobnie tym, czego chcesz.

UWAGA: do "malowania" za pomocą "pędzla", myślę, że można po prostu utworzyć boolowską tablicę z maską za pomocą pędzla. Na przykład:

# 7x7 boolean mask with the "brush" (example: a _crude_ circle) 
mask = array([[0, 0, 1, 1, 1, 0, 0], 
       [0, 1, 1, 1, 1, 1, 0], 
       [1, 1, 1, 1, 1, 1, 1], 
       [1, 1, 1, 1, 1, 1, 1], 
       [1, 1, 1, 1, 1, 1, 1], 
       [0, 1, 1, 1, 1, 1, 0], 
       [0, 0, 1, 1, 1, 0, 0]], dtype=bool) 

# random image 
I = rand(100, 100) 
# apply filter only on mask 
# compute the gauss. filter only on the 7x7 subregion, not the whole image 
I[40:47, 40:47][mask] = gaussian_filter(I[40:47, 40:47][mask], sigma=1) 
+0

Hm, to może postawić mnie na właściwej drodze - myślę, że magia krojenia pomoże mi zrobić to, czego potrzebuję. – Nate

+0

Dodałem przykład z maską binarną, może to właśnie potrzebujesz. – catchmeifyoutry

+0

to jest miłe +1 :) – Nope

0

Czy sprawdziłeś już numer Tkinter?

Python Image Library może być też pomocna.

+0

Tkinter trochę mnie alarmuje - naprawdę nie podoba mi się użycie interfejsu GUI do wykonania tablicy matematycznej. I ja znam PIL, ale tak naprawdę nie widzę, jak rozwiązuje to wszystko, czego nie robi numpy. Nadal musiałbym zrobić kilka dziwacznych gadżetów, żeby dodać tablice ...? – Nate

2

Należy naprawdę spojrzeć Andrzej Strawa motmot i libcamiface. Używa go do eksperymentów na muchy, ale jest to elastyczna biblioteka do robienia właśnie tego rodzaju pozyskiwania obrazów i przetwarzania, które robisz, myślę. Jest video z jego prezentacji na SciPy2009.

Co do scenariusza pędzel można wymienić, chciałbym zrobić kopię obrazu metodą .copy(), zachować obraz pędzel w tablicy, a po prostu dodać go

arr[first_br_row:last_br_row, first_br_col:last_br_col] += brush[first_row:last_row, first_col:last_col] 

gdzie ustawić first_br_row, last_br_rowfirst_br_col, last_br_col zająć się subimage gdzie chcesz dodać pędzla i first_row, last_row, first_col, last_col klip szczotkę (normalnie ustawić je na 0 i # wierszy/przełęcze - 1, ale dostosowanie kiedy” zbliżyć się do granicy obrazu, aby tylko pomalować część pędzla).

Mam nadzieję, że wszystko to pomoże.

+0

Dzięki! Okazuje się, że tak, sztuczki z krojem i indeksowaniem pomogą w tym wszystkim. Jednak! Prawidłowa odpowiedź to prawdopodobnie rysowanie pojedynczych punktów i nakładanie pędzla oraz rozmycie zarówno jako jądra. Dzięki za uderzenie w bibliotekach; jest to jednak naprawdę zadanie przetwarzania końcowego: dane zostały już zebrane. – Nate

2

Pomocna może być odrobina matematyki w przestrzeni Fouriera: tłumaczenie (splatanie przez diraca) jest równe prostemu mnożeniu przez fazę Fouriera ... to sprawia, że ​​pędzel przemieszcza się dokładnie w to miejsce (podobne rozwiązanie niż catchmeifyoutry & dwf, ale to pozwala na tłumaczenie lepsze niż piksel, np. 2.5, niestety z pewnym dzwonkiem). Następnie suma takich uderzeń jest sumą tych operacji.

w postaci kodu:

import numpy 
import pylab 
from scipy import mgrid 

def FTfilter(image, FTfilter): 
    from scipy.fftpack import fftn, fftshift, ifftn, ifftshift 
    from scipy import real 
    FTimage = fftshift(fftn(image)) * FTfilter 
    return real(ifftn(ifftshift(FTimage))) 

def translate(image, vec): 
    """ 
    Translate image by vec (in pixels) 

    """ 
    u = ((vec[0]+image.shape[0]/2) % image.shape[0]) - image.shape[0]/2 
    v = ((vec[1]+image.shape[1]/2) % image.shape[1]) - image.shape[1]/2 
    f_x, f_y = mgrid[-1:1:1j*image.shape[0], -1:1:1j*image.shape[1]] 
    trans = numpy.exp(-1j*numpy.pi*(u*f_x + v*f_y)) 
    return FTfilter(image, trans) 

def occlude(image, mask): 
    # combine in oclusive mode 
    return numpy.max(numpy.dstack((image, mask)), axis=2) 

if __name__ == '__main__': 
    Image = numpy.random.rand(100, 100) 
    X, Y = mgrid[-1:1:1j*Image.shape[0], -1:1:1j*Image.shape[1]] 
    brush = X**2 + Y**2 < .05 # relative size of the brush 
    # shows the brush 
    pylab.imshow(brush) 

    # move it to some other position/use a threshold to avoid ringing 
    brushed = translate(brush, [20, -10.51]) > .6 
    pylab.imshow(brushed) 

    pylab.imshow(occlude(Image, brushed)) 

    more_strokes = [[40, -15.1], [-40, -15.1], [-25, 15.1], [20, 10], [0, -10], [25, -10.51]] 
    for stroke in more_strokes: 
     brushed = brushed + translate(brush, stroke) > .6 

    pylab.imshow(occlude(Image, brushed)) 
1

OpenCV używa numpy tablice i posiada podstawowe funkcje rysowania okręgów, elips:, krzywe ...

Aby narysować linię można nazwać

cv.line(array,previous_point,new_point,colour,thickness=x) 

za każdym razem, gdy pojawi się zdarzenie myszy.

Powiązane problemy