5

Używam funkcji local_binary_pattern w pakiecie obrazu scikit. Chciałbym obliczyć obrót niezmienny jednolitego LBP 8 sąsiadami wewnątrz promienia 1. Oto mój kod Python:Dlaczego funkcja local_binary_pattern w obrazie scikit dostarcza tę samą wartość dla różnych wzorów

import numpy as np 
from skimage.feature import local_binary_pattern 

image = np.array([[150, 137, 137, 146, 146, 148], 
        [145, 144, 144, 144, 142, 144], 
        [149, 144, 144, 143, 153, 147], 
        [145, 144, 147, 150, 145, 150], 
        [146, 146, 139, 148, 144, 148], 
        [129, 139, 142, 150, 146, 140]]).astype(np.uint8) 

lbp = local_binary_pattern(image, 8, 1, "uniform") 

print "image =" 
print image 
print "lbp =" 
print lbp 

I tu jest wyjście

image = 
[[150 137 137 146 146 148] 
[145 144 144 144 142 144] 
[149 144 144 143 153 147] 
[145 144 147 150 145 150] 
[146 146 139 148 144 148] 
[129 139 142 150 146 140]] 
lbp = 
[[ 0. 5. 5. 1. 9. 0.] 
[ 9. 6. 9. 9. 8. 9.] 
[ 0. 8. 6. 8. 0. 3.] 
[ 9. 7. 1. 0. 7. 0.] 
[ 1. 1. 8. 9. 7. 1.] 
[ 3. 4. 9. 0. 2. 3.]] 

Co mnie dezorientuje jest, że niektóre te same wartości w lbp nie odpowiadają temu samemu jednolitemu wzorowi. Np lbp[1,1] i lbp[2,2] są zarówno 6. Ale LBP z image[1,1] jest

1 0 0 
1 x 1 
1 1 1 

LBP z image[2,2] jest

1 1 1 
1 x 0 
1 1 1 

gdzie na podstawie wartości w lbp, zakładam funkcja local_binary_pattern wykorzystuje „większy lub równe ", aby porównać z sąsiadami.

LBP z image[1,1] i image[2,2] są jednolite. Ale w jaki sposób image[1,1] i image[2,2] mają taką samą wartość LBP?

Odpowiedz

3

Niezmienny względem obrotu LBP nie wykorzystuje bezpośrednio wartości pikseli sąsiadów, ale raczej wartości interpolowane na okręgu (dla niezmienności obrotu). Zobacz https://github.com/scikit-image/scikit-image/blob/master/skimage/feature/_texture.pyx#L156

także zobaczyć oryginalny LBP papier http://vision.stanford.edu/teaching/cs231b_spring1415/papers/lbp.pdf, który wymienia „Szare wartości sąsiadów, które nie należą dokładnie w środku pikseli są szacowane przez interpolację.”

+0

Dzięki bardzo za odpowiedź. Ale według rys. 1 w artykule, czy 8 sąsiadów w promieniu 1 nie powinno być ośmioma sąsiadującymi pikselami? – Peter

+0

Położenie punktów o promieniu 1 rzeczywiście mieści się w 8 sąsiadach, ale nie w samym środku pikseli dla sąsiadów ukośnych, stąd potrzeba interpolacji. –

+0

Ah, rozumiem. Dziękuję bardzo za odpowiedź! – Peter

3

W celu zwiększenia odporności na obracanie deskryptora LBP kwadratowe sąsiedztwo zastępuje kwadratowe sąsiedztwo. W okrągłym sąsiedztwie utworzonym przez osiem pikseli cztery sąsiednie przekątne nie pokrywają się z centrami pikseli. Wartości intensywności tych sąsiadów są zwykle obliczane za pomocą interpolacji dwuliniowej. Poniższy rysunek objaśnia graficznie, dlaczego niektóre wzorce LBP są różne od wzorców LBP .

square and circular neighbourhoods

Kod

w_cen = (1-1/np.sqrt(2))**2 # Weights 
w_diag = (1/np.sqrt(2))**2 
w_orto = (1-1/np.sqrt(2))*(1/np.sqrt(2)) 

def bilinear_interpoplation(i_cen, i_diag, i_hor, i_ver): 
    return i_cen*w_cen + i_diag*w_diag + i_hor*w_orto + i_ver*w_orto 

def circular_neighbourhood(x): 
    [I7, I6, I5] = x[0, :] 
    [I0, Ic, I4] = x[1, :] 
    [I1, I2, I3] = x[2, :] 
    I7i = bilinear_interpolation(Ic, I7, I0, I6) 
    I5i = bilinear_interpolation(Ic, I5, I4, I6) 
    I3i = bilinear_interpolation(Ic, I3, I4, I2) 
    I1i = bilinear_interpolation(Ic, I1, I0, I2) 
    interpolated = np.array([[I7i, I6, I5i], 
          [ I0, Ic, I4], 
          [I1i, I2, I3i]]) 
    return interpolated 

def binary_pattern(x): 
    return np.where(x >= x[1, 1], 1, 0) 

def display_lbps(patch): 
    interpolated = circular_neighbourhood(patch) 
    print('Patch =') 
    print(patch) 
    print('LBP of patch =') 
    print(binary_pattern(patch)) 
    print('Interpolated patch =') 
    print(interpolated) 
    print('LBP of interpolated patch =') 
    print(binary_pattern(interpolated)) 

display_lbps(image[0:3, 0:3]) 
display_lbps(image[1:4, 1:4]) 
Powiązane problemy