मैटलैब में इष्टतम परिवहन युद्ध कार्यान्वयन


11

मैं पेपर " ऑप्टिमल मास ट्रांसपोर्ट फॉर रजिस्ट्रेशन एंड वारपिंग " को लागू कर रहा हूं, मेरा लक्ष्य इसे ऑनलाइन रखना है क्योंकि मैं अभी किसी भी यूलियन मास ट्रांसपोर्ट कोड को ऑनलाइन नहीं पा सकता हूं और कम से कम इमेज प्रोसेसिंग में अनुसंधान समुदाय के लिए यह दिलचस्प होगा।

कागज को इस प्रकार संक्षेप में प्रस्तुत किया जा सकता है:
- x और y निर्देशांक के साथ 1D हिस्टोग्राम मिलानों का उपयोग करके एक प्रारंभिक मानचित्र खोजें - के निश्चित बिंदु के लिए हल करें। , जहां 90 डिग्री काउंटर क्लॉकवाइज रोटेशन, लिए पॉरिचियन बाउंड्री कंडीशंस (= 0) के साथ पॉइसन समीकरण के समाधान के लिए खड़ा है । और जैकबियन मैट्रिक्स का निर्धारक है। - टाइमटेस्ट लिए स्थिरता की गारंटी हैu
ut=1μ0Du1div(u)u1Du
dt<min|1μ01div(u)|

संख्यात्मक सिमुलेशन (एक नियमित ग्रिड पर प्रदर्शन) के लिए, वे पॉसियन समीकरण को हल करने के लिए मैटलैब के पोइक का उपयोग करने का संकेत देते हैं , वे स्थानिक डेरिवेटिव के लिए केंद्रित परिमित अंतर का उपयोग करते हैं, ड्यू को छोड़कर Duजो एक अपवार्ड स्कीम का उपयोग करके गणना की जाती है।

मेरे कोड का उपयोग करते हुए, मैपिंग की ऊर्जा कार्यात्मक और कर्ल ठीक से एक जोड़े पुनरावृत्तियों के लिए कम हो रही है (कुछ दसियों से कुछ हजारों के लिए समय कदम पर निर्भर करता है)। लेकिन इसके बाद, सिमुलेशन में विस्फोट होता है: बहुत कम पुनरावृत्तियों में एनएएन तक पहुंचने के लिए ऊर्जा बढ़ जाती है। मैंने विभेदकों और एकीकरणों के लिए कई आदेशों की कोशिश की (क्यूट्रैप्ज के लिए एक उच्च आदेश प्रतिस्थापन यहां पाया जा सकता है ), और विभिन्न प्रक्षेप योजनाएं, लेकिन मुझे हमेशा एक ही मुद्दा (यहां तक ​​कि बहुत चिकनी छवियों, हर जगह गैर-शून्य आदि) मिलता है।
किसी को भी कोड और / या मैं जिस सैद्धांतिक समस्या का सामना कर रहा हूँ उसे देखने में दिलचस्पी होगी? कोड कम है।

कृपया gradient2 () को ग्रेडिएंट () के अंत में बदलें। यह एक उच्च क्रम ढाल था लेकिन चीजों को हल नहीं करता है।

मुझे केवल अब के लिए कागज के इष्टतम परिवहन भाग में दिलचस्पी है, अतिरिक्त नियमितीकरण शब्द नहीं।

धन्यवाद !

जवाबों:


5

मेरे अच्छे दोस्त पास्कल ने इसे कुछ साल पहले बनाया था (यह लगभग मतलब में है):

#! /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)

टेस्ट रन, लगभग 2 सेकंड लेता है।

ढाल मूल दृष्टिकोण यहां बताया गया है: People.clarkson.edu/~ebollt/Papers/quadcost.pdf


उत्कृष्ट .. बहुत बहुत धन्यवाद! मैं इस कोड की कोशिश करूंगा, और अपनी त्रुटियों की जांच करने के लिए मेरी तुलना करूंगा। यह दृष्टिकोण वास्तव में Haker एट अल द्वारा कागज का स्थानीय संस्करण प्रतीत होता है। मैंने जिक्र किया कि - यानी, बिना लैप्लेशियन के हल किए। एक बार फिर धन्यवाद !
व्हिटअंगल

मैं अंत में इस कोड के साथ कुछ मुद्दों का सामना कर रहा हूं ...: अगर मैं गणना हूं, तो मैं से काफी दूर ( साथ ) - यहां तक कि निकालने पर भी कलंक। इसके अलावा, अगर मैं सिर्फ एक जोड़े को पुनरावृत्तियों की संख्या बढ़ाता हूं, तो कोड फट जाता है और NaN मान (और क्रैश) देता है। कोई उपाय ? धन्यवाद ! f2(ϕ)detHϕf1H
व्हिटअंगल

क्या अधिक धब्बा NaN समस्या के साथ मदद करता है?
dranxo

हाँ, वास्तव में, अधिक परीक्षणों के बाद यह अधिक धुंधला के साथ मदद करता है - धन्यवाद!। मैं अब 1 पिक्सेल स्टदेव (अभी भी कंप्यूटिंग) तक 140 पिक्सेल मानक विचलन के शुरुआती धुंधला के साथ 8 चरणों की कोशिश कर रहा हूं। मैं अभी भी अपने अंतिम परिणाम में मूल छवि का एक महत्वपूर्ण राशि है (64px धुंधला के साथ)। मैं में किसी भी शेष कर्ल के लिए भी जाँच करूँगा । ϕ
व्हिटअंगल

ओह! अच्छा ठीक है। मुझे लगता है। धुंधला वहाँ है क्योंकि छवियाँ स्वाभाविक रूप से निरंतर (किनारों) नहीं हैं और ढाल समस्याग्रस्त होगा। उम्मीद है कि आप अभी भी बहुत ज्यादा धुंधला किए बिना अच्छे जवाब पा रहे हैं।
ड्रैंक्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.