opencv+python识别猪

背景:在车载监控回传的视频里判断该车里是否有猪

解决思路:在回传视频里做物体识别,如果有猪就框出来并且给出一个代表值

day1 2021-10-27

设想:物体识别,并且在图中框出来猪

1.找正样本

最开始对正样本负样本blabla没有概念,所以瞎转

在csdn里搜猪的数据包,找到了一个1447图+标注文件的数据包,因为以前没做过CV类的东西,感觉牛逼,赶紧下载。

opencv+python识别猪_第1张图片

 下载后就这个样子,所有图片都是裁好的,纯度不错,并在对应的xml文件里生成了对该猪的描述

(后来发现没鸡儿用,因为我不会处理xml)

 2.找负样本

csdn搜了一堆猫狗数据,充当负样本,该数据包自带neg.txt

3.对正样本进行灰度处理,并裁减

4.安装opencv

pip install opencv_python

 5.样本裁减+灰度处理

import cv2
path =  写你的图片地址比如  "D:/train/new/pos/"
for i in range(1, 1447):  有多少图写写多大范围
    print(path+str(i)+'.jpg') 对应的图片路径
    img = cv2.imread(path+str(i)+'.jpg', cv2.IMREAD_GRAYSCALE) 
    img5050 = cv2.resize(img, (100,100))
    cv2.imshow("img",img5050)
    cv2.waitKey(20)
    cv2.imwrite('D:/train/new/pos/pos/'+str(i)+'.jpg', img5050) 给出处理好的图片存储地址

6.对正样本进行描述处理,生成一个pos.txt文件

import os
def create_pos_n_neg():
        for img in os.listdir('D:/train/test2/pos'):    图片的路径,
                line = 'pos' + '/' + img + ' 1 0 0 100 100\n' 生成对图片的描述
                print(line)
                with open('D:/train/test2/pos.txt', 'a') as f:  写入的文件
                    f.write(line)  

if __name__ == '__main__':
    create_pos_n_neg()

 7.此事文件结构应该是这样的,neg放负样本图片,pos放正样本图片,neg.txt描述负样本,pos.txt描述正样本

对应的5个opencv文件是下载来的,https://pan.baidu.com/s/14plhrufj2hQR3Es3aYqoIg

opencv+python识别猪_第2张图片

 8.用createsample生成pos.vec

打开cmd,切到存放上边这一堆的文件夹下,输入下边的命令

-vec是生产的vec的名字,-info理解为指定vec从哪来的,-num是样本数,-w -h 宽,高

opencv_createsamples.exe -vec pos.vec -info pos.txt -num 1447 -w 100 -h 100

9.出现这个小东西

opencv+python识别猪_第3张图片 

 10.用traincascade进行分类器的训练,首先创建xml文件夹

opencv+python识别猪_第4张图片

 

和上边一样,打开cmd,输入下边命令

-numPos正样本数,-numNeg负样本数,-vec正样本,-bg负样本,-data xml指生成xml文件 -w -h 宽高,如果用LBP就把模型裁成24*24 -numStages层数,可任意

opencv_traincascade.exe -data xml -vec pos.vec -bg neg.txt -numPos 1447 -numNeg 2000 -numStages 20 -w 100 -h 100 -minHitRate 0.9999 -maxFalseAlarmRate 0.5 -mode ALL

 此处记录自己踩的坑

 1.numPos没有大写P

 2.样本太大内存装不下,一训练就崩溃(解决方法,乖乖把图片裁小点比如20*20)

3.层数太多内存装不下

11.训练完成

在xml文件夹里出现这个东西就说明训练ok

12.整一段代码引用cascade来识别一下视频里的猪

from PIL import Image, ImageDraw, 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为识别物体的最小尺寸,当识别的物体尺寸低于这个尺寸,则不检测,就当没识别到
# minSize为识别物体的最大尺寸,当大于该尺寸时不识别
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("C:/train/pigtest.mp4") #这里是对应的视频文件
pig = cv2.CascadeClassifier("C:/train/pig/xml/cascade.xml")  这里是对应的cascade


while True:
    _, frame = cap.read()
    frame = myClassifier(frame, pig, "pig", (0, 0, 255), (100, 100), (800, 800))
                                    这里的pig是描述框的标题

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

13. 看看效果

opencv+python识别猪_第5张图片

rnm退钱!垃圾垃圾垃圾垃圾 

 

你可能感兴趣的:(opencv,python,计算机视觉)