SORU
3 Kasım 2010, ÇARŞAMBA


Nasıl pençe benim algılama geliştirebilirim?

finding toes within each paw, önceki soruma sonra diğer Ölçümler tutmak istiyorsunuz görmek için toparlanmaya başladım. Ne yazık ki, ben hızlı bir şekilde önceki adımları ile bir sorun koştu: pençeleri tanımak.

Bakın, bunu bulana kadar kavram kanıtı benim temelde zamanla her sensör maksimum basıncı aldı ve her satır toplamı aramaya başlayacak,=! 0.0. Sütunlar için aynı ve 2'den fazla satır sıfır yine bulur bulmaz yapar. Bazı dizin minimal ve maksimal satır ve sütun değerlerini saklar.

alt text

Resimde gördüğünüz gibi, bu oldukça iyi, çoğu durumda çalışır. Ancak, bu yaklaşım pek çok dezavantaj (çok ilkel olmaktan başka) vardır:

  • İnsanlar olabilir 'içi boş ayak izi kendi içinde birkaç boş satır var demektir'. Bu (büyük) köpek de olabilirdi korktuğum beri, pençe kesmeden önce en az 2 ya da 3 boş satır bekledim.

    Bu birkaç boş satır ulaşmadan önce başka bir kişi farklı bir sütunda yaptıysanız bir sorun, böylece alanını genişletmek oluşturur. Sütunları karşılaştırmak ve eğer belli bir değeri aşmadığı mi diye düşündüm, ayrı pençeleri olmalılar.

  • Sorun köpek çok küçük olduğu zaman daha kötü olur ya da daha yüksek bir hızda yürür. Ne ön pençe ayak parmaklarını hala arka pençe ayak parmaklarını sadece ön pençe gibi aynı alan içinde temas kurmaya başlar süre temas sağlıyorlar.

    Benim basit bir script, bu mümkün olmayacaktır bölünmüş bu iki, çünkü o-cekti var olmak belirleyen aralıklarında o bölgeye ait olan pati, şu anda ise tek bakmak zorunda maksimal değerler üzerinden tüm kareleri.

Ters gitmeye başladığı örnekler:

alt text alt text

Şimdi ve pençeleri tanıma ayırarak daha iyi bir yol arıyorumsonra olan! karar verme sorunu için alacağım ().

Güncelleme:

Joe (müthiş!) almak için devreye soktum cevap uygulanıyor, ama zorluklar dosyalarımı gerçek pati veri ayıklama yaşıyorum.

alt text

Bu coded_paws bana Maksimum Baskı görüntü (yukarıda) uygulandığında farklı pençeleri gösterir. Ancak, çözüm her kare (ayrı örtüşen pençeleri için) gider ve dört Dikdörtgen öznitelikleri, koordinatları ve yüksekliği/genişliği gibi ayarlar.

Bu öznitelikleri almak için nasıl çözemedim ve ölçüm verileri için geçerli bir değişkende saklayın. Her pati için Bilmem Gereken bu yana, otelin konumu, çerçeveler ve birkaç bu hangi sırasında ne olduğunu paw (ön/arka, Sol/Sağ).

Nasıl Dikdörtgenler her pençe için bu değerleri ayıklamak için öznitelikleri kullanabilir miyim?

Kamu Dropbox klasörüne soru Kur(example 1, , *example 2*17)ben ölçümleri var. For anyone interested I also set up a blog güncel tutmak için :-)

CEVAP
3 Kasım 2010, ÇARŞAMBA


Eğer sadece yarı-bitişik bölgeler, zaten Python kolay bir uygulama var isteyen varsa: SciPy'ndimage.morphology s modülü. Bu oldukça yaygın image morphology bir işlemdir.


Temelde, 5 adım vardır:

def find_paws(data, smooth_radius=5, threshold=0.0001):
    data = sp.ndimage.uniform_filter(data, smooth_radius)
    thresh = data > threshold
    filled = sp.ndimage.morphology.binary_fill_holes(thresh)
    coded_paws, num_paws = sp.ndimage.label(filled)
    data_slices = sp.ndimage.find_objects(coded_paws)
    return object_slices
  1. Giriş verileri pençeleri sürekli bir ayak izi var emin olmak için biraz bulanık. (Daha verimli sadece daha büyük bir çekirdek (scipy.ndimage.morphology çeşitli fonksiyonları structure kwarg) kullanmak için iyi olurdu, ama bu oldukça düzgün bir sebep...) çalışmıyor

  2. Baskısının bir eşik değer üzerinde olduğu yerlerde boolean bir dizi var ki eşik dizisi (6* yani *)

  3. Temiz bölgeler var ve bu yüzden herhangi bir iç delik, (filled = sp.ndimage.morphology.binary_fill_holes(thresh)) doldurun

  4. Ayrı bitişik bölgeler (coded_paws, num_paws = sp.ndimage.label(filled)). Bu bölgeler sayısı (her bölgede benzersiz bir tamsayı (pençeleri sayısı kadar 1) sıfır ile her yerde) bitişik bir alandır) tarafından kodlanmış bir dizi döndürür.

  5. Bitişik bölgeler data_slices = sp.ndimage.find_objects(coded_paws) kullanarak ayrı tut. Bu [data[x] for x in data_slices] ile her pençe için veri bölgesi alabilmek slice nesnelerin dizilerini bir listesini verir. Bunun yerine, biraz daha fazla çalışma gerektirir bir dikdörtgen bu dilimler göre, çizeriz.


İki animasyonları altında "" ve "Gruplandırılmış Pençeleri" örnek veri. Patilerini üst üste göster Bu yöntem mükemmel bir şekilde çalışıyor gibi görünüyor. (Ve ne olursa olsun, bu pençe algılama algoritması oldukça hızlı ve çok daha sorunsuz GİF resimleri daha benim makinede altında çalışır,...)

Overlapping Paws Grouped Paws


İşte tam bir örnek (şimdi çok daha detaylı açıklamalar ile birlikte). Bu büyük çoğunluğu giriş okuma ve bir animasyon yapıyor. Gerçek pati algılama kod sadece 5 satır.

import numpy as np
import scipy as sp
import scipy.ndimage

import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle

def animate(input_filename):
    """Detects paws and animates the position and raw data of each frame
    in the input file"""
    # With matplotlib, it's much, much faster to just update the properties
    # of a display object than it is to create a new one, so we'll just update
    # the data and position of the same objects throughout this animation...

    infile = paw_file(input_filename)

    # Since we're making an animation with matplotlib, we need 
    # ion() instead of show()...
    plt.ion()
    fig = plt.figure()
    ax = fig.add_subplot(111)
    fig.suptitle(input_filename)

    # Make an image based on the first frame that we'll update later
    # (The first frame is never actually displayed)
    im = ax.imshow(infile.next()[1])

    # Make 4 rectangles that we can later move to the position of each paw
    rects = [Rectangle((0,0), 1,1, fc='none', ec='red') for i in range(4)]
    [ax.add_patch(rect) for rect in rects]

    title = ax.set_title('Time 0.0 ms')

    # Process and display each frame
    for time, frame in infile:
        paw_slices = find_paws(frame)

        # Hide any rectangles that might be visible
        [rect.set_visible(False) for rect in rects]

        # Set the position and size of a rectangle for each paw and display it
        for slice, rect in zip(paw_slices, rects):
            dy, dx = slice
            rect.set_xy((dx.start, dy.start))
            rect.set_width(dx.stop - dx.start   1)
            rect.set_height(dy.stop - dy.start   1)
            rect.set_visible(True)

        # Update the image data and title of the plot
        title.set_text('Time %0.2f ms' % time)
        im.set_data(frame)
        im.set_clim([frame.min(), frame.max()])
        fig.canvas.draw()

def find_paws(data, smooth_radius=5, threshold=0.0001):
    """Detects and isolates contiguous regions in the input array"""
    # Blur the input data a bit so the paws have a continous footprint 
    data = sp.ndimage.uniform_filter(data, smooth_radius)
    # Threshold the blurred data (this needs to be a bit > 0 due to the blur)
    thresh = data > threshold
    # Fill any interior holes in the paws to get cleaner regions...
    filled = sp.ndimage.morphology.binary_fill_holes(thresh)
    # Label each contiguous paw
    coded_paws, num_paws = sp.ndimage.label(filled)
    # Isolate the extent of each paw
    data_slices = sp.ndimage.find_objects(coded_paws)
    return data_slices

def paw_file(filename):
    """Returns a iterator that yields the time and data in each frame
    The infile is an ascii file of timesteps formatted similar to this:

    Frame 0 (0.00 ms)
    0.0 0.0 0.0
    0.0 0.0 0.0

    Frame 1 (0.53 ms)
    0.0 0.0 0.0
    0.0 0.0 0.0
    ...
    """
    with open(filename) as infile:
        while True:
            try:
                time, data = read_frame(infile)
                yield time, data
            except StopIteration:
                break

def read_frame(infile):
    """Reads a frame from the infile."""
    frame_header = infile.next().strip().split()
    time = float(frame_header[-2][1:])
    data = []
    while True:
        line = infile.next().strip().split()
        if line == []:
            break
        data.append(line)
    return time, np.array(data, dtype=np.float)

if __name__ == '__main__':
    animate('Overlapping paws.bin')
    animate('Grouped up paws.bin')
    animate('Normal measurement.bin')

Güncelleme:Bildiğim kadarıyla ne zaman sensörü ile temas halinde olan tanımlama, basit çözüm sadece aynı analizi yapmak, ama tüm verileri aynı anda kullanmaktır. (yani 3D bir dizi içine girdi yığını, ve onunla çalışmak, bireysel zaman dilimlerinde yerine.) SciPy. ndimage fonksiyonları n-boyutlu diziler ile çalışmak gerekiyordu, çünkü, pençe-bulma özgün işlevini değiştirmek zorunda değiliz.

# This uses functions (and imports) in the previous code example!!
def paw_regions(infile):
    # Read in and stack all data together into a 3D array
    data, time = [], []
    for t, frame in paw_file(infile):
        time.append(t)
        data.append(frame)
    data = np.dstack(data)
    time = np.asarray(time)

    # Find and label the paw impacts
    data_slices, coded_paws = find_paws(data, smooth_radius=4)

    # Sort by time of initial paw impact... This way we can determine which
    # paws are which relative to the first paw with a simple modulo 4.
    # (Assuming a 4-legged dog, where all 4 paws contacted the sensor)
    data_slices.sort(key=lambda dat_slice: dat_slice[2].start)

    # Plot up a simple analysis
    fig = plt.figure()
    ax1 = fig.add_subplot(2,1,1)
    annotate_paw_prints(time, data, data_slices, ax=ax1)
    ax2 = fig.add_subplot(2,1,2)
    plot_paw_impacts(time, data_slices, ax=ax2)
    fig.suptitle(infile)

def plot_paw_impacts(time, data_slices, ax=None):
    if ax is None:
        ax = plt.gca()

    # Group impacts by paw...
    for i, dat_slice in enumerate(data_slices):
        dx, dy, dt = dat_slice
        paw = i%4   1
        # Draw a bar over the time interval where each paw is in contact
        ax.barh(bottom=paw, width=time[dt].ptp(), height=0.2, 
                left=time[dt].min(), align='center', color='red')
    ax.set_yticks(range(1, 5))
    ax.set_yticklabels(['Paw 1', 'Paw 2', 'Paw 3', 'Paw 4'])
    ax.set_xlabel('Time (ms) Since Beginning of Experiment')
    ax.yaxis.grid(True)
    ax.set_title('Periods of Paw Contact')

def annotate_paw_prints(time, data, data_slices, ax=None):
    if ax is None:
        ax = plt.gca()

    # Display all paw impacts (sum over time)
    ax.imshow(data.sum(axis=2).T)

    # Annotate each impact with which paw it is
    # (Relative to the first paw to hit the sensor)
    x, y = [], []
    for i, region in enumerate(data_slices):
        dx, dy, dz = region
        # Get x,y center of slice...
        x0 = 0.5 * (dx.start   dx.stop)
        y0 = 0.5 * (dy.start   dy.stop)
        x.append(x0); y.append(y0)

        # Annotate the paw impacts         
        ax.annotate('Paw %i' % (i%4  1), (x0, y0),  
            color='red', ha='center', va='bottom')

    # Plot line connecting paw impacts
    ax.plot(x,y, '-wo')
    ax.axis('image')
    ax.set_title('Order of Steps')

alt text


alt text


alt text

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Elliot Davin

    Elliot Davin

    28 Kasım 2008
  • psidot

    psidot

    2 Kasım 2006
  • SellerDp

    SellerDp

    27 EKİM 2009