Машинное обучение в компьютерном зрении Филимонов Алексей Катаев Александр

advertisement
Машинное обучение
в компьютерном зрении
Филимонов Алексей
Катаев Александр
Singularis Lab, LLC
Найди кота!
22 - 24 октября, Москва
2
Что это?
22 - 24 октября, Москва
3
Как мы видим
Классификация
Локализация
Детектирование
Сегментация
22 - 24 октября, Москва
4
Признаки объектов
Цвет
Текстура
Форма
*Динамика
***Структура объекта
*****Контекст (сцена)
22 - 24 октября, Москва
5
Дерево решений
Желтое?
Гладкий и
блестящий?
Круглое?
Земля!
Монотонная
текстура?
Гамбургер!
22 - 24 октября, Москва
Лимон!
Теннисный
мяч!
Лайм!
6
Пространство признаков
Многоцветность
Гамбургеры
Лимоны
Лаймы
Желтизна
22 - 24 октября, Москва
7
Пространство признаков
22 - 24 октября, Москва
8
Классификация
?
22 - 24 октября, Москва
9
Ближайший сосед
22 - 24 октября, Москва
10
K ближайших соседей
22 - 24 октября, Москва
11
K ближайших соседей
22 - 24 октября, Москва
12
Линейное разделение
22 - 24 октября, Москва
13
Оптимальная гиперплоскость
22 - 24 октября, Москва
14
Опорные вектора
22 - 24 октября, Москва
15
Нелинейное разделение
признак
22 - 24 октября, Москва
16
признак^2
Нелинейное разделение
признак
22 - 24 октября, Москва
17
Простой пример: распознавание символов
22 - 24 октября, Москва
18
Распознавание символов: простой пример?
22 - 24 октября, Москва
19
THE MNIST DATABASE of handwritten digits
22 - 24 октября, Москва
20
Растр
22 - 24 октября, Москва
21
Загрузка данных
images_with_labels = []
path = 'd:/_databases/digits/'
# Загрузка большого количества картинок - затратный процесс,
# для оптимизации сохраняем загруженные массивы данных в файл,
UseFiles = False #True для загрузки из заранее подготовленных файлов
if UseFiles:
images_with_labels = np.load(path+"digits1000.npy")
else:
for num in range(0,10):
k = 0
for (dirpath, dirnames, filenames) in walk(path+str(num)):
for filename in filenames:
image = cv2.imread(dirpath+'/'+filename,0)
images_with_labels.append( (image, num) );
k+=1
if k >= 1000:
break
np.save(path+"digits1000.npy", images_with_labels)
# размеры изображения
W = images_with_labels[0][0].shape[1]
H = images_with_labels[0][0].shape[0]
22 - 24 октября, Москва
23
Подготовка выборок
NTrain = 70
NTest = 100 - NTrain
# 70% в обучающую выборку
# Остальные в тестовую выборку
train = []
test = []
for i in range(0, len(images_with_labels)-len(images_with_labels) % 100, 1
00):
train.extend(images_with_labels[i:i+NTrain])
test.extend(images_with_labels[i+NTrain:i+100])
# разбиваем каждую выборку на на 2 массива: данные и метки
train, train_labels = zip(*train)
test, test_labels = zip(*test)
# преобразуем списки в Numpy массивы
train = np.array(train)
test = np.array(test)
train_labels = np.array(train_labels).reshape(-1, 1)
test_labels = np.array(test_labels).reshape(-1, 1)
print 'Размер обучающей выборки: ', train.shape[0]
print 'Размер тестовой выборки: ', test.shape[0]
22 - 24 октября, Москва
24
Загрузка картинок
# Выбираем по одному изображению каждой цифры для визуализации
test_subset = [next(index for index in range(1,len(test)) if test_labels[inde
x] == num) for num in range(0,10)]
#рисуем выбранные цифры
plt.figure(1)
f, axarr = plt.subplots(1,10,figsize=(5,5))
for i in range (0,10):
axarr[i].imshow(test[test_subset[i]],cmap = cm.Greys_r)
axarr[i].axis('off')
plt.show()
22 - 24 октября, Москва
25
Обучение kNN
# вытягиваем все картинку в линию
train_data = train.reshape(-1,W*H).astype(np.float32)
# Создаем и обучаем классификатор
knn = cv2.KNearest()
tstart = dt.datetime.now()
knn.train(train_data,train_labels)
telapsed = dt.datetime.now() - tstart
print "Время обучения: ", telapsed.total_seconds()
Время обучения: 0.011
22 - 24 октября, Москва
26
Тестирование kNN
test_data = test.reshape(-1,W*H).astype(np.float32)
# Классификация тестовой выборки и оценка ошибки
tstart = dt.datetime.now()
ret,result,neighbours,dist = knn.find_nearest(test_data,k=3)
telapsed = dt.datetime.now() - tstart
correct = np.count_nonzero(result==test_labels)
print "kNN accuracy = ", correct*100.0/result.size
print "Время тестирования: ", telapsed.total_seconds()
kNN accuracy = 93.8333333333
Время тестирования: 20.932
22 - 24 октября, Москва
27
Тестирование kNN
#Визуализация части результата
plt.figure(1)
f, axarr = plt.subplots(1,10,figsize=(5,5))
for i in range (0,10):
axarr[i].imshow(test[test_subset[i]],cmap = cm.Greys_r)
axarr[i].axis('off')
axarr[i].set_title(result[test_subset[i]])
plt.show()
22 - 24 октября, Москва
28
Обучение SVM
svm_params = dict( kernel_type = cv2.SVM_POLY,
svm_type = cv2.SVM_C_SVC,
degree=2, C=1, gamma=1 )
svm = cv2.SVM()
tstart = dt.datetime.now()
svm.train(train_data,train_labels, params=svm_params)
telapsed = dt.datetime.now() - tstart
print "Время обучения: ", telapsed.total_seconds()
Время обучения: 6.516
22 - 24 октября, Москва
29
Тестирование SVM
test_data = test.reshape(-1,W*H).astype(np.float32)
tstart = dt.datetime.now()
result_svm = svm.predict_all(test_data)
telapsed = dt.datetime.now() - tstart
correct = np.count_nonzero(result_svm==test_labels)
print "SVM accuracy = ", correct*100.0/result.size
print "Время тестирования: ", telapsed.total_seconds()
SVM accuracy = 95.1333333333
Время тестирования: 3.686
22 - 24 октября, Москва
30
Пример с распознаванием маркеров
Реализовать обучение системы по фотографиям маркеров
Подготовка:
0. Загрузить базу фотографий маркеров и обучить классификатор
на ней
Для каждого кадра:
1. Найти координаты маркера
2. Вычислить трансформацию маркера и восстановить его форму
3. Классифицировать маркер с помощью обученного классификатора
4. Вычислить трансформацию изображения для совмещения с маркером
5. Вывести изображение поверх маркера
6. Отобразить результат на экране
22 - 24 октября, Москва
31
Создание базы маркеров
1. Сохраняем изображения, получаемые с
камеры:
static int counter = 0;
counter ++;
char name[100];
sprintf(name, "data\\m\\%04.png", counter);
imwrite(name, markerImage);
2. Сортируем вручную
22 - 24 октября, Москва
32
Загрузка изображений маркеров
char *classes[] = { "cat", "apple", "rob" };
Mat data, labels;
Size markerSize;
// Загружаем файлы, вытягиваем их в строку и вставляем в матрицу data
for ( int c = 0; c < 3; ++ c ) {
for ( int i = 0; i < 150; ++ i ) {
char name[100];
sprintf(name, "data\\m\\%s-%04i.png", classes[c],i+1);
Mat im = imread( name );
if ( !im.empty() ) {
if ( data.empty() ) {
data = im.reshape(1, 1);
labels = Mat::zeros(1,1,CV_32F);
} else {
vconcat(data, im.reshape(1, 1), data);
vconcat(labels, Mat::ones(1,1,CV_32F)*c, labels);
}
markerSize = im.size();
}
}
}
22 - 24 октября, Москва
33
Обучение и идентификация маркера
// Обучение классификатора
data.convertTo(data, CV_32F);
auto train_data = ml::TrainData::create(
data, ml::SampleTypes::ROW_SAMPLE, labels);
auto knn = ml::KNearest::create();
knn->train(train_data);
// Выбор маркера с помощью классификатора
Mat data;
marker.reshape(1,1).convertTo(data, CV_32F);
int bestIndex = knn->findNearest(data, 1,
noArray());
22 - 24 октября, Москва
34
Признаки изображений
•
•
•
•
•
•
•
•
•
Значения цвета и яркости пикселей
Моменты
Направления градиентов
Гистограммы градиентов (HOG)
Гистограммы цветовых компонент
Свертки различными ядрами
LBP
Haar
…
22 - 24 октября, Москва
35
Спасибо за внимание
Алексей Филимонов
• aleksey.filimonov@singularis-lab.com
Александр Катаев
• alexander.kataev@singularis-lab.com
36
Download