OpenCV 根据图像集检测图像
Posted
技术标签:
【中文标题】OpenCV 根据图像集检测图像【英文标题】:OpenCV detect image against a image set 【发布时间】:2014-04-02 19:17:39 【问题描述】:我想知道如何使用 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。很少有文字在上面,但其他只是标志。这里举个例子:
你们知道我该怎么做吗?
【问题讨论】:
你尝试过这样的事情吗:***.com/questions/10168686/…? 图像会是视频图像的精确子图像吗?像水印?或者它们的大小、方向和视角会有所不同吗? @Micka 这取决于用户如何握住相机。还是你的意思是别的? 您好,我对您的问题有些困惑。我目前的理解是,用户可能在野外拿着相机拍街景一样的照片,你的目标是检测交通标志(有500个候选)。我说的对吗? 没错!也许对于启动你必须指向标志(在它前面拿着相机) 【参考方案1】:这里有几件事。我将分解您的问题并指出一些可能的解决方案。
分类:您的主要任务是确定某个图像是否属于某个类别。这个问题本身可以分解成几个问题:
Feature Representation 您需要决定如何对 特征 进行建模,即如何在特征空间中表示每个图像,以便训练分类器来分离这些图像类。特征表示本身已经是一个重大的设计决策。可以(i)使用 n 个 bin 计算图像的histogram 并训练分类器,或者(ii)您可以选择一系列随机补丁比较,例如在随机森林中。但是,在训练之后,您需要评估算法的性能,看看您的决定有多好。
有一个称为overfitting 的已知问题,即当您学习得太好而无法泛化分类器时。这通常可以通过cross-validation 避免。如果您不熟悉误报或误报的概念,请查看此article。
定义特征空间后,您需要选择一种算法来训练该数据,这可能是您最大的决定。每天都会出现几种算法。举几个经典的例子:Naive Bayes、SVM、Random Forests,最近社区使用Deep learning 取得了很好的成果。每一个都有自己的特定用途(例如,SVM 非常适合二进制分类),您需要熟悉这个问题。您可以从简单的假设开始,例如随机变量之间的独立性,然后训练朴素贝叶斯classifier 来尝试分离您的图像。
补丁:现在您提到要识别网络摄像头上的图像。如果您要打印图像并在视频中显示,您需要处理几件事情。有必要在您的大图像(来自网络摄像头的输入)上定义补丁,您可以在其中为每个补丁构建特征表示,并以与上一步相同的方式进行分类。为此,您可以滑动一个窗口并对所有补丁进行分类,以查看它们是属于负类还是属于其中一个正类。还有其他选择。
Scale:考虑到您能够检测大图像中图像的位置并对其进行分类,下一步是放宽固定比例的玩具假设。要处理多尺度方法,您可以对pyramid 进行成像,这几乎可以让您以多分辨率执行检测。替代方法可以考虑关键点检测器,例如SIFT 和SURF。在 SIFT 内部,有一个允许不变性的图像金字塔。
投影 到目前为止,我们假设您的图像处于正交投影下,但您很可能会有轻微的透视投影,这将使之前的整个假设失效。一种简单的解决方案是,例如检测图像白色背景的角落,并在构建特征向量进行分类之前对图像进行校正。如果您使用 SIFT 或 SURF,您可以设计一种避免显式处理的方法。不过,如果您的输入只是正方形补丁,例如在ARToolkit 中,我会进行手动更正。
我希望我可以让您更好地了解您的问题。
【讨论】:
感谢您的解释。我会等几天,直到我接受你的回答。也许有不同的观点。顺便说一句,算法 SURF 怎么样?我在哪里读到过关于图像处理的信息,我遇到了这个。这对我的任务不是很好吗? 嗨,SIFT 和 SURF 是关键点检测器。 SIFT 诞生的目的是识别“重要”点,这些点对比例和透视变换尽可能不变,即携带强梯度信息的点。您可以使用关键点来设计您的功能,并且可以摆脱规模问题。但如果我是你,我会从简单的假设(正交投影)开始,当你让它发挥作用时,开始放松这些假设。 youtube 上有关于 SIFT 和 SURF 的讲座。【参考方案2】:我可能没有足够的资格回答这个问题。上次我认真使用 OpenCV 时,它仍然是 1.1。但只是想了一下,希望对您有所帮助(目前我对 DIP 和 ML 感兴趣)。
我认为,如果您只需要对图像进行分类,并且该图像只是您的 500 张图像中的一张(或非常相似),那么这可能会更容易。为此,您可以使用 SVM 或一些神经网络(Felix 已经对此进行了很好的列举)。
但是,您的问题似乎是您需要先在网络摄像头中找到此候选图像,而您事先几乎没有任何线索。 (让我们知道是不是这样。我认为这很重要。)
如果是这样,更难的问题是候选图像的检测/定位。 我没有一个通用的解决方案。我要做的第一件事是查看您的 500 张图像中是否有一些共同特征(例如,它们是否都被红色圆圈包围,或者它们中的一半是圆形,一半是矩形)。如果能做到这一点,问题会更简单(类似于人脸检测问题,有很好的解决方案)。
换句话说,这意味着您首先将 500 张图像分类为具有共同特征的几组(由人类),并首先检测该组,然后缩放并使用上述技术将它们分类为精细结果。这样一来,它在计算上将比尝试一张一张地检测 500 张图像更容易接受。
顺便说一句,这个 ppt 将有助于为特征提取和图像匹配提供一个视觉线索http://courses.cs.washington.edu/courses/cse455/09wi/Lects/lect6.pdf。
【讨论】:
【参考方案3】:我建议为此使用 SURF,因为图片与相机的距离可能不同,即改变比例。我进行了一项类似的实验,SURF 的工作与预期一样。但是 SURF 的调整非常困难(并且操作成本很高),您应该尝试不同的设置,然后才能获得所需的结果。 这是一个链接:http://docs.opencv.org/modules/nonfree/doc/feature_detection.html youtube 视频(用 C# 编写,但可以给出一个想法):http://www.youtube.com/watch?v=zjxWpKCQqJc
【讨论】:
【参考方案4】:检测与识别:检测图像只是在背景中找到它,从您的 cmets 我意识到您的歌曲可能被背景包围。如果您可以在尝试识别它们之前以某种方式从背景中裁剪您的标志(检测),它可能会促进您的算法。识别是下一个阶段,假设您可以像之前看到的那样正确地对裁剪的图像进行分类。
如果您需要实时速度和缩放/旋转不变性,那么 SIFT 和 SURF 都不会很快做到这一点。如今,如果您像Lepitit 那样将图像处理的负担转移到学习阶段,您可以做得更好。简而言之,他对每个模式进行了一系列仿射变换,并通过大量的二进制比较测试训练了一个二进制分类树来正确识别每个点。树的速度非常快,而且是一种方法,更不用说大部分处理都是离线完成的。与 SIFT 或 SURF 相比,此方法对平面外旋转的鲁棒性也更强。您还将了解可能有助于您最后处理阶段的树分类。
最后,识别阶段不仅基于匹配的数量,还基于它们的几何一致性。由于您的符号看起来很平坦,我建议找到在匹配点之间计算时具有最多内点的仿射或单应变换。
查看您的代码虽然我意识到您可能没有遵循这些建议中的任何一个。这可能是您阅读decision trees 的一个很好的起点,然后使用一些示例代码(请参阅上述链接中的蘑菇.cpp)
【讨论】:
以上是关于OpenCV 根据图像集检测图像的主要内容,如果未能解决你的问题,请参考以下文章
youcans 的 OpenCV 例程200篇148. 图像分割之线检测