2016-06-02 3 views
7

Я использую Opencv 3 в Java, я пытаюсь найти небольшие изображения (например, 25x25 пикселей) на другое изображение. Но FeatureDetector detection (0,0) размер Mat на маленьком изображении.Как использовать Opencv FeatureDetecter на крошечных изображениях

Mat smallImage = ... 

    FeatureDetector detector = FeatureDetector.create(FeatureDetector.ORB); 
    DescriptorExtractor descriptor = DescriptorExtractor.create(DescriptorExtractor.ORB); 
    DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING); 

    Mat descriptorsSmall = new Mat(); 
    MatOfKeyPoint keyPointsSmall = new MatOfKeyPoint(); 

    detector.detect(smallImage, keyPointsSmall); 
    descriptor.compute(smallImage, keyPointsSmall, descriptorsSmall); 

Здесь я получаю keyPointsSmall и descriptorsSmall размер как ноль, и уверен, что обнаружение не работает.

Но если я попробую это на больших изображениях, как 150x150 пикселей, которые работают нормально. Любые предложения? Спасибо.

Здесь я добавляю образцы. у нас есть этот исходный файл: This is source image

И пусть говорят, что мы имеем шаблон для P письма, поэтому мы должны обнаружить эту P на исходном изображении. This is template

ну, масштабирование изображения до более высокого разрешения не будет работать для меня. Это будет потеряно во времени и ресурсе. В идеале это должен быть инвариант масштаба вращения. Но простое решение без вращения и масштабирования также в порядке.

Другие решения, кроме OpenCv, не подходят для меня. (например, используя Tesseract)

+0

Можете ли вы также предоставить некоторые входные данные, над которыми вы работали? – ZdaR

+0

Я думаю, что лучшим образцом будет распознавание текста, представьте, что у вас есть значки каждой буквы, например 20x25 пикселей, поэтому попытайтесь распознать эти буквы с другого изображения. Для простоты можно сказать, что семейство шрифтов и шрифт одинаковы с образцами. – RustamIS

+0

Да, но если бы вы могли напрямую предоставить набор данных, над которым вы работаете, тогда мы сможем воспроизвести проблему. – ZdaR

ответ

1

Похоже, вы пытаетесь прочитать свойства PersonalID. Басиально то, что он делает, это подготовка изображений, векторизация (так его масштаб и инвариант вращения) и сравнение/совпадение. Это можно сделать в OpenCV.

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

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

  3. Соответствие должно быть достаточно простым. Поскольку вы знаете целевой шрифт и потенциальные символы, сопоставление должно давать много положительных результатов с очень тонким пределом погрешности. Кроме того, большинство ошибок должно быть легко узнаваемо, так что могут существовать несколько ошибок, которые вы можете отправить человеку для проверки.

Потенциальные Улучшения:

  1. Масштабирование с использованием фрактальной подход часто с сохранением свойств букв и цифр очень хорошо и может повысить качество результата.

  2. Обнаружение различной части идентификаторов поможет вам определить целевую область обнаружения. Это позволяет улучшить результаты. Часто люди просто сосредоточены на том, что они хотят распознать и забыть о дополнительной ненужной информации. Но эта информация дает вам представление о потенциальной ошибке, которую вы можете обнаружить при обнаружении. Поэтому, если вы не можете правильно распознать имя, вероятно, вы также потерпите неудачу в ID.Таким образом, попытка получить всю информацию об идентификаторе является хорошим показателем, если качество изображения достаточно хорошее, чтобы быть уверенным в информации, которую вы действительно заботитесь.

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

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

1

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

Лаки для вас, OpenCV 3 содержит модуль обнаружения текста/распознавания в хранилище CONTRIB: link, с примером, взятым из here и многих других, чтобы найти here:

/* 
* cropped_word_recognition.cpp 
* 
* A demo program of text recognition in a given cropped word. 
* Shows the use of the OCRBeamSearchDecoder class API using the provided default classifier. 
* 
* Created on: Jul 9, 2015 
*  Author: Lluis Gomez i Bigorda <lgomez AT cvc.uab.es> 
*/ 

#include "opencv2/text.hpp" 
#include "opencv2/core/utility.hpp" 
#include "opencv2/highgui.hpp" 
#include "opencv2/imgproc.hpp" 

#include <iostream> 

using namespace std; 
using namespace cv; 
using namespace cv::text; 

int main(int argc, char* argv[]) 
{ 

    cout << endl << argv[0] << endl << endl; 
    cout << "A demo program of Scene Text Character Recognition: " << endl; 
    cout << "Shows the use of the OCRBeamSearchDecoder::ClassifierCallback class using the Single Layer CNN character classifier described in:" << endl; 
    cout << "Coates, Adam, et al. \"Text detection and character recognition in scene images with unsupervised feature learning.\" ICDAR 2011." << endl << endl; 

    Mat image; 
    if(argc>1) 
     image = imread(argv[1]); 
    else 
    { 
     cout << " Usage: " << argv[0] << " <input_image>" << endl; 
     cout << "   the input image must contain a single character (e.g. scenetext_char01.jpg)." << endl << endl; 
     return(0); 
    } 

    string vocabulary = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; // must have the same order as the clasifier output classes 

    Ptr<OCRHMMDecoder::ClassifierCallback> ocr = loadOCRHMMClassifierCNN("OCRBeamSearch_CNN_model_data.xml.gz"); 

    double t_r = (double)getTickCount(); 
    vector<int> out_classes; 
    vector<double> out_confidences; 

    ocr->eval(image, out_classes, out_confidences); 

    cout << "OCR output = \"" << vocabulary[out_classes[0]] << "\" with confidence " 
     << out_confidences[0] << ". Evaluated in " 
     << ((double)getTickCount() - t_r)*1000/getTickFrequency() << " ms." << endl << endl; 

    return 0; 
} 
1

Вы можете дискретизацию изображения, его много быстрее, масштабирование и очень быстрая процедура по его дальше, его просто отображения каждого пикселя к набору пикселей, пока разрешение не будет в соответствии с просьбой, в OpenCV вы можете сделать это с помощью функции изменения размера и INTER_AREA флаг: http://docs.opencv.org/2.4/modules/imgproc/doc/geometric_transformations.html

Другим решением может быть просто копирование изображения на большее пустое изображение и запуск обнаружения на более крупном.