龙空技术网

对象检测:LBP级联分类器生成

林小婵的店 277

前言:

此时看官们对“opencv中的lbp算法”都比较关注,姐妹们都想要学习一些“opencv中的lbp算法”的相关文章。那么小编在网上搜集了一些关于“opencv中的lbp算法””的相关资讯,希望我们能喜欢,小伙伴们一起来了解一下吧!

目前传统的物体检测方法是Tensorflow,YOLO等。但我想介绍一条较少走过的路。尽管级联分类器并不像神经网络和深度学习框架那样强大,但由于其简单性,它对于初学者机器学习开发人员来说是一个很好的开始。它非常轻巧,适合在像Raspberry Pi这样的资源受限的设备上使用。

顾名思义,级联分类器是许多分类器的串联。每个分类器形成级联流水线的一个阶段,并用作滤除负数的过滤器。当我们沿着管道向上移动时,分类器变得越来越复杂。每个复杂的分类器都由管道下的基本分类器组成。这叫做boosting。

现在我们如何组合基本的分类器来获得复杂的分类器?为此,boosting提供了4个变体:Real AdaBoost,Gentle AdaBoost,Discrete AdaBoost和LogitBoost。我不会陷入每种类型的错综复杂。完全可以说,我将在本教程中使用Gentle AdaBoost。

AdaBoost最初创建一个强大的学习者,通常是一个决策树,并迭代地创建一个弱学习者,并将其添加到强大的学习者中。在每次迭代中,误分类的权重增加,并且正确预测的实例的权重减小。弱学习者因此更多地关注错误分类即困难的情况。弱学习者的准确性被用作判断弱学习者对强大学习者的影响的标准。准确性越高,对学习者的贡献就越大。重复该过程直到达到所需的错误率。

好吧,现在你知道它是什么了,让我们看看你如何生成级联分类器。我选择生成LBP分类器,即基于LBP(本地二进制模式)特征检测对象的分类器。您可以使用以下步骤生成比LBP更准确的Haar分类器。但是,如果你处于紧张状态,我会推荐LBP,因为Haar需要几周的时间来训练。

在开始之前,请确保您已安装OpenCV。

创建分类器的主要步骤是:

收集负面和正面的图像和预处理创建背景描述文件创建测试样本和注释文件生成特征矢量文件并合并它们使用opencv_traincascade实用程序进行级联训练收集负面和正面的图像和预处理:

对于LBP分类器的训练,我们需要正面和负面的图像。正像是车辆的图像,负像是没有任何车辆的图像。负面图像是从ImageNet的API 下载的。

我们使用Python脚本访问图像synset API链接,获取图像URL,然后继续到URL处的图像。从这里,我们抓取图像,转换为灰度,调整大小为100X100,然后将其保存在名为“neg”的文件夹中。我们执行相同的代码来收集来自不同synsets的不同负片图像。Python脚本如下:

import numpy as np

import os

def store_raw_images():

neg_image_link = '//image-net.org/api/text/imagenet.synset.geturls?wnid=n00523513'

neg_image_urls = urllib.request.urlopen(neg_images_link).read().decode()

pic_num = 1

if not os.path.exists('neg'):

os.makedirs('neg')

for i in neg_image_urls.split('\n'):

try:

print(i)

urllib.request.urlretrieve(i, "neg/"+str(pic_num)+".jpg")

img = cv2.imread("neg/"+str(pic_num)+".jpg",cv2.IMREAD_GRAYSCALE)

resized_image = cv2.resize(img, (100, 100))

cv2.imwrite("neg/"+str(pic_num)+".jpg",resized_image)

pic_num += 1

except Exception as e:

print(str(e))

要删除从synsets下载的空白“丑陋”图像,您可以使用这个漂亮的小功能。首先,将任何一个空白图像复制到uglies文件夹并运行该功能。

def find_uglies():

match = False

for file_type in ['neg']:

for img in os.listdir(file_type):

for ugly in os.listdir('uglies'):

try:

current_image_path = str(file_type)+'/'+str(img)

ugly = cv2.imread('uglies/'+str(ugly))

question = cv2.imread(current_image_path)

if ugly.shape == question.shape and not(np.bitwise_xor(ugly,question).any()):

print('Deleting!')

print(current_image_path)

os.remove(current_image_path)

except Exception as e:

print(str(e))

现在对于正面的图像,我创建了一个名为“pos”的目录来存储正面图像。每张正面图像都会裁剪为仅包含车辆。

同样,我收集了5个正面图像,转换为灰度并调整为70x70。请注意调整大小以保持宽高比并且不要过度扭曲图像。

创建背景描述文件

后台描述文件是一个文本文件,其中包含neg文件夹中每个负面图像的相对路径。使用以下Python代码来创建它。

def create_neg():

for file_type in ['neg']:

for img in os.listdir(file_type):

line = file_type+'/'+img+'\n'

with open('bg.txt','a') as f:

f.write(line)

所以现在你应该有一个看起来像这样的bg.txt文件:

创建测试样本和注释文件

现在我们需要通过在不同的角度和位置上叠加正面图像来创建测试样本。为此我们使用,

opencv_createsamples -img vehicle1.jpg -bg bg.txt -info info/info1/info.lst -pngoutput info/info1 -maxxangle 0.5 -maxyangle 0.5 -maxzangle 0.5 -num 6300

参数是

img,它指定了创建样本的正像,例如vehicle1.jpgbg,它指定了背景描述文件的名称info,它指定由命令生成的正面注释文件的位置pngoutput,这是我们想要放置新生成的样本的地方maxxangle,maxyangle和maxzangle指定正图像在叠加时可以旋转的最大角度num是将要创建的样本的数量。

该命令将生成测试样本和一个名为info.lst的注释文件。注释文件指定每个测试样本中车辆的边界框坐标。

类似地,我对这5张正面图片执行了5次命令,得到了5个信息目录,info1到info5。每个目录有6300个测试样本和一个info.lst。

在这个阶段,您的文件系统应该如下所示:

生成特征矢量文件并合并它们

现在我们需要创建一个正面所有特征的矢量文件。为此我们使用,

opencv_createsamples -info info / info1 / info.lst -num 6300 -w 70 -h 70 -vec positives1.vec

参数是:

info,它是从第一个正像创建的样本的注释文件的路径num,这是样本的数量w和h指定模型尺寸vec,这是要生成的矢量文件的路径

现在,重复从其他正面图片创建的样本命令,即info2到info5。这导致创建5个矢量文件。现在,这些文件必须合并到一个单独的矢量文件中。为此,我使用这个从GitHub Python程序。最终的矢量文件是finalpositive.vec

使用opencv_traincascade实用程序进行级联训练

如果你做到了这一点,你现在终于可以开始训练级联。这是opencv_traincascade进来的地方。

opencv_traincascade -data data -vec finalpositive.vec -bg bg.txt -numPos 4000 -numNeg 6300 -numStages 16 -w 70 -h 70 -featureType LBP

参数是:

data,每个分类器文件将被存储。这个文件必须手动创建,因为它不会被命令创建vec,它指定了正向量文件的路径bg,这是后台描述文件的路径numPos,它指定每个分类器阶段在训练中使用的正样本数。numNeg,它指定每个分类器阶段在训练中使用的负样本数。numStages,它指定要训练的级联阶段的数量。随着此值的增加,准确度水平会增加。应该小心避免过度训练。

使用numPos:numNeg比率为1:2,对我来说是最好的结果。你可能得考虑数字,找出最有效的方法。基本上,如果级联在检测对象i时遇到问题,增加numPos会有所帮助。如果你的级联提供了大量的假阳性,那么大量的假阴性和增加数字将会有所帮助。

当训练在12个阶段结束后,我的接受率是0.0003。acceptanceRatio价值是一个很好的指标准确性的探测器。理想情况下,它应该在0.0001-0.0004范围内。现在,您应该在数据文件夹中将级联设置为xml文件,以便在检测算法中使用。

使用我的数据集进行训练需要13-14个小时,但不用担心,你可以同时使用你的笔记本电脑。LBP级联的好处是,训练不会像Haar那样消耗大量的RAM。但缺点是,灯光的变化会使这个分类器失败得很惨。因此,只有在应用程序环境没有剧烈变化的照明时才使用它。

标签: #opencv中的lbp算法