использование OpenCV и SVM с изображениями

У меня возникают трудности с чтением изображения, извлечением функций для обучения и тестированием новых изображений в OpenCV с использованием SVM. Может кто-нибудь, пожалуйста, укажите мне отличную ссылку? Я посмотрел на OpenCV Введение в опорные векторные машины. Но это не помогает с чтением в изображениях, и я не уверен, как включить это.


Мои цели — классифицировать пиксели в изображении. Эти пиксели будут принадлежать кривым. Я понимаю формирование тренировочной матрицы (например,
изображение А
1,1 1,2 1,3 1,4 1,5
2,1 2,2 2,3 2,4 2,5
3,1 3,2 3,3 3,4 3,5

Я сформировал бы свою тренировочную матрицу как [3] [2] = {{1,1} {1,2} {1,3} {1,4} {1,5} {2,1} .. {} }

Тем не менее, я немного запутался в отношении этикеток. Из моего понимания я должен указать, какая строка (изображение) в обучающей матрице соответствует, которая соответствует кривой или не кривой. Но как я могу пометить строку обучающей матрицы (изображение), если есть некоторые пиксели, принадлежащие кривой, а некоторые не принадлежащие кривой. Например, моя тренировочная матрица: [3] [2] = {{1,1} {1,2} {1,3} {1,4} {1,5} {2,1} .. {}} пиксели {1,1} и {1,4} принадлежат кривой, а остальные нет.

59

Решение

Мне пришлось столкнуться с этим недавно, и вот что я в итоге сделал, чтобы заставить SVM работать с изображениями.

Чтобы обучить свой SVM на наборе изображений, сначала вы должны построить матрицу обучения для SVM. Эта матрица указывается следующим образом: каждая строка матрицы соответствует одному изображению, а каждый элемент в этой строке соответствует одному признаку класса — в этом случае цвет пикселя в определенной точке. Поскольку ваши изображения 2D, вам нужно будет преобразовать их в 1D матрицу. Длина каждой строки будет соответствовать площади изображений (обратите внимание, что изображения должны быть одинакового размера).

Допустим, вы хотели обучить SVM на 5 разных изображениях, и каждое изображение было размером 4х3 пикселя. Сначала вам нужно будет инициализировать тренировочную матрицу. Количество строк в матрице будет 5, а количество столбцов будет площадь изображения, 4 * 3 = 12.

int num_files = 5;
int img_area = 4*3;
Mat training_mat(num_files,img_area,CV_32FC1);

В идеале, num_files а также img_area не будет жестко закодирован, но получен из циклического просмотра каталога и подсчета количества изображений и получения реальной площади изображения.

Следующим шагом является «заполнение» строк training_mat с данными из каждого изображения. Ниже приведен пример того, как это отображение будет работать для одной строки.

Конвертировать матрицу 2D изображения в 1D матрицу

Я пронумеровал каждый элемент матрицы изображения, указав, куда он должен идти в соответствующей строке в обучающей матрице. Например, если бы это было третье изображение, это была бы третья строка в обучающей матрице.

Вы должны были бы пройтись по каждому изображению и соответственно установить значение в выходной матрице. Вот пример для нескольких изображений:

Учебная матрица с несколькими изображениями

Что касается того, как вы будете делать это в коде, вы можете использовать reshape(), но у меня были проблемы с этим из-за того, что матрицы не были непрерывными. По своему опыту я сделал что-то вроде этого:

Mat img_mat = imread(imgname,0); // I used 0 for greyscale
int ii = 0; // Current column in training_mat
for (int i = 0; i<img_mat.rows; i++) {
for (int j = 0; j < img_mat.cols; j++) {
training_mat.at<float>(file_num,ii++) = img_mat.at<uchar>(i,j);
}
}

Сделайте это для каждого тренировочного образа (не забывая увеличивать file_num). После этого у вас должна быть правильно настроена тренировочная матрица для перехода к функциям SVM. Остальные шаги должны быть очень похожи на примеры в Интернете.

Обратите внимание, что при этом вы также должны установить метки для каждого тренировочного образа. Так, например, если вы классифицировали глаза и не глаза на основе изображений, вам нужно будет указать, какая строка в обучающей матрице соответствует глазу и не глазу. Это указывается как 1D матрица, где каждый элемент в 1D матрице соответствует каждой строке в 2D матрице. Выберите значения для каждого класса (например, -1 для не-глаза и 1 для глаза) и установите их в матрице меток.

Mat labels(num_files,1,CV_32FC1);

Так что, если 3-й элемент в этом labels матрица была -1, это означает, что 3-я строка в обучающей матрице находится в классе «без глаз». Вы можете установить эти значения в цикле, где вы оцениваете каждое изображение. Одна вещь, которую вы могли бы сделать, это отсортировать обучающие данные в отдельные каталоги для каждого класса, пройтись по изображениям в каждом каталоге и установить метки на основе каталога.

Следующее, что нужно сделать, это настроить параметры SVM. Эти значения будут варьироваться в зависимости от вашего проекта, но в основном вы бы объявили CvSVMParams Объект и установить значения:

CvSVMParams params;
params.svm_type = CvSVM::C_SVC;
params.kernel_type = CvSVM::POLY;
params.gamma = 3;
// ...etc

В Интернете есть несколько примеров того, как установить эти параметры, как в ссылке, которую вы разместили в вопросе.

Далее вы создаете CvSVM возражать и тренировать его на основе ваших данных!

CvSVM svm;
svm.train(training_mat, labels, Mat(), Mat(), params);

В зависимости от того, сколько у вас есть данных, это может занять много времени. Однако после завершения обучения вы можете сохранить обученный SVM, чтобы вам не приходилось каждый раз переучивать его.

svm.save("svm_filename"); // saving
svm.load("svm_filename"); // loading

Чтобы проверить ваши изображения с помощью обученного SVM, просто прочитайте изображение, преобразуйте его в 1D матрицу и передайте его в svm.predict():

svm.predict(img_mat_1d);

Он будет возвращать значение, основанное на том, что вы установили в качестве метки (например, -1 или 1, на основе приведенного выше примера для моего глаза / глаза). В качестве альтернативы, если вы хотите проверить более одного изображения за раз, вы можете создать матрицу, которая имеет тот же формат, что и обучающая матрица, определенная ранее, и передать ее в качестве аргумента. Однако возвращаемое значение будет другим.

Удачи!

208

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]