Я хотел бы знать, как я могу использовать OpenCV для обнаружения на моей VideoCamera изображения. Изображение может быть одним из 500 изображений.
Что я делаю на данный момент:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.videoCamera = [[CvVideoCamera alloc] initWithParentView:imageView];
self.videoCamera.delegate = self;
self.videoCamera.defaultAVCaptureDevicePosition = AVCaptureDevicePositionBack;
self.videoCamera.defaultAVCaptureSessionPreset = AVCaptureSessionPresetHigh;
self.videoCamera.defaultAVCaptureVideoOrientation = AVCaptureVideoOrientationPortrait;
self.videoCamera.defaultFPS = 30;
self.videoCamera.grayscaleMode = NO;
}
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
[self.videoCamera start];
}
#pragma mark - Protocol CvVideoCameraDelegate
#ifdef __cplusplus
- (void)processImage:(cv::Mat&)image;
{
// Do some OpenCV stuff with the image
cv::Mat image_copy;
cvtColor(image, image_copy, CV_BGRA2BGR);
// invert image
//bitwise_not(image_copy, image_copy);
//cvtColor(image_copy, image, CV_BGR2BGRA);
}
#endif
Изображения, которые я хотел бы обнаружить, размером 2-5kb. Мало кто получил текст на них, но другие просто знаки. Вот пример:
Ребята, вы знаете, как я могу это сделать?
Здесь есть несколько вещей. Я разобью вашу проблему и укажу на некоторые возможные решения.
классификация: Ваша основная задача состоит в том, чтобы определить, принадлежит ли определенное изображение к классу. Эта проблема сама по себе может быть разложена на несколько проблем:
Представление функций Вы должны решить, как вы будете моделировать свой особенность, то есть, как вы собираетесь представлять каждое изображение в пространстве объектов, чтобы вы могли обучить классификатор для разделения этих классов. Представление функции само по себе уже является большим дизайнерским решением. Можно (я) рассчитать гистограмма из изображений с использованием n бинов и обучить классификатор или (ii) вы можете выбрать последовательность случайных сравнений патчей, например, в случайном лесу. Однако после обучения вам нужно оценить производительность вашего алгоритма, чтобы увидеть, насколько удачным было ваше решение.
Существует известная проблема под названием переобучения, когда вы слишком хорошо усвоили, что не можете обобщить свой классификатор. Этого обычно можно избежать с перекрестная проверка. Если вы не знакомы с концепцией ложного положительного или ложного отрицательного, взгляните на это статья.
После того как вы определили свое пространство признаков, вам нужно выбрать алгоритм для обучения этих данных, и это может рассматриваться как ваше самое важное решение. Есть несколько алгоритмов, выходящих каждый день. Чтобы назвать несколько классических: Наивный байесовский, SVM, Случайные Леса, и совсем недавно сообщество получило отличные результаты, используя Глубокое обучение. Каждый из них имеет свое специфическое использование (например, SVM отлично подходит для бинарной классификации), и вы должны быть знакомы с проблемой. Вы можете начать с простых предположений, таких как независимость между случайными переменными и обучить наивного Байеса классификатор попытаться отделить ваши изображения.
Патчи: Вы упомянули, что хотели бы распознать изображения с вашей веб-камеры. Если вы собираетесь распечатывать изображения и отображать их в видео, вам нужно разобраться с несколькими вещами. необходимо определить патчи для вашего большого изображения (вход от веб-камеры), в котором вы строите представление объектов для каждого патча и классифицируете так же, как вы делали это на предыдущем шаге. Для этого вы можете сдвинуть окно и классифицировать все патчи, чтобы увидеть, принадлежат ли они отрицательному классу или одному из положительных. Есть и другие альтернативы.
Масштаб: Учитывая, что вы можете определить местоположение изображений на большом изображении и классифицировать его, следующим шагом будет ослабление предположения о масштабах исправлений. Для обработки многомасштабного подхода вы можете пирамида что в значительной степени позволяет выполнять обнаружение в многократном разрешении. Альтернативные подходы могут учитывать детекторы ключевых точек, такие как ПРОСЕЯТЬ а также SURF. Внутри SIFT есть пирамида изображений, которая допускает неизменность.
проекция До сих пор мы предполагали, что у вас были изображения в ортогональной проекции, но, скорее всего, у вас будут небольшие перспективные проекции, которые приведут к провалу всего предыдущего предположения. Одним из наивных решений для этого было бы, например, обнаружить углы белого фона вашего изображения и исправить изображение перед созданием вектора объектов для классификации. Если вы используете SIFT или SURF, вы можете разработать способ избежать явной обработки этого. Тем не менее, если ваш вклад будет просто квадратными патчами, такими как в ARToolkit, Я бы пошел на ручное исправление.
Я надеюсь, что мог бы дать вам лучшее представление о вашей проблеме.
Я бы порекомендовал использовать для этого SURF, потому что изображения могут находиться на разных расстояниях от вашей камеры, то есть изменять масштаб. У меня был один подобный эксперимент, и SURF работал так, как ожидалось. Но SURF имеет очень сложную настройку (и дорогостоящие операции), вы должны попробовать различные настройки, прежде чем получите требуемые результаты.
Вот ссылка: http://docs.opencv.org/modules/nonfree/doc/feature_detection.html
YouTube видео (в C #, но может дать представление): http://www.youtube.com/watch?v=zjxWpKCQqJc
Возможно, я недостаточно квалифицирован, чтобы ответить на эту проблему. В прошлый раз, когда я серьезно использовал OpenCV, это было все еще 1.1. Но только некоторые думают об этом, и надеются, что это поможет (в настоящее время я интересуюсь DIP и ML).
Я думаю, что это, вероятно, будет более легкой задачей, если вам нужно только классифицировать изображение, если изображение только одно из (или очень похоже) из ваших 500 изображений. Для этого вы можете использовать SVM или некоторую нейронную сеть (Феликс уже дал превосходное перечисление по этому вопросу).
Однако, похоже, ваша проблема заключается в том, что вам сначала нужно найти это изображение-кандидата в вашей веб-камере, местоположение которой вы заранее не знаете. (дайте нам знать, так ли это. Я думаю, что это важно.)
Если это так, то более сложной проблемой является обнаружение / локализация вашего изображения-кандидата.
У меня нет общего решения для этого. Первое, что я хотел бы сделать, это посмотреть, есть ли какая-то общая черта в ваших 500 изображениях (например, все ли они заключены в красный круг, или половина из них имеет круг, а половина имеет прямоугольник). Если это можно сделать, проблема будет проще (это будет похоже на проблему с распознаванием лиц, которая имеет хорошее решение).
Другими словами, это означает, что вы сначала классифицируете 500 изображений по нескольким группам с общим признаком (по человеку), и сначала обнаруживаете группу, затем масштабируете и используете вышеупомянутую технику, чтобы классифицировать их в прекрасный результат. Таким образом, это будет более приемлемо с вычислительной точки зрения, чем попытка обнаружить 500 изображений одно за другим.
Кстати, этот ppt поможет визуально понять, что происходит для извлечения объектов и сопоставления изображений. http://courses.cs.washington.edu/courses/cse455/09wi/Lects/lect6.pdf.
Обнаружение против распознавания: обнаружение изображения — это просто нахождение его на заднем плане, и из ваших комментариев я понял, что ваши песни могут быть окружены фоном. Это может облегчить ваш алгоритм, если вы можете каким-то образом обрезать свои знаки с фона (обнаружить), прежде чем пытаться их распознать. Распознавание — это следующая стадия, которая предполагает, что вы можете правильно классифицировать обрезанное изображение, как показано ранее.
Если вам нужна скорость в реальном времени и инвариантность масштаба / вращения, ни SIFT, ни SURF не сделают это быстро. В настоящее время вы можете добиться большего успеха, если перенесете бремя обработки изображений на этап обучения, как это было сделано Lepitit. Короче говоря, он подверг каждый шаблон множеству аффинных преобразований и обучил двоичное дерево классификации правильно распознавать каждую точку, выполнив множество тестов двоичного сравнения. Деревья работают очень быстро, и не стоит упоминать, что большая часть обработки выполняется в автономном режиме. Этот метод также более устойчив к поворотам вне плоскости, чем SIFT или SURF. Вы также узнаете о древовидной классификации, которая может облегчить вам последнюю стадию обработки.
Наконец, этап распознавания основан не только на количестве совпадений, но и на их геометрической согласованности. Поскольку ваши знаки выглядят плоскими, я предлагаю найти аффинное или гомографическое преобразование, которое имеет наибольшее количество внутренних значений при расчете между соответствующими точками.
Глядя на ваш код, я понял, что вы можете не следовать ни одной из этих рекомендаций. Это может быть хорошей отправной точкой для вас, чтобы прочитать о деревья решений а затем поиграйте с некоторым примером кода (см. mushroom.cpp в вышеупомянутой ссылке)