在Linux环境下进行Opencv分类器的训练(基于树莓派和OpenCV的物体识别)

网上都是针对人脸识别的教程比较多,所以拥有五花百门的人脸识别分类器,因此也不必麻烦自己训练,而且识别度都挺高的。但是最近一直想在树莓派和OpenCV的环境下进行某种物体的识别,所以要训练特定的分类器,过程不难,相对繁杂,跟着走就OK,以下用苹果识别为例。

一、环境配置

如果你以前安装过OpenCV,下面一些步骤会被系统跳过,省出不少时间。

sudo apt install libopencv-dev python-opencv
sudo apt install build-essential
sudo apt install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
sudo apt-get install python-dev python-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libjasper-dev libdc1394-22-dev

创建一个文件夹:

cd
mkdir opencv_workspace

然后把opencv源码下到当前目录:

cd   opencv_workspace
git clone https://github.com/Itseez/opencv.git

至此环境配置完成。

二、收集和处理样本

需要的图像数据分为正样本和负样本,正样本是一些苹果的图片(正样本的数量看情况而定,对于复杂的图像比如人脸,正样本的数量需要很多才行,而对于简单的样本识别,正样本需要几张就够了,正样本虽然越多越好,但是收集起来就得很麻烦了)

1、收集正样本

在opencv_workspace文件夹下创建文件夹pos,将正样本放到pos下
在这里插入图片描述
将正样本图片转为灰度图,并剪成合适的尺寸,方便后续处理。创建1.py文件,放进下面代码并运行。

import cv2
for  i in range(1,6):#批量处理照片
	img = cv2.imread('pos/'+str(i)+'.jpg',cv2.IMREAD_GRAYSCALE)#读入照片,并转灰度
	img1 = cv2.resize(img,(50,50))#调整大小
	cv2.imwrite('pos/'+str(i)+'.jpg',img1)#保存图片
print('批量转灰度成功!')

效果如下:
在这里插入图片描述

2、收集负样本

关于负样本,只要不含有正样本图片即可,最好是识别场景的图片。给大家一个负样本下载 链接: https://pan.baidu.com/s/1TgyAuhuggktrZuWBFonUwQ提取码:j5q2,下载后如图,2000多张,已处理好灰度。
在这里插入图片描述
将负样本文件夹neg放到opencv_workspace文件夹下即可。

3、正负样本描述文件生成

生成正样本描述文件,建立2.py文件,把下面代码拷贝进去

import os
def create_pos_n_neg():
    for file_type in ['pos']: #此处修改pos或neg即可生成正负样本的描述文件,pos是生成正样本描述文件info.txt
        for img in os.listdir(file_type):
            if (file_type == 'neg'):
            	line = file_type + '/' + img + '\n'
                with open('bg.txt', 'a') as f:
                    f.write(line)
            elif (file_type == 'pos'):
                line = file_type + '/' + img + ' 1 0 0 50 50\n'
                with open('info.txt', 'a') as f:
                    f.write(line)

if __name__ == '__main__':
    create_pos_n_neg()
    print('正样本描述文件info.txt已生成')

在这里插入图片描述
生成负样本描述文件,建立3.py文件,把下面代码拷贝进去

import os
def create_pos_n_neg():
    for file_type in ['neg']: #此处修改pos或neg即可生成正负样本的描述文件,neg是生成正样本描述文件bg.txt
        for img in os.listdir(file_type):
            if (file_type == 'neg'):
            	line = file_type + '/' + img + '\n'
                with open('bg.txt', 'a') as f:
                    f.write(line)
            elif (file_type == 'pos'):
                line = file_type + '/' + img + ' 1 0 0 50 50\n'
                with open('info.txt', 'a') as f:
                    f.write(line)

if __name__ == '__main__':
    create_pos_n_neg()
    print('正样本描述文件bg.txt已生成')

在这里插入图片描述

三、训练分类器

生成positives.vec文件。在当前目录打开控制台程序,输入

opencv_createsamples -info info.txt -num 50 -w 50 -h 50 -vec positives.vec

其中,-info字段填写正样本描述文件;-num制定正样本的数目;-w和-h分别指定正样本的宽和高(-w和-h越大,训练耗时越大);-vec用于保存制作的正样本。

mkdir data #用于存储Cascade分类器数据

训练分类器

opencv_traincascade -data data -vec positives.vec -bg bg.txt -numPos 4 -numNeg 10 -numStages 16 -w 50 -h 50

字段说明如下:
-data data:训练后data目录下会存储训练过程中生成的文件
-vec positives.vec:Pos.vec是通过opencv_createsamples生成的vec文件
-bg bg.txt:bg.txt是负样本文件的数据
-numPos :正样本的数目,这个数值一定要比准备正样本时的数目少,不然会报can not get new positive sample.
-numNeg :负样本数目,数值可以比负样本大
-numStages :训练分类器的级数
-w 50:必须与opencv_createsample中使用的-w值一致
-h 50:必须与opencv_createsample中使用的-h值一致
注:-w和-h的大小对训练时间的影响非常大

注意:树莓派内存较小,numPos和numNeg的数值太大会被系统终止训练,因此适当取numPos和numNeg的数值,错误如下:
在这里插入图片描述
训练成功则如下:
在这里插入图片描述
进入data文件夹下,就可以看到生成训练出来的xml文件cascade.xml。

四、使用生成的xml文件进行识别

将需要识别的照片(命名为test.jpg)放到在opencv_createsamples文件夹下,并在opencv_createsamples文件夹下创建4.py文件,拷贝以下代码进去

import cv2

watch_cascade = cv2.CascadeClassifier('/home/pi/opencv_createsamples/data/cascade.xml')#分类器路径

img = cv2.imread('test.jpg')#需要识别的照片,放到opencv_createsamples文件夹下

gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

watches = watch_cascade.detectMultiScale(gray)

for (x,y,w,h) in watches:
    cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)#建立方框,(0,255,0)表示绿色

    roi_gray = gray[y:y+h,x:x+w]
    roi_color = img[y:y+h,x:x+w]

cv2.imshow('识别窗口',img)
k = cv2.waitKey(0)

运行即可,如果识别的图片太大,运行下面程序调整一下

import cv2
img = cv2.imread('test.jpg')#读入照片
img1 = cv2.resize(img,(300,300))#调整大小
cv2.imwrite('test.jpg',img1)#保存图片
print('调整成功!')

识别效果如下:
在这里插入图片描述

由于树莓派内存太小,训练的分类器精度还是有待提高。
有问题的下方留言,谢谢!
参考:
链接: https://www.freesion.com/article/79671247590/.
链接: https://blog.csdn.net/qq_16309049/article/details/73039567.

  • 12
    点赞
  • 144
    收藏
    觉得还不错? 一键收藏
  • 16
    评论
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值