OpenCV训练级联分类器
新建文件夹,在该文件夹当中新建neg(存放负样本)、pos(存放正样本)这两个文件夹。
在该文件夹当中新建1.py,填入如下代码以生成灰度文件,注意要以管理员权限打开powershell执行python代码!
# 图像转换代码,负责处理正样本
import cv2
import os
# 指定目录路径
directory_path = r'C:\Users\20414\Desktop\opencv341_bin-master\pos'
# 获取目录下所有文件
file_list = os.listdir(directory_path)
# 遍历每个文件并转换为灰度图
for filename in file_list:
file_path = os.path.join(directory_path, filename)
img = cv2.imread(file_path, cv2.IMREAD_GRAYSCALE) # 读取为灰度图
resized_img = cv2.resize(img, (60, 60)) # 调整像素为 60x60
# 保存灰度图;此处如果不改文件名,会覆盖原先的文件
cv2.imwrite(f'GRAY_{filename}', resized_img)
print("已将所有图片转换为灰度图并调整像素。")
新建2.py,填入如下代码以生成两个txt文件,同样以管理员权限打开powershell执行python代码!
import os
def create_pos_n_neg():
for file_type in ['pos', 'neg']: #此处修改neg或pos即可
if not os.path.exists(file_type):
continue
for img in os.listdir(file_type):
if (file_type.startswith('neg')):
line = 'C:/Users/20414/Desktop/opencv341_bin-master/'+ file_type + '/' + img + '\n'
with open('bg.txt', 'a') as f:
f.write(line)
elif (file_type.startswith('pos')):
line = 'C:/Users/20414/Desktop/opencv341_bin-master/'+ 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('描述文件已生成!')
生成的代码会在根目录下生成两个txt文档
将这两个txt复制到opencv_annotation.exe的所在目录,并在该目录下执行以下指令,以生成.vec文件
.\opencv_createsamples.exe -vec info.vec -info info.txt -bg bg.txt -num 105 -w 50 -h 50
或:
opencv_createsamples.exe -vec info.vec -info info.txt -bg bg.txt -num 1200 -w 50 -h 50
生成完成后,终端继续执行以下指令,生成最终的xml文件
.\opencv_traincascade.exe -data C:\Users\20414\Desktop\opencv\build\x64\vc14\bin\data -vec C:\Users\20414\Desktop\opencv\build\x64\vc14\bin\info.vec -bg C:\Users\20414\Desktop\opencv\build\x64\vc14\bin\bg.txt -numPos 4 -numNeg 100 -numStages 5 -featureType LBP -w 50 -h 50
或:
opencv_traincascade.exe -data data -vec info.vec -bg bg.txt -numPos 1000 -numNeg 2000 -numStages 5 -featureType LBP -w 50 -h 50
参考链接:
OpenCV编程:OpenCV3.X训练自己的分类器_7月月更_DS小龙哥_InfoQ写作社区
Windows环境下训练OpenCV分类器_positives.vec-CSDN博客
加载分类器并在指定区域匹配:
只检测画面正中央的指定区域作为检测区域,如果检测到特定物体,则将该物体用绿色方框框出
import cv2
# 加载级联分类器
object_cascade = cv2.CascadeClassifier("./data/testdata/cascade.xml")
# 打开摄像头
cap = cv2.VideoCapture(0)
# 获取画面宽度和高度
frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
# 计算画面中间矩形区域的左上角坐标
roi_x = (frame_width - 20) // 2
roi_y = (frame_height - 20) // 2
while True:
# 读取摄像头帧
ret, frame = cap.read()
# 将帧转换为灰度图像
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 获取画面中间 20x20 区域
roi_gray = gray[roi_y:roi_y + 150, roi_x:roi_x + 150]
# 检测物体
objects = object_cascade.detectMultiScale(roi_gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))
# 在原始图像上绘制矩形框
for (x, y, w, h) in objects:
cv2.rectangle(frame, (roi_x + x, roi_y + y), (roi_x + x + w, roi_y + y + h), (0, 255, 0), 2)
# 显示结果
cv2.imshow("Object Detection", frame)
# 按下 'q' 键退出循环
if cv2.waitKey(1) & 0xFF == ord("q"):
break
# 释放摄像头和窗口
cap.release()
cv2.destroyAllWindows()