如何在小图片上使用Opencv FeatureDetecter
我在Java中使用Opencv 3,我试图在其他图像上找到小图像(如25x25像素)。 但FeatureDetector检测(0,0)大小小图片上的Mat。
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像素的大图像上尝试这种方式,那很好。 有什么建议么? 谢谢。
我在这里添加样品。 我们有这个源代码图片:
让我们说我们有P字母模板,所以我们需要在源图像上检测到这个P。
好吧,缩放图像到更高的分辨率将不适用于我。 这将会浪费时间和资源。 理想情况下,它应该是旋转尺度不变的。 但没有旋转和缩放的简单解决方案也可以。
除OpenCv之外的其他解决方案对我来说是不可接受的。 (例如使用Tesseract)
用于文本识别的关键点检测不是最佳解决方案,因为您将获得许多看起来相似的特征,并且如果模板非常小,滑动窗口将不会产生足够的检测特征。
幸运的是,OpenCV 3在contrib存储库中包含一个文本检测/识别模块:链接,从这里和其他许多地方可以找到这里找到的示例:
/*
* 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 = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; // 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;
}
您可以对图像进行重新采样,然后对图像进行重新采样,然后对其进行缩放并使用非常快速的过程,将每个像素映射到一组像素,直到解析度达到要求为止,在opencv中,您可以使用调整大小函数和INTER_AREA标志来实现: http://docs.opencv.org/2.4/modules/imgproc/doc/geometric_transformations.html
另一种解决方案可以是将图像复制到较大的空白图像,然后在较大的图像上运行检测。
它看起来像你试图读取PersonalID属性。 基本上,准备图像,矢量化图像(因此它的比例和旋转不变)并进行比较/匹配。 这可以在OpenCV中完成。
准备:通常你会减少颜色和亮度。 如果您的信件显眼,您可以使用阈值(亮度/颜色/ perColorChannel)并删除这些颜色。 对于你来说,你可能会减少几乎黑色的东西,变成白色。 您可能想要尝试更多的锐化和边缘检测。
矢量化非常简单,并且可以进一步改进,因为您知道您只对某些符号感兴趣,您应该找到可用于改善矢量化结果的附加质量(抑制噪声,更好地选择和校正某些边缘/角度等等)。
匹配应该非常简单。 既然你知道目标字体和潜在的符号,匹配应该产生很多积极的结果,并且具有很小的误差。 此外,大多数错误应该易于识别,以便可以将错误发送给某个人进行验证。
潜在的改进:
使用分形方法进行缩放通常可以很好地保留字母和数字的属性,并且可以提高结果的质量。
检测ID的不同部分将有助于识别检测的目标区域。 这可以让你进一步改进结果。 通常人们只关注他们想要认识的东西,忘记额外的不必要的信息。 但是这些信息让您了解您可能在检测中发现的潜在错误。 因此,如果您无法正确识别名称,则很可能您的ID也无法识别。 因此,如果图片的质量足以确定您真正关心的信息,那么试图获取ID的所有信息是一个很好的指标。
如果您确切知道您的目标区域是什么样的,您可以将目标区域缩放到固定大小并使用每像素匹配。 既然你确切知道你所关心的字体,这种检测可以有一个惊人的高检测率。 使用每像素匹配和矢量化会为您提供出众的检测率。 与矢量化相比,每像素匹配速度也非常快。
由于您知道预期符号的位置和大小,因此您可以根据属性(符号的实际大小,某些区域中黑色的分布等)创建决策树。 这会将问题从35分之一降到4分之一甚至更少。
上一篇: How to use Opencv FeatureDetecter on tiny images
下一篇: Combing 2D list of tuples and then sorting them in Python