pc+树莓派+ opencv 分类器

基本文件

在这里插入图片描述
工具下载:https://download.csdn.net/download/weixin_42206625/12869520

在 pc 上安装 opencv

打开命令行

pip install opencv-python==4.1.2.30

这里指定安装版本

正样本

首先用手机拍几十张上百张只有需识别对象的照片,
在这里插入图片描述
运行 正样本_txt生成.py 处理正样本,同时会生 pos.txt 正样本的描述文件,在运行前先在同级目录下创建 pos 文件夹

# -*- coding: utf-8 -*-
# 斌彬电脑
# @Time : 2020/9/14 0014  17:10


"""处理正样本"""

import os
import cv2
# 原始图片路径
path = "C:aa/pos_/"
# 正样本路径
path_2 = "pos/"
# 宽度,高度
w = 20
h = 20

# pos文件中图片数量
n = 0
with open('pos' + '.txt', 'w')as f:
    for i in os.listdir(path):
        print(i)
        img = cv2.imread(path+str(i), cv2.IMREAD_GRAYSCALE)
        # 将pos文件中图片压缩为50*50
        img5050=cv2.resize(img, (w, h))
        cv2.imshow("img", img5050)
        cv2.waitKey(20)
        n += 1
        n_path = path_2 + 'pos' + str(n).rjust(3, '0') + '.jpg'
        cv2.imwrite(n_path, img5050)
        # 图片路径 txt 文件
        # f.write(n_path + ' 1 0 0 w h' '\n')
        f.write(n_path + ' 1 0 0 '+ str(w) + ' ' + str(h)+ '\n')


# 生成的 pos.txt :
'''
# 图片路径名称     检测出的样本数量如果是2个写2, 0 0是图像的坐标 50,50图片大小
C:aa/pos1/pos020.jpg 1 0 0 50 50
C:aa/pos1/pos021.jpg 1 0 0 50 50
'''

  1. path = 写自己用手机拍的正样本图片路径,
  2. path_2 = 处理后生成的正样本图片
  3. w = 正样本图片的宽度 (最好在20~120)
  4. h = 正样本图片的高度 (最好在20~120)

pos.txt 描述文件
在这里插入图片描述

负样本

可以用手机拍几十,百张拍照片作为负样本,最好在应用场景中拍,负样本中不要出现要识别的物体,张数大概是正样本的3倍,图片尺寸只要比正样本的大就行, 运行 负样本_txt生成.py 前,在同级目录惠创建 neg 文件夹,同时会生成负样本描述文件 neg.txt

# -*- coding: utf-8 -*-
# 斌彬电脑
# @Time : 2020/9/15 0015  14:22


"""处理负样本"""

import os
import cv2
# 原始图片路径
path = "C:aa/neg_/"
# 负样本路径
path_2 = "neg/"
# 宽度,高度
w = 50
h = 50


n = 0
with open('neg' + '.txt', 'a')as f:
    for i in os.listdir(path):
        print(path+str(i))
        img = cv2.imread(path+str(i), cv2.IMREAD_GRAYSCALE)
        # img5050=cv2.resize(img, (w, h))
        # cv2.imshow("img", img5050)
        # cv2.waitKey(20)
        n += 1
        n_path = path_2 + 'neg' + str(n).rjust(3, '0') + '.jpg'
        cv2.imwrite(n_path, img)
        # 图片路径 txt 文件
        f.write(n_path +'\n')
        # f.write(n_path + ' 1 0 0 ' + str(w) + ' ' + str(h) + '\n')

neg.txt
在这里插入图片描述

在 cmd 中 cd 到 opencv_createsamples.exe 所在文件夹下运行如下命令,生成训练用的 vec 文件,

opencv_createsamples.exe  -vec pos.vec  -info pos.txt  -num 22  -w 20  -h 20   

        -vec :写 vec 文件名
        -info:pos.txt 在处理正样本时生成的正样本说明文件
        -num :正样本的系数
        -w   :正样本照片的宽度 要与 正样本_txt生成.py 的 w 值一至
        -h   :正样本照片的高度 要与 正样本_txt生成.py 的 h 值一至
pause

开始训练前在同目录下创建 xml 文件夹
运行如下命令,开始训练

opencv_traincascade.exe -data xml -vec pos.vec -bg neg.txt -numPos 22 -numNeg 63 -numStages 15 -w 20 -h 20 -minHitRate 0.999 -maxFalseAlarmRate 0.2 -weightTrimRate 0.95 -featureType LBP
        -vec :写 vec 文件名
        -info:pos.txt 在处理正样本时生成的正样本说明文件
        -num :正样本的系数
        -w   :正样本照片的宽度 要与 正样本_txt生成.py 的 w 值一至
        -h   :正样本照片的高度 要与 正样本_txt生成.py 的 h 值一至
pause

完成后在 xml 中 在这里插入图片描述
就是训练好的 xmll

测试 xml 文件
# -*- coding: utf-8 -*-
# 斌彬电脑
# @Time : 2020/9/17 0017  14:54


"""测试训练好的分类器"""


import cv2


faceCascade = cv2.CascadeClassifier("cascade.xml")

cap = cv2.VideoCapture(0)
flag = 0
timeF = 10
while True:
    flag+=1
    ret, frame = cap.read()
    img = frame.copy()
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    rect = faceCascade.detectMultiScale(
        gray,
        scaleFactor=1.15,
        minNeighbors=3,
        minSize=(3,3),
        flags = cv2.IMREAD_GRAYSCALE
    )
    for (x, y, w, h) in rect:
        cv2.rectangle(frame, (x, y), (x+w, y+h), (200, 2, 0), 3)
        print(x,y,w,h)
        # 识别到物体后进行裁剪保存
        # jiequ = img[x:(x+w), y:(y+h)]
        # cv2.imwrite('c:aa/'+str(flag) + '.jpg', jiequ)  # save as jpg

    #读取到保存图片
#     if(flag%timeF==0):
#         cv2.imwrite('c:aa/'+str(flag) + '.jpg',frame) #save as jpg


    cv2.imshow('frame', frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
cap.release()
cv2.destroyAllWindows()
下面是多物体识别
# -*- coding: utf-8 -*-
# 斌彬电脑
# @Time : 2020-06-20  下午 2:51


"""opencv多物体分类器,中文显示"""


from PIL import Image, ImageDtrraw, ImageFont
import cv2
import numpy as np
import time


# 由于直接用opencv显示中文会乱码,所以先将图片格式转化为PIL库的格式,用PIL的方法写入中文,然后在转化为CV的格式
def change_cv2_draw(image, strs, local, sizes, colour):
    cv2img = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    pilimg = Image.fromarray(cv2img)
    draw = ImageDraw.Draw(pilimg)
    font = ImageFont.truetype("SIMYOU.TTF", sizes, encoding="utf-8")  # SIMYOU.TTF为字体文件
    draw.text(local, strs, colour, font=font)
    image = cv2.cvtColor(np.array(pilimg), cv2.COLOR_RGB2BGR)
    return image


# src为输入的图像
# classifier为对应识别物体的分类器
# strs为识别出的物体的中文说明
# colors表示框的颜色
# minSize为识别物体的最小尺寸,当识别的物体尺寸低于这个尺寸,则不检测,就当没识别到
# minxize为识别物体的最大尺寸,当大于该尺寸时不识别
def myClassifier(src, classifier, strs, colors, minSize, maxSize):
    gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
    # detectMultiScale()方法里面的参数在另一篇博客中有详解:https://blog.csdn.net/GottaYiWanLiu/article/details/90442274
    obj = classifier.detectMultiScale(gray, scaleFactor=1.15, minNeighbors=5, minSize=minSize, maxSize=maxSize)
    for (x, y, w, h) in obj:
        cv2.rectangle(src, (x, y), (x + w, y + w), colors, 2)  # 画框,(x,y)为识别物体的左上角顶点,(w,h)为宽和高
        src = change_cv2_draw(src, strs, (x, y - 20), 20, colors)  # 显示中文
    return src


# 读取视频文件 若 cap=cv2.VideoCapture(0),则为获取摄像头画面
# cap = cv2.VideoCapture("001.mp4")
cap = cv2.VideoCapture(0)

# 读取对应物体的训练数据,  注意,以下这些训练数据仅对本视频文件有较好的识别概率,其他场景不行
# 其他场景中,需要重新使用大量到的样本数据去训练,本程序只是一个示例教程

juzuo = cv2.CascadeClassifier("cascade.xml")  # 螺丝
# juzuo = cv2.CascadeClassifier("juzuo.xml")  # 局座人脸的训练数据
# dajin = cv2.CascadeClassifier("dajin.xml")  # 大紧人类的训练数据
# volvo = cv2.CascadeClassifier("volvo.xml")  # 沃尔沃汽车的训练数据
# volkswagen = cv2.CascadeClassifier("volkswagen.xml")  # 大众汽车的训练数据

while True:
    _, frame = cap.read()
    frame = myClassifier(frame, juzuo, "螺丝", (0, 0, 255), (40, 40), (60, 60))
    # frame = myClassifier(frame, dajin, "大紧", (0, 255, 0), (40, 40), (70, 70))
    # frame = myClassifier(frame, volvo, "沃尔沃", (255, 0, 0), (35, 35), (70, 70))
    # frame = myClassifier(frame, volkswagen, "大众", (0, 255, 255), (40, 40), (70, 70))

    cv2.imshow("frame", frame)
    cv2.waitKey(30)

简化版用在树莓派上
# -*- coding: utf-8 -*-
# 斌彬电脑
# @Time : 2020/9/20 0020  11:01

"""opencv多物体分类器,英文显示"""

import cv2

A = cv2.CascadeClassifier("cascade.xml")
B = cv2.CascadeClassifier("cascade.xml")
C = cv2.CascadeClassifier("cascade.xml")


def myClassifier(classes, gray, frame, name=None):
    rect = classes.detectMultiScale(
        gray,
        scaleFactor=1.15,
        minNeighbors=3,
        minSize=(3, 3),
        flags=cv2.IMREAD_GRAYSCALE
    )

    for (x, y, w, h) in rect:
        cv2.rectangle(frame, (x, y), (x + w, y + h), (200, 2, 0), 3)
        print(x, y, w, h)
        print('类名:', name)

    return frame


cap = cv2.VideoCapture(0)
while True:
    ret, frame = cap.read()
    img = frame.copy()
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    frame = myClassifier(A, gray, frame,'A')
    # frame = myClassifier(A, gray, frame,'B')
    # frame = myClassifier(A, gray, frame,'C')

    cv2.imshow('frame', frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weixin_42206625

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值