您现在的位置是:网站首页> PY&Rust

OpenCV知识收集

  • PY&Rust
  • 2022-06-11
  • 1072人已阅读
摘要

OpenCV介绍

OpenCV双目摄像头

如何使用OpenCV RTMP直播推流

车牌识别的例子

opencv 入侵检测代码

OpenCV的高压线异物入侵检测系统

OpenCV人脸检测和识别

使用OpenCV自带的预训练模型YOLOv3调用摄像头进行目标检测

利用OpenCV自带的预训练模型实现人脸识别

OpenCV4机器学习算法原理与编程实战

OpenCV目录中data文件夹中的XML文件详细介绍

opencv训练自己的模型,实现特定物体的识别

Python-opencv实现目标检测定位:判断固定颜色物体是否在规定区域内


OpenCV介绍

查看原文

OpenCV应用场景
OpenCV 可以应用但不仅限于以下场景:二维和三维特征提取、街景图像拼接、人脸识别系统、手势识别、人机交互、动作识别、物体识别、自动检查和监视、分割与识别、医学图像分析、运动跟踪、增强现实、视频/图像搜索与检索、机器人与无人驾驶汽车导航与控制、驾驶员疲劳驾驶检测等。

对于 Linux 和 Windows 操作系统,首需要在 shell 或 cmd 中运行以下命令安装 NumPy:

pip install numpy

然后再安装 OpenCV,可以选择两种不同版本:

仅安装主模块包

pip install opencv-python

安装完整包(包括主模块和附加模块)


pip install opencv-contrib-python

下表整理介绍了各主要模块的作用

1.png

2.png


图像处理流程 

完整的图像处理程序通常可以分为以下三个步骤:


读取图像,图像的获取可以有多种不同的来源(相机、视频流、磁盘、在线资源),因此图像的读取可能涉及多个函数,以便可以从不同的来源读取图像;

图像处理,通过应用图像处理技术来处理图像,以实现所需的功能(例如,检测图像中的猫);

显示结果,将图像处理完成后的结果以人类可读的方式进行呈现(例如,在图像中绘制边界框,有时也可能需要将其保存到磁盘)。

此外,上述第2步图像处理可以进一步分为三个不同的处理级别:


低层处理(或者在不引起歧义的情况下可以称为预处理),通常将一个图像作为输入,然后输出另一个图像。可在此步骤中应用的步骤包括但不限于以下方法:噪声消除、图像锐化、光照归一化以及透视校正等; 中层处理:是将预处理后的图像提取其主要特征(例如采用 DNN 模型得到的图像特征),输出某种形式的图像表示,它提取了用于图像进一步处理的主要特征。 


高层处理:接受中层处理得到的图像特征并输出最终结果。例如,处理的输出可以是检测到的人脸.

像素、颜色、通道、图像和颜色空间 在表示图像时,有多种不同的颜色模型,但最常见的是红、绿、蓝 (RGB) 模型。 RGB 模型是一种加法颜色模型,其中原色 (在RGB模型中,原色是红色 R、绿色 G 和蓝色 B) 混合在一起就可以用来表示广泛的颜色范围。 每个原色 (R, G, B) 通常表示一个通道,其取值范围为[0, 255]内的整数值。因此,每个通道有共256个可能的离散值,其对应于用于表示颜色通道值的总比特数 ( 2 8 = 256 2^8=256 2 8 =256)。此外,由于有三个不同的通道,使用 RGB 模型表示的图像称为24位色深图像: 


当你使用Python编程语言时,可以使用OpenCV库来获取摄像头视频并显示。下面是一个基本示例代码

获得直播流cap = cv2.VideoCapture('rtmp://your_streaming_url')


import cv2


# 打开摄像头

cap = cv2.VideoCapture(0)


while True:

    # 读取视频帧

    ret, frame = cap.read()


    # 显示视频帧

    cv2.imshow('Video', frame)


    # 按下 'q' 键退出循环

    if cv2.waitKey(1) & 0xFF == ord('q'):

        break


# 释放摄像头资源

cap.release()


# 关闭窗口

cv2.destroyAllWindows()

上述代码首先导入了cv2模块,然后通过cv2.VideoCapture(0)打开摄像头。这里的参数0表示使用默认的摄像头设备,如果你有多个摄像头,可以尝试使用不同的参数来指定摄像头索引。


接下来,通过一个无限循环不断读取视频帧,并使用cv2.imshow('Video', frame)显示每一帧。cv2.imshow函数的第一个参数是窗口的名称,可以自定义。cv2.waitKey(1)等待用户按下键盘上的某个键,返回按键的ASCII码。如果按下的键是字母'q',则通过break语句退出循环。


最后,使用cap.release()释放摄像头资源,然后通过cv2.destroyAllWindows()关闭显示窗口。


运行这段代码后,你将能够获取摄像头的视频并在一个窗口中显示出来。按下键盘上的'q'键即可退出程序。


请注意,为了运行上述代码,你需要先安装OpenCV库。你可以使用以下命令通过pip安装OpenCV:

pip install opencv-python


要获取直播地址视频并使用OpenCV显示,你可以使用cv2.VideoCapture来打开视频流。下面是一个示例代码


import cv2


# 直播地址

live_stream_url = "your_live_stream_url_here"


# 打开视频流

cap = cv2.VideoCapture(live_stream_url)


while True:

    # 读取视频帧

    ret, frame = cap.read()


    # 如果视频帧读取失败,可能是直播已结束或出现其他问题,可以添加相应的错误处理逻辑

    if not ret:

        print("Failed to read frame")

        break


    # 显示视频帧

    cv2.imshow('Live Stream', frame)


    # 按下 'q' 键退出循环

    if cv2.waitKey(1) & 0xFF == ord('q'):

        break


# 释放视频流资源

cap.release()


# 关闭窗口

cv2.destroyAllWindows()


要打开抖音的直播地址并使用OpenCV显示,你可以使用cv2.VideoCapture来打开视频流。然而,需要注意的是,抖音的直播地址通常是加密的,并且需要通过抖音的API来获取有效的直播地址。以下是一个示例代码,演示如何获取抖音直播地址并使用OpenCV显示

import cv2

import requests


# 抖音直播地址

live_stream_url = "your_douyin_live_stream_url_here"


# 抖音接口请求头信息

headers = {

    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36",

    "Referer": "https://www.douyin.com/",

    # 添加其他必要的请求头信息,如Cookie等

}


# 发送请求获取直播地址

response = requests.get(live_stream_url, headers=headers)

data = response.json()


# 获取有效的直播地址

live_url = data["data"]["live_hls_url"]


# 打开视频流

cap = cv2.VideoCapture(live_url)


while True:

    # 读取视频帧

    ret, frame = cap.read()


    # 如果视频帧读取失败,可能是直播已结束或出现其他问题,可以添加相应的错误处理逻辑

    if not ret:

        print("Failed to read frame")

        break


    # 显示视频帧

    cv2.imshow('Douyin Live Stream', frame)


    # 按下 'q' 键退出循环

    if cv2.waitKey(1) & 0xFF == ord('q'):

        break


# 释放视频流资源

cap.release()


# 关闭窗口

cv2.destroyAllWindows()

在上述代码中,你需要将live_stream_url替换为你要观看的抖音直播地址。然后使用requests库发送GET请求获取直播地址的JSON响应。根据抖音API的响应结构,你可能需要根据实际情况进行相应的数据提取和处理。最终,将有效的直播地址赋值给live_url变量。


然后使用cv2.VideoCapture打开该直播地址,将其传递给cap变量。


接下来,使用一个无限循环来读取视频帧,并使用cv2.imshow显示每一帧。如果视频帧读取失败,可能是直播已结束或出现其他问题,你可以根据需要添加相应的错误处理逻辑。


最后,通过按下'q'键退出循环,释放视频流资源并关闭显示窗口。


请注意,抖音的直播地址可能会随时间变化而失效,因此你可能需要根据需要更新直播地址,并在代码中进行相应的处理。


OpenCV双目摄像头

import cv2

 

# 创建两个VideoCapture对象来分别获取左右摄像头图像

left_camera = cv2.VideoCapture(0) # 第一个参数为设备索引号或者文件路径

right_camera = cv2.VideoCapture(1)

 

while True:

    ret_l, left_frame = left_camera.read() # 从左摄像头中读取图像

    ret_r, right_frame = right_camera.read() # 从右摄像头中读取图像

    

    if not (ret_l and ret_r):

        break

        

    # 在这里可以添加其他图像处理操作,如立体校正、特征点提取等

    

    cv2.imshow('Left Camera', left_frame) # 显示左摄像头图像

    cv2.imshow('Right Camera', right_frame) # 显示右摄像头图像

    

    key = cv2.waitKey(1) & 0xFF

    if key == ord('q'):

        break

 

left_camera.release()

right_camera.release()

cv2.destroyAllWindows()


如何使用OpenCV RTMP直播推流

# 需先自行安装FFmpeg,并添加环境变量

import cv2

import subprocess

 

# FFmpeg官方文档:http://ffmpeg.org/ffmpeg.html


# RTMP服务器地址

rtmp_server = r'rtmp://live-push.bilivideo.com/live-bvc/'

# RTMP推流码

rtmp_key = '?streamname=live_xxx'

# 读取视频并获取属性,摄像头就写0,视频文件就写文件名

cap = cv2.VideoCapture(0)

size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))

sizeStr = str(size[0]) + 'x' + str(size[1])

command = ['ffmpeg',

    '-y', '-an',            # 无需询问即可覆盖输出文件

    '-f', 'rawvideo',       # 强制输入或输出文件格式

    '-vcodec','rawvideo',   # 设置视频编解码器。这是-codec:v的别名

    '-pix_fmt', 'bgr24',    # 设置像素格式

    '-s', sizeStr,          # 设置图像大小

    '-r', '25',             # 设置帧率

    '-i', '-',              # 输入

    '-c:v', 'libx264',      # 编解码器

    '-pix_fmt', 'yuv420p',  # 像素格式

    '-preset', 'ultrafast', # 调节编码速度和质量的平衡

    '-f', 'flv',            # 强制输入或输出文件格式

    '-tune', 'zerolatency', # 视频类型和视觉优化

    rtmp_server+rtmp_key]

pipe = subprocess.Popen(command, shell=False, stdin=subprocess.PIPE)


# 用来实现循环播放

frame_counter = 0


while cap.isOpened():

    success, frame = cap.read()

    # 如果帧尾,就重新开始;

    # 如果不需要循环播放,就把这部分删掉。

    frame_counter += 1

    if frame_counter == int(cap.get(cv2.CAP_PROP_FRAME_COUNT)):

        frame_counter = 0

        cap.set(cv2.CAP_PROP_POS_FRAMES, 0)


    if success:

        if cv2.waitKey(1) & 0xFF == ord('q'):

            break

        pipe.stdin.write(frame.tostring())

cap.release()

pipe.terminate()






车牌识别的例子

车牌区域检测是车牌识别中的关键步骤之一。下面是一个补全车牌区域检测代码的示例,使用基于颜色过滤和轮廓检测的方法:


import cv2

import pytesseract


# 配置Tesseract OCR

pytesseract.pytesseract.tesseract_cmd = r"path_to_tesseract_executable"


# 读取图像

image = cv2.imread("your_image.jpg")


# 对图像进行预处理

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

blur = cv2.GaussianBlur(gray, (5, 5), 0)


# 进行颜色过滤,提取车牌的颜色特征

lower = (0, 0, 0)  # 车牌颜色的下限(根据实际情况调整)

upper = (255, 255, 255)  # 车牌颜色的上限(根据实际情况调整)

mask = cv2.inRange(blur, lower, upper)


# 进行形态学操作,进一步处理图像

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))

dilated = cv2.dilate(mask, kernel, iterations=3)

eroded = cv2.erode(dilated, kernel, iterations=2)


# 进行轮廓检测

contours, _ = cv2.findContours(eroded, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)


# 对每个轮廓进行处理和筛选

for contour in contours:

    # 计算轮廓的面积

    area = cv2.contourArea(contour)


    # 根据面积进行筛选,以排除过小或过大的轮廓

    if area > min_area_threshold and area < max_area_threshold:

        # 获取轮廓的边界框

        x, y, w, h = cv2.boundingRect(contour)


        # 裁剪出车牌区域

        plate_image = gray[y:y+h, x:x+w]


        # 使用Tesseract OCR识别车牌号

        plate_number = pytesseract.image_to_string(plate_image,, config='--psm 7')


        # 打印车牌号及位置信息

        print("车牌号:", plate_number)

        print("位置信息:", (x, y, x+w, y+h))  # 坐标形式可以根据需要进行调整


在上述代码中,你需要根据实际情况调整车牌颜色的下限和上限,以及面积阈值(即min_area_threshold和max_area_threshold),以确保能够准确地检测到车牌区域。你可以根据车牌样式和光照条件进行调整。



opencv 入侵检测代码

以下是使用OpenCV进行入侵检测的示例代码:

import cv2

 

# 加载训练好的人体分类器模型(Haar Cascade)

body_cascade = cv2.CascadeClassifier('haarcascade_fullbody.xml')

 

# 打开视频文件或者连接到网络摄像头

cap = cv2.VideoCapture(0)

 

while True:

    # 从视频中获取每一帧图像

    ret, frame = cap.read()

    

    if not ret:

        break

        

    # 将当前帧转换为灰度图像

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

    

    # 在灰度图像上运行人体分类器来检测人体

    bodies = body_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))

    

    for (x, y, w, h) in bodies:

        # 标记被检测到的人体区域并显示红色边界框

        cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 0, 255), 2)

    

    # 展示结果图像

    cv2.imshow("Intrusion Detection", frame)

    

    # 按下 'q' 键退出循环

    if cv2.waitKey(1) & 0xFF == ord('q'):

        break

 

# 关闭所有窗口及释放相机对象

cap.release()

cv2.destroyAllWindows()


这段代码首先通过cv2.CascadeClassifier()函数加载了一个已经训练好的人体分类器模型。然后,利用cv2.VideoCapture()函数可以选择要处理的视频文件或者连接到本地摄像头。之后,程序会不断地从视频流中提取每一帧图像,并将其转换成灰度图像。最后,调用人体分类器模型的detectMultiScale()函数来检测图像中的人体,如果存在人体则在原始图像上画出红色边界框。


OpenCV的高压线异物入侵检测系统

点击查看原文

1.算法流程图

1.png



2.混合高斯模型背景提取

该博客采用混合高斯模型(MOG)作为背景的统计模型,对每个高斯分布的参数不断进行更新以适应背景的逐渐变化;该方法对于非完全静止的时变背景有较好的适应能力;但MOG的缺点在于,当图像边缘纹理、颜色变化很明显的情况下,识别前景对象仍不是很准确 l; 本研究采用改进的混合高斯模型,在一定边框范围内,利用像素局部邻域之间的相关性,采用每一个像素点及其邻域组成的集合作为特征矢量来描述图像。为了更加充分地利用边缘空间背景,本研究扩大图像背景分割建模,以从重复变化的背景中提取出活动目标。


图像的混合高斯分布表示

利用像素邻域之间的相关性,采用每一个像素点及其邻域组成的集合作为特征矢量来描述图像。例如,对像素x55 采用其5×5邻域像素构成特征向量,即x55(x11,… x15,x21,…,x25, x31,… x35, x41,… x45 x51,… x55)T。 为使白天、黑夜获得同样的识别效果,本系统使用灰度图像序列。

1.png



3.基于像素亮度的特征

为了解决像素的亮度随着光照的变化而改变,引入Markov模型。像素亮度特征是背景建模中常用的一个特征。在一个完全静止的场景中,一个像素在一段时间内的亮度变化服从高斯分布N( u , o )。如果场景变化缓慢,那么只要用基本的高斯模型就可以适应这种变化。在模型需要更新时,可以使用各种滤波器来实现。 在现实中,完全静止的场景是不存在的。严格地说,在每一种情况下,像素都会呈现出不同的亮度值,具有不同的分布。因此,只用单个的高斯分布来模拟像素亮度的概率密度函数是不充分的。使用混合高斯分布(MOG)是建模时一种比较好的方法。 把每个像素在一段时间内的值作为一个“像素过程”,场景中每个像素最近观察值的分布用一个混合高斯分布来表示。每个新的像素值可以由混合模型的主要组成之一来表示。这种方法通过缓慢改变高斯分布值来处理光照的渐变问题,同时还可以处理阴影、摄像头抖动问题,可有效地实现图像监控系统活动对象识别功能。再加上利用像素亮度的亮度特征,通过非参数核密度估计对背景建模。其模型保留图像中每个像素亮度值的样本,然后用这个样本来估计像素亮度分布的密度函数。这个模型可以估计任何新观察像素值的概率,达到处理背景比较凌乱、背景与前景同色的问题,同时减少由于摄像头的抖动而引起的误识。


基于块的特征

背景建模的过程也用到基于块特征的方法。 在背景学习的过程中用每一个块的中值模板和块标准偏移来代替第一块。在每一个新帧,每一块与它的模板对应。如果某块相对于标准偏移量的偏移程度很大,就认为它是前景区域。


背景建模的保持

背景建模的保持是背景算法的一个难点。该博客综合考虑以下的一些问题: ①背景对象可以移动,这种情况可能会被检测为前景;自然光照的渐亮变化; ③光照的突变,例如闪电等天气的突然变化; ④摆动的树枝和草叶,这种情况使背景像素值频繁改变,且像素值之间的关系不是很清晰; ⑤云彩或塔身投入的阴影;⑥活动对象停在场景中; 背景模型的保持拟从多种空间尺度来处理,例如结合图像像素、区域、帧的特征,从像素级、区域级、帧级综合进行运算,是自上而下的阶梯式处理方法。 像素级只用到孤立像素点的信息,将前景和背景进行第一次分离。像素级能处理一些问题,例如可动背景、光照的渐变和摆动树枝等。


4.代码实现

import numpy as np

import cv2

import time

import datetime


colour=((0, 205, 205),(154, 250, 0),(34,34,178),(211, 0, 148),(255, 118, 72),(137, 137, 139))#定义矩形颜色


cap = cv2.VideoCapture("vtest.avi") #参数为0是打开摄像头,文件名是打开视频


fgbg = cv2.createBackgroundSubtractorMOG2()#混合高斯背景建模算法


fourcc = cv2.VideoWriter_fourcc(*'XVID')#设置保存图片格式

out = cv2.VideoWriter(datetime.datetime.now().strftime("%A_%d_%B_%Y_%I_%M_%S%p")+'.avi',fourcc, 10.0, (768,576))#分辨率要和原视频对应



while True:

    ret, frame = cap.read()  #读取图片

    fgmask = fgbg.apply(frame)


    element = cv2.getStructuringElement(cv2.MORPH_CROSS, (3, 3))  # 形态学去噪

    fgmask = cv2.morphologyEx(fgmask, cv2.MORPH_OPEN, element)  # 开运算去噪


    _ ,contours, hierarchy = cv2.findContours(fgmask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) #寻找前景


    count=0

    for cont in contours:

        Area = cv2.contourArea(cont)  # 计算轮廓面积

        if Area < 300:  # 过滤面积小于10的形状

            continue


        count += 1  # 计数加一


        print("{}-prospect:{}".format(count,Area),end="  ") #打印出每个前景的面积


        rect = cv2.boundingRect(cont) #提取矩形坐标


        print("x:{} y:{}".format(rect[0],rect[1]))#打印坐标


        cv2.rectangle(frame,(rect[0],rect[1]),(rect[0]+rect[2],rect[1]+rect[3]),colour[count%6],1)#原图上绘制矩形

        cv2.rectangle(fgmask,(rect[0],rect[1]),(rect[0]+rect[2],rect[1]+rect[3]),(0xff, 0xff, 0xff), 1)  #黑白前景上绘制矩形


        y = 10 if rect[1] < 10 else rect[1]  # 防止编号到图片之外

        cv2.putText(frame, str(count), (rect[0], y), cv2.FONT_HERSHEY_COMPLEX, 0.4, (0, 255, 0), 1)  # 在前景上写上编号




    cv2.putText(frame, "count:", (5, 20), cv2.FONT_HERSHEY_COMPLEX, 0.6, (0, 255, 0), 1) #显示总数

    cv2.putText(frame, str(count), (75, 20), cv2.FONT_HERSHEY_COMPLEX, 0.6, (0, 255, 0), 1)

    print("----------------------------")


    cv2.imshow('frame', frame)#在原图上标注

    cv2.imshow('frame2', fgmask)  # 以黑白的形式显示前景和背景

    out.write(frame)

    k = cv2.waitKey(30)&0xff  #按esc退出

    if k == 27:

        break



out.release()#释放文件

cap.release()

cv2.destoryAllWindows()#关闭所有窗口



OpenCV人脸检测和识别

点击查看原文



使用OpenCV自带的预训练模型YOLOv3调用摄像头进行目标检测

点击查看原文



利用OpenCV自带的预训练模型实现人脸识别

点击查看原文

# -*- coding: utf-8 -*-

# @Time : 2023/10/24 14:35

# @Author :Muzi

# @File : 人脸检测.py

# @Software: PyCharm

import cv2

 

image = cv2.imread('people.jpg')

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

#--加载分类器---

faceCascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

 

faces = faceCascade.detectMultiScale(gray,scaleFactor = 1.01,minNeighbors =30,minSize = (20,20))

 

print("发现{0}张人脸!".format(len(faces)))

print("其位置分别是:",faces)

# 遍历检测到的人脸,并绘制外接矩形

for (x, y, w, h) in faces:

    cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)  # 绘制矩形

 

# 显示结果图像

cv2.imshow('Result', image)

cv2.waitKey(0)

cv2.destroyAllWindows()


其他模型作用:(预训练模型在opencv安装后opencv\sources\data下

 1、haarcascade_frontalface_default.xml:用于检测图像中的人脸。


2、haarcascade_eye.xml:用于检测图像中的眼睛。


3、haarcascade_smile.xml:用于检测笑容。


4、haarcascade_upperbody.xml: 用于检测图像中的上半身部分,包括头和肩膀。


5、haarcascade_fullbody.xml:用于检测整个身体。


6、lbpcascade_frontalface.xml:也用于检测人脸,采用了不同的级联分类器(Local Binary Pattern)。


7、haarcascade_eye_tree_eyeglasses.xml:用于检测带眼镜的眼睛。


8、haarcascade_frontalcatface.xml:用于检测猫的脸部。


9、haarcascade_frontalcatface_extended.xml:用于识别猫的面部特征,包括猫的眼睛、鼻子和嘴巴等。


10、haarcascade_frontalface_alt.xml:用于检测图像中的人脸。


11、haarcascade_frontalface_alt2.xml:用于检测图像中的人脸。


12、haarcascade_frontalface_alt_tree.xml:用于识别人的面部特征,包括人的眼睛、鼻子和嘴巴等。


13、haarcascade_lefteye_2splits.xml:用于检测图像或视频流中的左眼。


14、haarcascade_licence_plate_rus_16stages.xml:用于检测图像或视频帧中的车牌,特别是俄罗斯车牌。


15、haarcascade_lowerbody.xml:可以识别与下半身相关的模式和特征,通常包括腹部和臀部区域。


16、haarcascade_profileface.xml:用于检测图像或视频流中的配置文件人脸。


17、haarcascade_righteye_2splits.xml:检测图像或视频流中的右眼。


18、haarcascade_russian_plate_number.xml:用于检测俄罗斯车牌。



OpenCV4机器学习算法原理与编程实战

点击查看原文



OpenCV目录中data文件夹中的XML文件详细介绍

一、引言

在OpenCV(Open Source Computer Vision Library)的目录中的data文件夹中,通常包含了一些预训练的XML文件,这些文件用于不同的计算机视觉任务,如面部检测、对象识别、人眼检测等。这些XML文件包含了模型的训练数据和配置信息,可以被用于加载训练好的机器学习模型,以便在你的应用程序中执行各种计算机视觉任务。


二、介绍

1、haarcascade_frontalface_default.xml:用于检测图像中的人脸。


2、haarcascade_eye.xml:用于检测图像中的眼睛。


3、haarcascade_smile.xml:用于检测笑容。


4、haarcascade_upperbody.xml: 用于检测图像中的上半身部分,包括头和肩膀。


5、haarcascade_fullbody.xml:用于检测整个身体。


6、lbpcascade_frontalface.xml:也用于检测人脸,采用了不同的级联分类器(Local Binary Pattern)。


7、haarcascade_eye_tree_eyeglasses.xml:用于检测带眼镜的眼睛。


8、haarcascade_frontalcatface.xml:用于检测猫的脸部。


9、haarcascade_frontalcatface_extended.xml:用于识别猫的面部特征,包括猫的眼睛、鼻子和嘴巴等。


10、haarcascade_frontalface_alt.xml:用于检测图像中的人脸。


11、haarcascade_frontalface_alt2.xml:用于检测图像中的人脸。


12、haarcascade_frontalface_alt_tree.xml:用于识别人的面部特征,包括人的眼睛、鼻子和嘴巴等。


13、haarcascade_lefteye_2splits.xml:用于检测图像或视频流中的左眼。


14、haarcascade_licence_plate_rus_16stages.xml:用于检测图像或视频帧中的车牌,特别是俄罗斯车牌。


15、haarcascade_lowerbody.xml:可以识别与下半身相关的模式和特征,通常包括腹部和臀部区域。


16、haarcascade_profileface.xml:用于检测图像或视频流中的配置文件人脸。


17、haarcascade_righteye_2splits.xml:检测图像或视频流中的右眼。


18、haarcascade_russian_plate_number.xml:用于检测俄罗斯车牌。


三、代码实现(举例:检测猫的脸部) 

objects = cv2.CascadeClassifier.detectMultiScale( image[,scaleFactor

                     [,minNeighbors[, flags[, minSize[,maxSize]]]]] )

其中,各个参数及返回值的含义如下。

·image:待检测图像,通常为灰度图像。

·scaleFactor:表示在前后两次相继扫描中搜索窗口的缩放比例。识别,扫描,按照不同比例来进行扫描

·minNeighbors:表示构成检测目标的相邻矩形的最小个数。在默认情况下,该参数的值为 3,

      表示有 3 个以上的检测标记存在时才认为存在猫脸。如果希望提高检测的准确率可以将该参数的值设置得更大,

      但这样做可能会让一些猫脸无法被检测到。

flags: 该参数通常被省略。在使用低版本 OpenCV (OpenCV 1.X 版本)时,该参数可能会被设置为

CV_HAAR_DO_CANNY_PRUNING,表示使用 Canny 边缘检测器拒绝一些区域。

·minSize: 目标的最小尺寸,小于这个尺寸的目标将被忽略。

·maxSize: 目标的最大尺寸,大于这个尺寸的目标将被忽略。通常情况下,将该可选参数省略即可。

          若 maxSize 和 minSize 大小一致,则表示仅在一个尺度上查找目标。

·objects: 返回值,目标对象的矩形框向量组。该值是一组矩形信息,

      包含每个检测到的猫脸对应的矩形框的信息 (x轴方向位置、y轴方向位置、宽度、高度)。


import cv2 #导入所需要的库

 

#将图片读取为灰度图片

image = cv2.imread('cat(1).jpg') 

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

 

# 创建包含分类器参数的经过训练的 XML 文件的实例并加载该文件。

faceCascade = cv2.CascadeClassifier('haarcascade_frontalcatface.xml')

 

# 执行人脸检测

faces = faceCascade.detectMultiScale(gray, scaleFactor=1.02, minNeighbors=20, minSize=(8, 8))

 

在检测到的人脸周围绘制矩形

for i, (x, y, w, h) in enumerate(faces):

    rect = cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 3)

cv2.imshow("rect", rect)

cv2.waitKey(0)

 代码运行结果:

1.png



四、总结

这些XML文件包含了用于检测特定目标的级联分类器的信息。你可以使用OpenCV库中的类来加载这些XML文件并将它们应用于图像。这允许你在图像中识别人脸、眼睛、笑容等。 



opencv训练自己的模型,实现特定物体的识别

点击查看原文

程序准备

训练自己的分类器文件,需要用到两个程序 : opencv_createsamples.exe和opencv_traincascade.exe

opencv最新的安装包中没有这两个程序,我们可以下载 3.4.14这个版本的安装包进行安装。

opencv安装包 : opencv-3.4.14-vc14_vc15.exe

安装完成后,在这个目录下就会有这两个程序文件 opencv\build\x64\vc15\bin


样本数据准备

正样本数据 : 也就是我们需要检测的物体图片,可以自己用手机拍摄下你要检测的物体的图片,多拍摄一些不同角度的图片。

我的正样本数据在这个目录下 image\positive\img,大概有50多张图片

1.png

然后在image\positive目录下新建一个info.dat文件,在其中记录正样本图片信息

1.png

参数介绍


img/1.jpg : 文件路径和文件名

1:表示图片中有几个目标物体,一般一个就行了

0,0:目标物体起始坐标

1280,1706:目标物体大小



负样本数据:不包含我们要检测物体的图片,可以拍摄一些风景之类的图片,尽量多一些。

我的负样本数据在这个目录下 image\negitive\img

1.png

然后在image\negitive目录下新建一个bg.txt文件,在其中记录负样本图片信息

负样本图片信息我们只需记录路径和文件名就行了,但是这里要注意,路径名要写绝对路径,后面会说为什么

1.png


正样本VEC文件创建

训练样本之前先要生成vec文件,要用到opencv_createsamples.exe程序

opencv_createsamples.exe部分参数介绍

  [-info <collection_file_name>]  # 记录样本数据的文件(就是我们刚才创建的info.data文件)

  [-img <image_file_name>]    

  [-vec <vec_file_name>]   # 输出文件,内含用于训练的正样本。 

  [-bg <background_file_name>]  # 背景图像的描述文件

  [-num <number_of_samples = 1000>]   #样本数量(默认为1000)

  [-bgcolor <background_color = 0>]    #指定背景颜色

  [-w <sample_width = 24>]#输出样本的宽度(以像素为单位)

  [-h <sample_height = 24>]#输出样本的高度(以像素为单位)


在安装包的这个目录下opencv\build\x64\vc15\bin可以找到opencv_createsamples.exe程序,我们生成下vec文件

D:\opencv3.4.12\opencv\build\x64\vc15\bin\opencv_createsamples.exe -info C:\Users\lng\Desktop\image\positive\info.dat -vec C:\Users\lng\Desktop\image\sample.vec -num 58 -bgcolor 0 -bgthresh 0 -w 24 -h 24


在image目录下就生成了vec文件

1.png


样本数据训练

完成上面的准备工作,就可以开始训练样本。训练样本需要用到opencv_traincascaded.exe程序

opencv_traincascaded.exe程序部分参数介绍

 -data <cascade_dir_name>     #目录名,如不存在训练程序会创建它,用于存放训练好的分类器

 -vec <vec_file_name>              #包含正样本的vec文件名

 -bg <background_file_name>   #背景描述文件

 [-numPos <number_of_positive_samples = 2000>]   #每级分类器训练时所用的正样本数目

 [-numNeg <number_of_negative_samples = 1000>]   #每级分类器训练时所用的负样本数目

 [-numStages <number_of_stages = 20>]   #训练的分类器的级数

--cascadeParams--

 [-featureType <{HAAR(default), LBP, HOG}>]  # 特征的类型: HAAR - 类Haar特征; LBP - 局部纹理模式特征

 [-w <sampleWidth = 24>] #训练样本的尺寸(单位为像素)

 [-h <sampleHeight = 24>] #训练样本的尺寸(单位为像素)

--boostParams--

 [-minHitRate <min_hit_rate> = 0.995>] #分类器的每一级希望得到的最小检测率

 [-maxFalseAlarmRate <max_false_alarm_rate = 0.5>] #分类器的每一级希望得到的最大误检率


在安装包的这个目录下opencv\build\x64\vc15\bin可以找到opencv_traincascade.exe程序,开始训练样本

这里注意下

指定-bg参数时,文件名前不能加路径,所以需要把刚才在image\negitive下创建的bg.txt文件拷贝到opencv_traincascade.exe程序所在目录下,所以要在bg.txt写负样本图片的绝对路径。

指定numPos参数时,因为每个阶段训练时有些正样本可能会被识别为负样本,故每个训练阶段后都会消耗一定的正样本。因此,此处使用的正样本数量绝对不能等于或超过positive文件夹下的正样本个数,一般留有一定的余量

指定-numNeg参数时,可以多于negitive目录下的负样本数量


D:\opencv3.4.12\opencv\build\x64\vc15\bin\opencv_traincascade.exe -data C:\Users\lng\Desktop\image -vec C:\Users\lng\Desktop\image\sample.vec -bg bg.txt -numPos 50 -numNeg 500 -numStages 12 -feattureType HAAR -w 24 -h 24 -minHitRate 0.995 -maxFalseAlarmRate 0.5


训练完成后,在img目录下就会生成以下文件。

1.png

cascade.xml就是我们需要的分类器文件,其他都是过程文件。


测试代码

main.cpp

#include <iostream>

#include <opencv2/opencv.hpp>


char* face_cascade_name = "C:\\Users\\lng\\Desktop\\image\\cascade.xml";


void faceRecongize(cv::CascadeClassifier faceCascade, cv::Mat frame);


int main(){

    cv::VideoCapture *videoCap = new cv::VideoCapture;


cv::CascadeClassifier faceCascade;


    // 加载苹果分类器文件

if (!faceCascade.load(face_cascade_name)) {

std::cout << "load face_cascade_name failed. " << std::endl;

return -1;

}


    // 打开摄像机

videoCap->open(0);



if (!videoCap->isOpened()) {

videoCap->release();

std::cout << "open camera failed"<< std::endl;

        return -1;

}


std::cout << "open camera success"<< std::endl;


    while(1){

cv::Mat frame;

//读取视频帧

videoCap->read(frame);


if (frame.empty()) {

videoCap->release();

return -1;

}


        //进行苹果识别

faceRecongize(faceCascade, frame);


        //窗口进行展示

        imshow("face", frame);


        //等待回车键按下退出程序

if (cv::waitKey(30) == 13) {

cv::destroyAllWindows();

return 0;

}

    }


    system("pause");

    return 0;

}


void faceRecongize(cv::CascadeClassifier faceCascade, cv::CascadeClassifier eyesCascade, cv::CascadeClassifier mouthCascade, cv::Mat frame) {

std::vector<cv::Rect> faces;


    // 检测苹果

faceCascade.detectMultiScale(frame, faces, 1.1, 2, 0 | cv::CASCADE_SCALE_IMAGE, cv::Size(30, 30));

for (int i = 0; i < faces.size(); i++) {

        // 用椭圆画出苹果部分

        cv::Point center(faces[i].x + faces[i].width / 2, faces[i].y + faces[i].height / 2);

ellipse(frame, center, cv::Size(faces[i].width / 2, faces[i].height / 2), 0, 0, 360, cv::Scalar(255, 0, 255), 4, 8, 0);

cv::Mat faceROI = frame(faces[i]);

std::vector<cv::Rect> eyes;


            

        // 苹果上方区域写字进行标识

cv::Point centerText(faces[i].x + faces[i].width / 2 - 40, faces[i].y - 20);

cv::putText(frame, "apple", centerText, cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(0, 0, 255), 2);


Python-opencv实现目标检测定位:判断固定颜色物体是否在规定区域内

点击查看原文

运行环境:python 3.8.17      opencv 4.8.0

下面是完整代码:


import numpy as np

import cv2

 

cap = cv2.VideoCapture("video.mp4")  # 将"video.mp4"换为0,即可调用摄像头

width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))  # 获取视频的宽度

height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))  # 获取视频的高度

print(width, height)

# 下面是规定区域的位置设置

w1 = 400

h1 = 400

x1 = int(width / 2 - w1 / 2)

y1 = int(height / 2 - h1 / 2 - 100)

# print(x1, y1, x1 + w1, y1 + h1)

font = cv2.FONT_HERSHEY_SIMPLEX  # 设置字体样式

kernel = np.ones((5, 5), np.uint8)  # 卷积核

 

if cap.isOpened() is True:  # 检查摄像头是否正常启动

    while True:

        ret, frame = cap.read()

        if not ret:

            break

        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)  # 转换为灰色通道

        hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)  # 转换为HSV空间

 

        lower_green = np.array([35, 50, 100])  # 设定绿色的阈值下限

        upper_green = np.array([77, 255, 255])  # 设定绿色的阈值上限

        # 消除噪声

        mask = cv2.inRange(hsv, lower_green, upper_green)  # 设定掩膜取值范围

        opening = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)  # 形态学开运算

        bilateral = cv2.bilateralFilter(mask, 10, 200, 200)  # 双边滤波消除噪声

        edges = cv2.Canny(opening, 50, 100)  # 边缘识别

 

        # 在原视频上跟踪目标绘制绿色矩形框

        contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

        for contour in contours:

            x, y, w, h = cv2.boundingRect(contour)  # 获取轮廓的边界框

            # print(x, y, w, h)

            cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)  # 在原视频上绘制矩形框

            # 判断位置关系

            if x >= x1 and y >= y1 and x + w <= x1 + w1 and y + h <= y1 + h1:

                result = "True"

            else:

                result = "Flase"

            cv2.putText(frame, result, (10, 30), font, 1.0, (255, 0, 255), 2)

 

        # 在原视频上绘制限定区域框

        cv2.rectangle(frame, (x1, y1), (x1 + w1, y1 + h1), (0, 0, 0), 2)  # frame要绘制的帧,四个坐标点,颜色,线宽

 

        cv2.imshow('edges', edges)

        cv2.imshow('frame', frame)

        k = cv2.waitKey(5) & 0xFF

        # 按Esc键退出

        if k == 27:

            break

    cap.release()

    cv2.destroyAllWindows()

else:

    print('cap is not opened!')


可以将cv2.rectangle(frame, (x1, y1), (x1 + w1, y1 + h1), (0, 0, 0), 2)缩进,把固定区域框的颜色从黑色(0,0,0)换为变量color,与判定结果"True""Flase"关联,设为两种不同的颜色,即可只管看到区域之间的位置关系。

缺点:对噪声处理不完全,在分割边缘的时候会产生噪点。













Top