Длина гистограммы отличается в случае - PullRequest
0 голосов
/ 07 мая 2018

Я использую алгоритм LBP для классификации images по их особенностям текстуры. Классификационный метод - LinearSVC в sklearn.svm упаковке.

Получение гистограммы и подгонка по SVM выполнено, но иногда length из histogram изменяется в зависимости от image.

Пример ниже:

from skimage import feature
from scipy.stats import itemfreq
from sklearn.svm import LinearSVC
import numpy as np
import cv2
import cvutils
import csv
import os

def __get_hist(image, radius):
    NumPoint = radius*8
    lbp = feature.local_binary_pattern(image, NumPoint, radius, method="uniform")
    x = itemfreq(lbp.ravel())
    hist = x[:,1]/sum(x[:,1])
    return hist
def get_trainHist_list(train_txt):
    train_dic = {}
    with open(train_txt, 'r') as csvfile:
        reader = csv.reader(csvfile, delimiter = ' ')
        for row in reader:
            train_dic[row[0]] = int(row[1])

    hist_list=[]
    key_list=[]
    label_list=[]
    for key, label in train_dic.items():
        img = cv2.imread("D:/Python36/images/texture/%s" %key, cv2.IMREAD_GRAYSCALE)
        key_list.append(key)
        label_list.append(label)
        hist_list.append(__get_hist(img,3))
    bundle = [np.array(key_list), np.array(label_list), np.array(hist_list)]
    return bundle

train_txt = 'D:/Python36/images/class_train.txt'
train_hist = get_trainHist_list(train_txt)
model = LinearSVC(C=100.0, random_state=42)
model.fit(train_hist[2], train_hist[1])
for i in train_hist[2]:
    print(len(i))

test_img = cv2.imread("D:/Python36/images/texture_test/flat-3.png", cv2.IMREAD_GRAYSCALE)
hist= np.array(__get_hist(test_img, 3))
print(len(hist))
prediction = model.predict([hist])
print(prediction)

результат

26
26
26
26
26
26
25
Traceback (most recent call last):
  File "D:\Python36\texture.py", line 44, in <module>
    prediction = model.predict([hist])
  File "D:\Python36\lib\site-packages\sklearn\linear_model\base.py", line 324, in predict
    scores = self.decision_function(X)
  File "D:\Python36\lib\site-packages\sklearn\linear_model\base.py", line 305, in decision_function
    % (X.shape[1], n_features))
ValueError: X has 25 features per sample; expecting 26

Как видите, length из histogram для training images - это все 26, а test_img - 25. По этой причине predict в SVM не работает.

Я думаю, test_img имеет пустые части в histogram, и эти пустые части могли быть пропущены. (Я не уверен)

У кого-нибудь есть идея, чтобы это исправить?

1 Ответ

0 голосов
/ 07 мая 2018

Существует 59 различных одинаковых LBP для окрестности 8 точек. Это должно быть измерение ваших векторов объектов, но это не потому, что вы использовали itemfreq для вычисления гистограмм (в качестве примечания: itemfreq устарело). Длина гистограмм, полученных через itemfreq, представляет собой количество различных однородных LBP на изображении. Если на изображении отсутствуют какие-либо однородные LBP, количество бинов в полученной гистограмме будет меньше 59. Эту проблему можно легко исправить, используя bincount, как показано в примере с игрушкой ниже:

import numpy as np
from skimage import feature
from scipy.stats import itemfreq

lbp = np.array([[0, 0, 0, 0],
                [1, 1, 1, 1],
                [8, 8, 9, 9]])

hi = itemfreq(lbp.ravel())[:, 1]  # wrong approach
hb = np.bincount(lbp.ravel(), minlength=59)  # proposed method

Вывод выглядит так:

In [815]: hi
Out[815]: array([4, 4, 2, 2], dtype=int64)

In [816]: hb
Out[816]: 
array([4, 4, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0], dtype=int64)
...