Почему OpenCV распознает объект только на тренировочных изображениях?

Чтобы мое приложение для iOS распознало монеты достоинством 1 €, 2 € и 0,50 €, которые я пытался использовать opencv_createsamples а также opencv_traincascade создать свой собственный classifier.xml. Итак, я обрезал 60 изображений монет по 2 евро из короткого видео, как показано ниже:

введите описание изображения здесь

Затем я соединил их со случайными фонами, используя opencv_createsamples, Я получил 12000 изображений, похожих на это:

введите описание изображения здесь

и я выполнил следующие команды:

opencv_createsamples -img positives/i.jpg -bg negatives.txt -info i.txt -num 210 -maxidev 100 -maxxangle 0.0 -maxyangle 0.0 -maxzangle 0.9 -bgcolor 0 -bgthresh 0 -w 48 -h 48 (для меня от 0 до 60)

cat *.txt > positives.txt

opencv_createsamples -info positives.txt -bg negatives.txt -vec 2.vec -num 12600 -w 48 -h 48

opencv_traincascade -data final -vec 2.vec -bg negatives.txt -numPos 12000 -numNeg 3000 -numStages 20 -featureType LBP -precalcValBufSize 2048 -precalcIdxBufSize 2048 -minHitRate 0.999 -maxFalseAlarmRate 0.5 -w 48 -h 48

Тренировки остановились на 13-м этапе. Однажды я получил cascade.xml Я попробовал это сразу (с detectMultiScale()) на простом изображении, сделанном моим смартфоном, но ничего не обнаружено:

введите описание изображения здесь

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

введите описание изображения здесь

Я не могу понять, почему это происходит, и это сводит меня с ума, прежде всего потому, что я пытался заставить это работать в течение нескольких недель … не могли бы вы сказать мне, где я совершаю ошибку?

Короткая программа, которую я написал, здесь:

#include "opencv2/opencv.hpp"
using namespace cv;

int main(int, char**) {

Mat src = imread("2b.jpg");

Mat src_gray;

std::vector<cv::Rect> money;

CascadeClassifier euro2_cascade;

cvtColor(src, src_gray, CV_BGR2GRAY );
equalizeHist(src_gray, src_gray);

if ( !euro2_cascade.load( "cascade.xml" ) ) {
printf("--(!)Error loading\n");
return -1;
}

euro2_cascade.detectMultiScale( src_gray, money, 1.1, 3, 0|CASCADE_SCALE_IMAGE/*CV_HAAR_FIND_BIGGEST_OBJECT | CV_HAAR_SCALE_IMAGE*/, cv::Size(10, 10),cv::Size(2000, 2000) );
printf("%d\n", int(money.size()));

for( size_t i = 0; i < money.size(); i++ ) {
cv::Point center( money[i].x + money[i].width*0.5, money[i].y + money[i].height*0.5 );
ellipse( src, center, cv::Size( money[i].width*0.5, money[i].height*0.5), 0, 0, 360, Scalar( 255, 0, 255 ), 4, 8, 0 );
}

namedWindow( "Display window", WINDOW_AUTOSIZE );
imwrite("result.jpg",src);
}

Я также пытался принять во внимание особенность омографии для моей версии 3.1 OpenCV. Таким образом, я скачал opencv_contrib для своей версии и попытался скомпилировать модуль xfeatures2d, но я получаю ошибку CMake в файле CMakeList … более того, xfeature2d даже не присутствует в рамках opencv для xcode, поэтому даже если я заставлю его работать на моем компьютере, я смогу не использовать его в iOS в любом случае …

ОБНОВИТЬ

Как советовали, я только что попытался удалить equalizeHist(src_gray, src_gray); и я установил количество соседей в detectMultiScale () «, и это то, что я получаю:

введите описание изображения здесь

ОБНОВЛЕНИЕ 2

Как кто-то предложил, после этот Учебное пособие Я только что создал файл .vec, используя только обрезанные положительные изображения, только с монетой. Я использовал эту команду:

opencv_createsamples -vec i.vec -w 48 -h 48 -num 210 -img ./positives/i.jpg -maxidev 100 -maxxangle 0 -maxyangle 0 -maxzangle 0.9 -bgcolor 0 -bgthresh 0
(для меня от 0 до 60)

Итак, как вы можете видеть, для создания образцов не используется фоновое изображение.
Затем после загрузки mergevec.py, Я объединил все файлы векторов вместе. Теперь я собираюсь начать еще одну тренировку LBP … Я надеюсь, что она будет работать лучше

8

Решение

Ваш каскад не был обучен должным образом.
Для вашей монеты вы должны добавить не только другой фон, но и разные масштабы и разные повороты на 3 угла.
Также добавьте больше негативов для обучения (у вас есть много небольших обнаружений, которые означают, что каскад не обучен на негативах)

1

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

Это может быть причиной из-за отсутствия данных обучения, которые представляют общий сценарий возможных случаев. Вы не представляете полную информацию для Модели. Если у вас нет больше данных,

  1. Вы должны вращать изображения, обрезать их в произвольном размере и под углом, переворачивая (зеркальное отображение вдоль вертикального края) в основном Увеличение данных
  2. Ты можешь сделать разделение фона а затем использовать модель для классификации
  3. Конвертировать изображения в grey scale и затем используйте классификационную модель (иногда цвет может ввести модель в заблуждение)
1

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