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



У меня возникли трудности с чтением изображения, извлечением функций для обучения и тестирования новых изображений в OpenCV с помощью SVMs. может кто-нибудь указать мне на отличную ссылку? Я посмотрел на введение 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} принадлежат кривой, а остальные-нет.

636   1  

1 ответ:

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

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

допустим, вы хотели обучить SVM на 5 разных изображениях, и каждое изображение было 4x3 пикселей. Сначала вам нужно будет инициализировать матрицу обучения. Количество строк в матрице будет равно 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 С данными от каждого изображения. Ниже приведен пример того, как это сопоставление будет работать для одной строки.

Convert 2D image matrix to 1D matrix

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

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

Training matrix with multiple images

как вы могли бы сделать это в коде, вы могли бы использовать 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, на основе моего глаза / не-глаза пример выше). Кроме того, если вы хотите проверить несколько изображений одновременно, вы можете создать матрицу, которая имеет тот же формат, что и обучающая матрица, определенная ранее, и передать ее в качестве аргумента. Возвращаемое значение будет другим.

удачи!

Comments

    Ничего не найдено.