Doar pentru a demonstra că n^0.79 nu este Omega(n^0.8): pentru fiecare constantă c › 0, există infinit de multe n astfel încât n^0.79 ‹ cn^0.8 (adică toate n › c^-100).

person Joe Flip    schedule 28.10.2016    source sursă
comment
Nu am testat, dar un lucru iese în evidență - graficul de ieșire folosește subplot. Primul lucru pe care trebuie să îl încercați este să reprezentați imaginea deformată cu plt.figure / plt.imshow mai degrabă decât cu plt.subplots / ax.imshow. De asemenea,, vă rog să vă editați întrebarea pentru a include import declarații? Mulțumiri! De asemenea, ce versiune Python?   -  person cxw    schedule 31.10.2016
comment
@cxw Actualizat multumesc!!   -  person Joe Flip    schedule 31.10.2016
comment
@cxw Am încercat fără plt.subplots() dar am același rezultat.   -  person Joe Flip    schedule 31.10.2016
comment
Răspuns postat! Voi fi departe de computerul meu mâine până duminică. Sper că cele de mai jos vă ajută să vă dați seama ce se întâmplă în cazul dvs. real de utilizare!   -  person cxw    schedule 03.11.2016


Răspunsuri (1)


Îți dau ce am. Nu cred că voi reuși să rezolv asta cu datele de testare date. Maparea unui unghi de 45 de grade la o linie dreaptă într-o imagine atât de mică înseamnă că trebuie să se întâmple multă mișcare și nu prea multe date pe care să o bazeze. Am găsit câteva erori specifice care sunt remediate în codul de mai jos, marcate /* */ (din moment ce nu este ceva ce se vede de obicei într-un fișier Python, acel marker ar trebui să iasă în evidență :) ).

Vă rugăm să încercați acest cod pe datele dvs. reale și să-mi spuneți dacă funcționează! Cu acest set de date de intrare, există câteva ieșiri diferite de zero.

Marile probleme au fost:

  • Datele interp trebuie sortate
  • multe dintre punctele de control au fost lipsite de sens, deoarece nu există suficiente date în acest set de date (de exemplu, maparea unor intervale mari ale unei coloane la un singur punct)
  • intervalul de valori din imagine a fost dezactivat (deci rezultatul original a fost aproape 0 - patch-urile de culoare au fost valori în jurul valorii de 1e-9).

Cel mai important lucru pe care l-am adăugat, de dragul viitoarei codări, este un diagramă 3D care arată cum punctele de control „adevărate” se mapează la punctele de control „ideale”. Acest lucru vă oferă un instrument de depanare pentru a vă arăta dacă maparea punctelor de control este așa cum vă așteptați. Acest complot este ceea ce m-a condus la problema interp.

Apropo, vă rugăm să folosiți nume precum „înainte” și „după” în loc de ideal și true :) . Încerc să-mi amintesc care m-a împiedicat cel puțin o dată.

Prima încercare

import pdb
import matplotlib.pyplot as plt
import numpy as np
from skimage import measure, transform, img_as_float

from mpl_toolkits.mplot3d import Axes3D # /**/

#/**/
# From https://stackoverflow.com/a/14491059/2877364 by
# https://stackoverflow.com/users/1355221/dansalmo
def flatten_list(L):
    for item in L:
        try:
            for i in flatten_list(item): yield i
        except TypeError:
            yield item
#end flatten_list

true_input = np.array([range(i,i+10) for i in range(20)])  # /** != True **/
ideal = np.array([range(10)]*20)

#pdb.set_trace()
# Find contours of ideal and true_input images and create list of control points for warp
true_control_pts = []
ideal_control_pts = []
OLD_true=[]     # /**/ for debugging
OLD_ideal=[]

for lam in [x+0.5 for x in ideal[0]]:   # I tried the 0.5 offset just to see,
    try:                                # but it didn't make much difference

        # Get the isowavelength contour in the true_input and ideal images
        tc = measure.find_contours(true_input, lam)[0]
        ic = measure.find_contours(ideal, lam)[0]
        nc = np.zeros(ic.shape) # /** don't need ones() **/

        # Use the y /** X? **/ coordinates of the ideal contour
        nc[:, 0] = ic[:, 0]

        # Interpolate true contour onto ideal contour y axis so there are the same number of points

        # /** Have to sort first - https://docs.scipy.org/doc/numpy/reference/generated/numpy.interp.html#numpy-interp **/
        tc_sorted = tc[tc[:,0].argsort()]
            # /** Thanks to https://stackoverflow.com/a/2828121/2877364 by
            # https://stackoverflow.com/users/208339/steve-tjoa **/

        nc[:, 1] = np.interp(ic[:, 0], tc_sorted[:, 0], tc_sorted[:, 1],
            left=np.nan, right=np.nan)
            # /** nan: If the interpolation is out of range, we're not getting
            #     useful data.  Therefore, flag it with a nan. **/

        # /** Filter out the NaNs **/
        # Thanks to https://stackoverflow.com/a/11453235/2877364 by
        # https://stackoverflow.com/users/449449/eumiro
        #pdb.set_trace()
        indices = ~np.isnan(nc).any(axis=1)
        nc_nonan = nc[indices]
        ic_nonan = ic[indices]

        # Add the control points to the appropriate list.
        # /** Flattening here since otherwise I wound up with dtype=object
        #     in the numpy arrays. **/
        true_control_pts.append(nc_nonan.flatten().tolist())
        ideal_control_pts.append(ic_nonan.flatten().tolist())

        OLD_true.append(nc)     # /** for debug **/
        OLD_ideal.append(ic)

    except (IndexError,AttributeError):
        pass

#pdb.set_trace()
# /** Make vectors of all the control points. **/
true_flat = list(flatten_list(true_control_pts))
ideal_flat = list(flatten_list(ideal_control_pts))
true_control_pts = np.array(true_flat)
ideal_control_pts = np.array(ideal_flat)

# Make the vectors 2d
length = len(true_control_pts)/2
true_control_pts = true_control_pts.reshape(length,2)
ideal_control_pts = ideal_control_pts.reshape(length,2)

#pdb.set_trace()

# Plot the original image
image = np.array([range(i,i+10) for i in range(20)]) / 30.0 # /**.astype(np.int32)**/
    # /** You don't want int32 images!  See
    #     http://scikit-image.org/docs/dev/user_guide/data_types.html .
    #     Manually rescale the image to [0.0,1.0] by dividing by 30. **/
image_float = img_as_float(image) #/** make sure skimage is happy */ 
fig = plt.figure()
plt.imshow(image_float, origin='lower', interpolation='none')
plt.title('Input image')
fig.show()  # /** I needed this on my test system **/

# Warp the actual image given the transformation between the true and ideal wavelength maps
tform = transform.PiecewiseAffineTransform()
tform.estimate(true_control_pts, ideal_control_pts)
out = transform.warp(image, tform)
    # /** since we started with float, and this is float, too, the two are
    #     comparable. **/

pdb.set_trace()

# Plot the warped image!
fig, ax = plt.subplots()
ax.imshow(out, origin='lower', interpolation='none')    # /**note: float**/
plt.title('Should be parallel lines')
fig.show()

# /** Show the control points.
#     The z=0 plane will be the "true" control points (before), and the
#     z=1 plane will be the "ideal" control points (after). **/
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
fig.show()

for rowidx in range(length):
    ax.plot([true_control_pts[rowidx,0], ideal_control_pts[rowidx,0]],
            [true_control_pts[rowidx,1], ideal_control_pts[rowidx,1]],
            [0,1])

input() # /** because I was running from the command line **/

A doua încercare

Se apropie:

introduceți descrierea imaginii aici

Și iată o vedere a maparii punctelor de control care arată mai promițătoare:

introduceți descrierea imaginii aici

Puteți vedea că încearcă să învârtească puțin imaginea, ceea ce m-aș aștepta de la acest set de date.

Cod

import pdb
import matplotlib.pyplot as plt
import numpy as np
from skimage import measure, transform, img_as_float

from mpl_toolkits.mplot3d import Axes3D # /**/

#/**/
# From https://stackoverflow.com/a/14491059/2877364 by
# https://stackoverflow.com/users/1355221/dansalmo
def flatten_list(L):
    for item in L:
        try:
            for i in flatten_list(item): yield i
        except TypeError:
            yield item
#end flatten_list

#/**/
# Modified from https://stackoverflow.com/a/19122075/2877364 by
# https://stackoverflow.com/users/2588210/christian-k
def equispace(data, npts):
    x,y = data.T
    xd =np.diff(x)
    yd = np.diff(y)
    dist = np.sqrt(xd**2+yd**2)
    u = np.cumsum(dist)
    u = np.hstack([[0],u])

    t = np.linspace(0,u.max(),npts)
    xn = np.interp(t, u, x)
    yn = np.interp(t, u, y)
    return np.column_stack((xn, yn))

true_input = np.array([range(i,i+10) for i in range(20)])  # /** != True **/
ideal = np.array([range(10)]*20)

#pdb.set_trace()
# Find contours of ideal and true_input images and create list of control points for warp
true_control_pts = []
ideal_control_pts = []
OLD_true=[]     # /**/ for debugging
OLD_ideal=[]

for lam in [x+0.5 for x in ideal[0]]:   # I tried the 0.5 offset just to see,
    try:                                # but it didn't make much difference

        # Get the isowavelength contour in the true_input and ideal images
        tc = measure.find_contours(true_input, lam)[0]
            # /** So this might not have very many numbers in it. **/
        ic = measure.find_contours(ideal, lam)[0]
            # /** CAUTION: this is assuming the contours are going the same
            #       direction.  If not, you'll need to make it so. **/
        #nc = np.zeros(ic.shape) # /** don't need ones() **/

        # /** We just want to find points on _tc_ to match _ic_.  That's
        #       interpolation _within_ a curve. **/
        #pdb.set_trace()
        nc_by_t = equispace(tc,ic.shape[0])
        ic_by_t = equispace(ic,ic.shape[0])


        ### /** Not this **/
        ## Use the y /** X? **/ coordinates of the ideal contour
        #nc[:, 0] = ic[:, 0]
        #
        ## Interpolate true contour onto ideal contour y axis so there are the same number of points
        #
        ## /** Have to sort first - https://docs.scipy.org/doc/numpy/reference/generated/numpy.interp.html#numpy-interp **/
        #tc_sorted = tc[tc[:,0].argsort()]
        #    # /** Thanks to https://stackoverflow.com/a/2828121/2877364 by
        #    # https://stackoverflow.com/users/208339/steve-tjoa **/
        #
        #nc[:, 1] = np.interp(ic[:, 0], tc_sorted[:, 0], tc_sorted[:, 1],
        #    left=np.nan, right=np.nan)
        #    # /** nan: If the interpolation is out of range, we're not getting
        #    #     useful data.  Therefore, flag it with a nan. **/

        # /** Filter out the NaNs **/
        # Thanks to https://stackoverflow.com/a/11453235/2877364 by
        # https://stackoverflow.com/users/449449/eumiro
        #pdb.set_trace()
        #indices = ~np.isnan(nc).any(axis=1)
        #nc_nonan = nc[indices]
        #ic_nonan = ic[indices]
        #

        # Add the control points to the appropriate list.
        ## /** Flattening here since otherwise I wound up with dtype=object
        ##     in the numpy arrays. **/
        #true_control_pts.append(nc_nonan.flatten().tolist())
        #ideal_control_pts.append(ic_nonan.flatten().tolist())

        #OLD_true.append(nc)     # /** for debug **/
        #OLD_ideal.append(ic)

        true_control_pts.append(nc_by_t)
        ideal_control_pts.append(ic_by_t)

    except (IndexError,AttributeError):
        pass

pdb.set_trace()
# /** Make vectors of all the control points. **/
true_flat = list(flatten_list(true_control_pts))
ideal_flat = list(flatten_list(ideal_control_pts))
true_control_pts = np.array(true_flat)
ideal_control_pts = np.array(ideal_flat)

# Make the vectors 2d
length = len(true_control_pts)/2
true_control_pts = true_control_pts.reshape(length,2)
ideal_control_pts = ideal_control_pts.reshape(length,2)

#pdb.set_trace()

# Plot the original image
image = np.array([range(i,i+10) for i in range(20)]) / 30.0 # /**.astype(np.int32)**/
    # /** You don't want int32 images!  See
    #     http://scikit-image.org/docs/dev/user_guide/data_types.html .
    #     Manually rescale the image to [0.0,1.0] by dividing by 30. **/
image_float = img_as_float(image) #/** make sure skimage is happy */ 
fig = plt.figure()
plt.imshow(image_float, origin='lower', interpolation='none')
plt.title('Input image')
fig.show()  # /** I needed this on my test system **/

# Warp the actual image given the transformation between the true and ideal wavelength maps
tform = transform.PiecewiseAffineTransform()
tform.estimate(true_control_pts, ideal_control_pts)
out = transform.warp(image, tform)
    # /** since we started with float, and this is float, too, the two are
    #     comparable. **/

pdb.set_trace()

# Plot the warped image!
fig, ax = plt.subplots()
ax.imshow(out, origin='lower', interpolation='none')    # /**note: float**/
plt.title('Should be parallel lines')
fig.show()

# /** Show the control points.
#     The z=0 plane will be the "true" control points (before), and the
#     z=1 plane will be the "ideal" control points (after). **/
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
fig.show()

for rowidx in range(length):
    ax.plot([true_control_pts[rowidx,0], ideal_control_pts[rowidx,0]],
            [true_control_pts[rowidx,1], ideal_control_pts[rowidx,1]],
            [0,1])

input() # /** because I was running from the command line **/

Explicaţie

Gândiți-vă la interpolare diferit: coordonatele X și Y nu sunt de fapt ceea ce doriți să mapați, nu-i așa? Cred că ceea ce doriți să mapați este distanța de-a lungul conturului, astfel încât conturul diagonală să fie întins pentru a fi un contur vertical. Asta fac aceste rânduri:

nc_by_t = equispace(tc,ic.shape[0])
ic_by_t = equispace(ic,ic.shape[0])

Facem ic.shape[0] număr de puncte egal distanțate de-a lungul fiecărui contur și apoi mapăm acele puncte unul cu celălalt. equispace este modificat de la acest răspuns. Deci, aceasta întinde conturul mai scurt pentru a se potrivi mai lung, indiferent de sens, cu numărul de puncte definit de lungimea conturului în ic. De fapt, puteți folosi orice număr de puncte cu această tehnică; Tocmai am testat 100 de puncte și am obținut în mod substanțial același rezultat.

Din nou, testați acest lucru pe datele dvs. reale. Gândiți-vă care este exact referința dvs. pentru interpolare. Este într-adevăr coordonata X sau Y? Este distanța de-a lungul conturului? Procentul conturului (ca mai sus)?

OK, încă o idee

Pentru acest caz de testare, mai multe date ar ajuta? Da!

introduceți descrierea imaginii aici

Am folosit imagini mai mari pentru a determina punctele de control, apoi am cartografiat o imagine mai mică în centrul acelei regiuni.

Cod

(ceea ce este o mizerie totală până în acest moment - vezi marcajele ===========)

import pdb
import matplotlib.pyplot as plt
import numpy as np
from skimage import measure, transform, img_as_float

from mpl_toolkits.mplot3d import Axes3D # /**/

#/**/
def test_figure(data,title):
    image_float = img_as_float(data) #/** make sure skimage is happy */ 
    fig = plt.figure()
    plt.imshow(image_float, origin='lower', interpolation='none')
    plt.title(title)
    fig.show()

#/**/
# From https://stackoverflow.com/a/14491059/2877364 by
# https://stackoverflow.com/users/1355221/dansalmo
def flatten_list(L):
    for item in L:
        try:
            for i in flatten_list(item): yield i
        except TypeError:
            yield item
#end flatten_list

#/**/
# Modified from https://stackoverflow.com/a/19122075/2877364 by
# https://stackoverflow.com/users/2588210/christian-k
def equispace(data, npts):
    x,y = data.T
    xd =np.diff(x)
    yd = np.diff(y)
    dist = np.sqrt(xd**2+yd**2)
    u = np.cumsum(dist)
    u = np.hstack([[0],u])

    t = np.linspace(0,u.max(),npts)
    xn = np.interp(t, u, x)
    yn = np.interp(t, u, y)
    return np.column_stack((xn, yn))

# ======================  BIGGER
true_input = np.array([range(i,i+20) for i in range(30)])  # /** != True **/
ideal = np.array([range(20)]*30)
# ======================    
test_figure(true_input / 50.0, 'true_input')
test_figure(ideal / 20.0, 'ideal')

#pdb.set_trace()
# Find contours of ideal and true_input images and create list of control points for warp
true_control_pts = []
ideal_control_pts = []
OLD_true=[]     # /**/ for debugging
OLD_ideal=[]

for lam in [x+0.5 for x in ideal[0]]:   # I tried the 0.5 offset just to see,
    try:                                # but it didn't make much difference

        # Get the isowavelength contour in the true_input and ideal images
        tc = measure.find_contours(true_input, lam)[0]
            # /** So this might not have very many numbers in it. **/
        ic = measure.find_contours(ideal, lam)[0]
            # /** CAUTION: this is assuming the contours are going the same
            #       direction.  If not, you'll need to make it so. **/
        #nc = np.zeros(ic.shape) # /** don't need ones() **/

        # /** We just want to find points on _tc_ to match _ic_.  That's
        #       interpolation _within_ a curve. **/
        #pdb.set_trace()
        nc_by_t = equispace(tc,ic.shape[0])
        ic_by_t = equispace(ic,ic.shape[0])


        ### /** Not this **/
        ## Use the y /** X? **/ coordinates of the ideal contour
        #nc[:, 0] = ic[:, 0]
        #
        ## Interpolate true contour onto ideal contour y axis so there are the same number of points
        #
        ## /** Have to sort first - https://docs.scipy.org/doc/numpy/reference/generated/numpy.interp.html#numpy-interp **/
        #tc_sorted = tc[tc[:,0].argsort()]
        #    # /** Thanks to https://stackoverflow.com/a/2828121/2877364 by
        #    # https://stackoverflow.com/users/208339/steve-tjoa **/
        #
        #nc[:, 1] = np.interp(ic[:, 0], tc_sorted[:, 0], tc_sorted[:, 1],
        #    left=np.nan, right=np.nan)
        #    # /** nan: If the interpolation is out of range, we're not getting
        #    #     useful data.  Therefore, flag it with a nan. **/

        # /** Filter out the NaNs **/
        # Thanks to https://stackoverflow.com/a/11453235/2877364 by
        # https://stackoverflow.com/users/449449/eumiro
        #pdb.set_trace()
        #indices = ~np.isnan(nc).any(axis=1)
        #nc_nonan = nc[indices]
        #ic_nonan = ic[indices]
        #

        # Add the control points to the appropriate list.
        ## /** Flattening here since otherwise I wound up with dtype=object
        ##     in the numpy arrays. **/
        #true_control_pts.append(nc_nonan.flatten().tolist())
        #ideal_control_pts.append(ic_nonan.flatten().tolist())

        #OLD_true.append(nc)     # /** for debug **/
        #OLD_ideal.append(ic)

        true_control_pts.append(nc_by_t)
        ideal_control_pts.append(ic_by_t)

    except (IndexError,AttributeError):
        pass

#pdb.set_trace()
# /** Make vectors of all the control points. **/
true_flat = list(flatten_list(true_control_pts))
ideal_flat = list(flatten_list(ideal_control_pts))
true_control_pts = np.array(true_flat)
ideal_control_pts = np.array(ideal_flat)

# Make the vectors 2d
length = len(true_control_pts)/2
true_control_pts = true_control_pts.reshape(length,2)
ideal_control_pts = ideal_control_pts.reshape(length,2)

#pdb.set_trace()

# Plot the original image
image = np.array([range(i,i+10) for i in range(20)]) / 30.0 # /**.astype(np.int32)**/
    # /** You don't want int32 images!  See
    #     http://scikit-image.org/docs/dev/user_guide/data_types.html .
    #     Manually rescale the image to [0.0,1.0] by dividing by 30. **/

# ======================    
# /** Pad from 10x20 to 20x30 just for grins **/
#pdb.set_trace()
image = np.concatenate( (np.zeros((20,5)),image,np.zeros((20,5))), 1)
    # now it's 20x20
image = np.concatenate( (np.zeros((5,20)),image,np.zeros((5,20))), 0)
# ======================    

#Plot it
image_float = img_as_float(image) #/** make sure skimage is happy */ 
fig = plt.figure()
plt.imshow(image_float, origin='lower', interpolation='none')
plt.title('Input image')
fig.show()  # /** I needed this on my test system **/

# Warp the actual image given the transformation between the true and ideal wavelength maps
tform = transform.PiecewiseAffineTransform()
tform.estimate(true_control_pts, ideal_control_pts)
out = transform.warp(image, tform)
    # /** since we started with float, and this is float, too, the two are
    #     comparable. **/

pdb.set_trace()

# Plot the warped image!
fig, ax = plt.subplots()
ax.imshow(out, origin='lower', interpolation='none')    # /**note: float**/
plt.title('Should be parallel lines')
fig.show()

# /** Show the control points.
#     The z=0 plane will be the "true" control points (before), and the
#     z=1 plane will be the "ideal" control points (after). **/
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
fig.show()

for rowidx in range(length):
    ax.plot([true_control_pts[rowidx,0], ideal_control_pts[rowidx,0]],
            [true_control_pts[rowidx,1], ideal_control_pts[rowidx,1]],
            [0,1])

input() # /** because I was running from the command line **/
person cxw    schedule 03.11.2016