Matlab'da optimum taşıma çözgü uygulaması


11

" Kayıt ve Çözgü için Optimum Toplu Taşıma " adlı makaleyi uyguluyorum , amacım çevrimiçi olarak herhangi bir eulerian toplu taşıma kodu bulamadığım için bunu çevrimiçi hale getirmektir ve bu en azından görüntü işleme konusunda araştırma topluluğu için ilginç olacaktır.

Bildiri aşağıdaki gibi özetlenebilir:
- x ve y koordinatları boyunca 1D histogram eşleşmelerini kullanarak bir başlangıç ​​haritası bulun - u t = 1 sabit noktasını çözünu
,U90 derece açılımı, saat yönünde döndürme karşı-1Dirichlet sınır koşulları (= 0) ile Poisson denkleminin çözümü için veJacobian matrisinin belirleyicisidir. -perp) için kararlılık garanti edilirut=1μ0Du1div(u)u1Du
dt<min|1μ01div(u)|

Sayısal simülasyonlar için (düzenli bir ızgarada gerçekleştirilir), poisson denklemini çözmek için matlab'ın poicalc'ini belirtirler , bir rüzgar rüzgarı şeması kullanılarak hesaplanan hariç, uzaysal türevler için ortalanmış sonlu farklar kullanırlar.Du

Kodumu kullanarak, eşleştirmenin enerji işlevi ve kıvrılması birkaç yineleme için uygun şekilde azalmaktadır (zaman adımına bağlı olarak birkaç ondan birkaç bine kadar). Ancak bundan sonra simülasyon patlar: enerji çok az yinelemede bir NAN'a ulaşmak için artar. Farklılıklar ve entegrasyonlar için birkaç sipariş denedim (cumptrapz'ın daha yüksek bir siparişi burada bulunabilir ) ve farklı enterpolasyon şemaları, ama her zaman aynı sorunu alıyorum (çok düzgün görüntülerde bile, her yerde sıfır olmayan vb.).
Herkes kod ve / veya karşılaştığım teorik soruna bakmak ister misiniz? Kod oldukça kısadır.

Lütfen sonunda degrade2 () öğesini degrade () ile değiştirin. Bu daha yüksek dereceli bir gradyandı, ancak işleri de çözmüyor.

Şimdilik sadece ek optimumlaştırma terimiyle değil, kağıdın en uygun taşıma kısmıyla ilgileniyorum.

Teşekkürler !

Yanıtlar:


5

İyi arkadaşım Pascal bunu birkaç yıl önce yaptı ( neredeyse Matlab'da):

#! /usr/bin/env python

#from scipy.interpolate import interpolate
from pylab import *
from numpy import *


def GaussianFilter(sigma,f):
    """Apply Gaussian filter to an image"""
    if sigma > 0:
        n = ceil(4*sigma)
        g = exp(-arange(-n,n+1)**2/(2*sigma**2))
        g = g/g.sum()

        fg = zeros(f.shape)

        for i in range(f.shape[0]):
            fg[i,:] = convolve(f[i,:],g,'same')
        for i in range(f.shape[1]):
            fg[:,i] = convolve(fg[:,i],g,'same')
    else:
        fg = f

    return fg


def clamp(x,xmin,xmax):
    """Clamp values between xmin and xmax"""
    return minimum(maximum(x,xmin),xmax)


def myinterp(f,xi,yi):
    """My bilinear interpolator (scipy's has a segfault)"""
    M,N = f.shape
    ix0 = clamp(floor(xi),0,N-2).astype(int)
    iy0 = clamp(floor(yi),0,M-2).astype(int)
    wx = xi - ix0
    wy = yi - iy0
    return ( (1-wy)*((1-wx)*f[iy0,ix0] + wx*f[iy0,ix0+1]) +
        wy*((1-wx)*f[iy0+1,ix0] + wx*f[iy0+1,ix0+1]) )


def mkwarp(f1,f2,sigma,phi,showplot=0):
    """Image warping by solving the Monge-Kantorovich problem"""
    M,N = f1.shape[:2]

    alpha = 1
    f1 = GaussianFilter(sigma,f1)
    f2 = GaussianFilter(sigma,f2)

    # Shift indices for going from vertices to cell centers
    iUv = arange(M)             # Up
    iDv = arange(1,M+1)         # Down
    iLv = arange(N)             # Left
    iRv = arange(1,N+1)         # Right
    # Shift indices for cell centers (to cell centers)
    iUc = r_[0,arange(M-1)]
    iDc = r_[arange(1,M),M-1]
    iLc = r_[0,arange(N-1)]
    iRc = r_[arange(1,N),N-1]
    # Shifts for going from centers to vertices
    iUi = r_[0,arange(M)]
    iDi = r_[arange(M),M-1]
    iLi = r_[0,arange(N)]
    iRi = r_[arange(N),N-1]


    ### The main gradient descent loop ###      
    for iter in range(0,30):
        ### Approximate derivatives ###
        # Compute gradient phix and phiy at pixel centers.  Array phi has values
        # at the pixel vertices.
        phix = (phi[iUv,:][:,iRv] - phi[iUv,:][:,iLv] + 
            phi[iDv,:][:,iRv] - phi[iDv,:][:,iLv])/2
        phiy = (phi[iDv,:][:,iLv] - phi[iUv,:][:,iLv] + 
            phi[iDv,:][:,iRv] - phi[iUv,:][:,iRv])/2
        # Compute second derivatives at pixel centers using central differences.
        phixx = (phix[:,iRc] - phix[:,iLc])/2
        phixy = (phix[iDc,:] - phix[iUc,:])/2
        phiyy = (phiy[iDc,:] - phiy[iUc,:])/2
        # Hessian determinant
        detD2 = phixx*phiyy - phixy*phixy

        # Interpolate f2 at (phix,phiy) with bilinear interpolation
        f2gphi = myinterp(f2,phix,phiy)

        ### Update phi ###
        # Compute M'(phi) at pixel centers
        dM = alpha*(f1 - f2gphi*detD2)
        # Interpolate to pixel vertices
        phi = phi - (dM[iUi,:][:,iLi] + 
            dM[iDi,:][:,iLi] + 
            dM[iUi,:][:,iRi] + 
            dM[iDi,:][:,iRi])/4


    ### Plot stuff ###      
    if showplot:
        pad = 2
        x,y = meshgrid(arange(N),arange(M))
        x = x[pad:-pad,:][:,pad:-pad]
        y = y[pad:-pad,:][:,pad:-pad]
        phix = phix[pad:-pad,:][:,pad:-pad]
        phiy = phiy[pad:-pad,:][:,pad:-pad]

        # Vector plot of the mapping
        subplot(1,2,1)
        quiver(x,y,flipud(phix-x),-flipud(phiy-y))
        axis('image')
        axis('off')
        title('Mapping')

        # Grayscale plot of mapping divergence
        subplot(1,2,2)  
        divs = phixx + phiyy # Divergence of mapping s(x)
        imshow(divs[pad:-pad,pad:-pad],cmap=cm.gray)
        axis('off')
        title('Divergence of Mapping')
        show()

    return phi


if __name__ == "__main__":  # Demo
    from pylab import *
    from numpy import * 

    f1 = imread('brain-tumor.png')
    f2 = imread('brain-healthy.png')
    f1 = f1[:,:,1]
    f2 = f2[:,:,1]

    # Initialize phi as the identity map
    M,N = f1.shape
    n,m = meshgrid(arange(N+1),arange(M+1))
    phi = ((m-0.5)**2 + (n-0.5)**2)/2

    sigma = 3
    phi = mkwarp(f1,f2,sigma,phi)
    phi = mkwarp(f1,f2,sigma/2,phi,1)
#   phi = mkwarp(f1,f2,sigma/4,phi,1)

Test çalıştırması yaklaşık 2 saniye sürer.

Gradyan iniş yaklaşımı burada açıklanmaktadır: people.clarkson.edu/~ebollt/Papers/quadcost.pdf


mükemmel .. çok teşekkürler! Bu kodu deneyeceğim ve hatalarımı kontrol etmek için benimkiyle karşılaşacağım. Bu yaklaşım aslında Haker ve ark. bahsettiğim - yani, bir laplacian için çözmeden. Tekrar teşekkürler !
WhitAngl

Sonunda bu kodla ilgili birkaç sorunla karşılaşıyorum ...: Eğer , oldukça ( ile kendir ile) - hatta gaussian'ı kaldırırken Görüntü. Ayrıca, sadece birkaç bin yineleme sayısını artırırsanız, kod patlar ve NaN değerleri (ve çöküyor) verir. Herhangi bir fikir ? Teşekkürler ! f 1 Hf2(ϕ)detHϕf1H
WhitAngl

Daha fazla bulanıklık NaN problemine yardımcı olur mu?
dranxo

Evet, gerçekten, daha fazla testten sonra daha fazla bulanıklığa yardımcı oluyor - teşekkürler !. Şimdi 1 piksel stdev (hala hesaplama) kadar 140 piksel standart sapma başlangıç ​​bulanıklığı ile 8 adım deniyorum. Son sonucumda hala önemli miktarda orijinal görüntü var (64 piksel bulanıklık ile). Ayrıca içinde kalan kıvrım olup olmadığını da kontrol edeceğim . ϕ
WhitAngl

Ah tamam iyi. Bence. Görüntüler doğal olarak sürekli olmadığından (kenarlar) ve renk geçişi sorunlu olacağından bulanıklık vardır. Umarım çok fazla bulanıklık olmadan hala iyi cevaplar alırsınız.
dranxo
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.