当前位置:   article > 正文

计算机视觉基础系列(python与opencv的操作与运用/tensorflow的基础介绍)(二十四)---Hog+SVM的识别_hog+svm训练 数据集该怎么准备

hog+svm训练 数据集该怎么准备

训练数据的时候,首先需要做下面几步:

1.准备训练样本;2.对样本进行Hog+Svm的训练;3.运用test图片进行预测

一、准备样本

样本分为正样本和负样本,样本的准备可以运用视频的分帧截取图片存储。这里pos文件夹下包含正样本,包含所检测的目标;neg不包含检测的目标为负样本。样本的准备的时候,图片的尺寸需要注意,这里的尺寸是64x128。

样本的获取的手段:1.来源于网络;2.自己收集。一个好的样本远胜过一个复杂的神经网络,容量大。通常我们是自己收集样本的,会通过视频截取帧来得到的,比如说一秒28帧,有100秒,则可以得到2800张图片。

正样本的特点:尽可能多样性,这里的多样性一般是指的环境的多样性,干扰性因素多,这样检测的效果较好。这里有截取本数据集的部分代码。如下,代码有部分解释,也较为简单,可以看懂:

  1. # 视频分解成图片
  2. # 1 load加载视频 2 读取info 3 解码 单帧视频parse 4 展示 imshow
  3. import cv2
  4. # 获取一个视频打开cap
  5. cap = cv2.VideoCapture('1.mp4')
  6. # 判断是否打开
  7. isOpened = cap.isOpened
  8. print(isOpened)
  9. #帧率
  10. fps = cap.get(cv2.CAP_PROP_FPS)
  11. #宽度
  12. width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
  13. #高度
  14. height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
  15. print(fps,width,height)
  16. i = 0
  17. while(isOpened):
  18. if i == 100:
  19. break
  20. else:
  21. i = i+1
  22. (flag,frame) = cap.read() # 读取每一张 flag读取是否成功 frame内容
  23. fileName = 'imgs\\'+str(i) + '.jpg'
  24. print(fileName)
  25. if flag == True:
  26. #写入图片
  27. cv2.imwrite(fileName,frame,[cv2.IMWRITE_JPEG_QUALITY,100])
  28. print('end!')

图片分解完后,我们这里其实准备的数据集的尺寸是64x128,所以这里我们需要裁剪和截取。下面是裁剪和截取的代码,这里的代码前面有所介绍,这里可以看到具体介绍

  1. # 540 * 960 ==>64*128
  2. import cv2
  3. for i in range(0,100):
  4. fileName = 'imgs\\'+str(i+1)+'.jpg'
  5. print(fileName)
  6. img = cv2.imread(fileName)
  7. imgInfo = img.shape
  8. height = imgInfo[0]
  9. width = imgInfo[1]
  10. mode = imgInfo[2]
  11. dstHeight = 128
  12. dstWidth = 64
  13. dst = cv2.resize(img,(dstWidth,dstHeight))
  14. cv2.imwrite(fileName,dst)

这里准备的正样本的数量是820个,负样本是1931个,一般来说,正负样本的比例是1:2或者1:3。

二、训练样本

在训练样本的时候,要注意一些问题,在代码注释中会有详细说明,如下,代码很多地方都有,可以看一下说明注释:

可以结合上一篇博客来看,就会较快的理解。

第七步(检测)的重点介绍:
没有直接运用svm.predict来进行预测。

resultArray是3780维的,rho是一个一行一列一维的,而最终的的数组myDetect是3781维度的,所以3780的维是来自resultArray的,最后一个维度是来自rho的。

检测需要创建myhog,需要用myhog进行检测,用detectMultiScale进行检测,没有用predict方法,得到宽高等信息返回,才能把目标绘制出来。代码如下:

  1. # 1.参数的设置 2.hog的创建(实例对象) 3.获取SVM的参数
  2. # 4.计算hog 5.label标签 6.完成train训练 7.完成predicr 8.绘图draw
  3. import cv2
  4. import numpy as np
  5. import matplotlib.pyplot as plt
  6. # 1 参数的设置:设置全局变量 在一个windows窗体中有105个block,每个block下有4个cell,每个cell下有9个bin,总共3780维
  7. PosNum = 820 # 正样本的个数
  8. NegNum = 1931 # 负样本的个数
  9. winSize = (64, 128) # 窗体大小
  10. blockSize = (16, 16) # 105个block
  11. blockStride = (8, 8) # block的步长
  12. cellSize = (8, 8)
  13. nBin = 9
  14. # 2 hog对象的创建,HOGDescriptor创建的方法,参数设置:1.窗体的大小,2.block的大小,3.步长,4.cell的大小,5.Bin的数量
  15. hog = cv2.HOGDescriptor(winSize, blockSize, blockStride, cellSize, nBin)
  16. # 3 SVM分类器的创建,定义一个SVM的对象,来自机器学习的SVM创建的模块
  17. svm = cv2.ml.SVM_create()
  18. # 4 计算当前的hog,需要准备各种参数,并且我们需要把参数计算完后保存在某个地方,所以我们需要新设置一定的数组,或者是当前hog特征的维度
  19. featureNum = int(((128-16)/8+1)*((64-16)/8+1)*4*9)
  20. # 3780,特征的维度,是一个int类型;((128-16)/8+1)是block的数量,((64-16)/8+1)为windows的宽度,4就是指的一个block里面有4个cell,9是一个cell里面有9个Bin,这样计算可以的恶道3780维
  21. # 还需要创建一个feature数组和一个label数组用于装载当前的特征,为接下来的第五步和第六步作准备,将标签和特征准备好
  22. featureArray = np.zeros(((PosNum+NegNum), featureNum), np.float32)
  23. # featureArray是一个二维的数组,第一个(PosNum+NegNum)是正负样本的个数,featureNum特征的维度
  24. labelArray = np.zeros(((PosNum+NegNum), 1), np.int32) # 定义一个标签,也是一个二维的,参数和上面的一样
  25. # SVM 是监督学习,所以需要样本和标签 SVM进行学习,而学习的是图片中的的hog特征,所以我们可以说hog特征可以说做是SVM真正的样本,标签是我们在进行SVM训练的时候,进行监督学习使用的
  26. # 遍历所有的图片:正负样本都需要遍历
  27. for i in range(0, PosNum):
  28. fileName = 'pos\\'+str(i+1)+'.jpg'
  29. img = cv2.imread(fileName) # 图片的读取
  30. hist = hog.compute(img, (8, 8)) # 当前hog的计算 3780维的数据,用hist装载特征,计算HOG描述子,检测窗口移动步长(8,8)
  31. # 当前的问题是:我们需要将hog特征装载到featureArray中,而featureArray是一个二维的,而计算出来的只是一个hist,那么这一步怎么完成呢?
  32. # 其实我们这里的hist是一个3780维的,而featureArray是一个二维的,且第一个参数是正负样本的个数,第二个参数是featureNum,我们可以这么操作:
  33. for j in range(0,featureNum):
  34. # featureArray装载的是hog的特征,比如说i=1的时候,第一个hog表示为hog1,i=2的时候为hog2,第二个特征,每一个特征是3780维的,所以hist[j]要放到i行,第j列中
  35. featureArray[i,j] = hist[j] # hog特征的装载
  36. labelArray[i,0] = 1 # 正样本标签为1,labelArray也是一个二维的,n行1列的,所以纵坐标放置的是0,正样本处理完毕,接下来的负样本的设置是一样的
  37. for i in range(0, NegNum):
  38. fileName = 'neg\\'+str(i+1)+'.jpg'
  39. img = cv2.imread(fileName)
  40. hist = hog.compute(img,(8,8))
  41. for j in range(0,featureNum):
  42. featureArray[i+PosNum,j] = hist[j] # 同样要把特征放在featureArray中,所以i+PosNum是要记录负样本的时候必须装载在正样本的后面
  43. labelArray[i+PosNum,0] = -1 # 负样本标签为-1
  44. # 设置SVM的属性,setType设置属性,添加当前类型,再来设置setKernel为SVM的线性内核,再来设置setC
  45. svm.setType(cv2.ml.SVM_C_SVC)
  46. svm.setKernel(cv2.ml.SVM_LINEAR)
  47. svm.setC(0.01)
  48. # 6 train,调用train进行训练,参数:1.特征数组;2.机器学习ROW_SAMPLE;3.标签数组。返回值为ret
  49. ret = svm.train(featureArray, cv2.ml.ROW_SAMPLE, labelArray)
  50. # 预测可以运用svm.predict来进行预测,这里我们不用,使用其他方法来进行检测
  51. # 7 预测(创建myHog--->myDect参数得到-->来源于resultArray(公式得到) rho(训练得到))
  52. # rho是svm得到的一个hog的描述信息,这个在最后的阈值判决的时候起作用,在累加的时候起作用
  53. # 深入到hog以及svm最后的判决中看
  54. alpha = np.zeros((1), np.float32)
  55. # getDecisionFunction方法最核心的还是svm的计算,svm来源于训练方法,样本准备好后训练可以得到svm,然后得到rho
  56. rho = svm.getDecisionFunction(0, alpha)
  57. print(rho)
  58. print(alpha)
  59. # resultArray,定义alphaArray,我们需要用alphaArray和支持向量机数组进行相乘
  60. alphaArray = np.zeros((1, 1), np.float32)
  61. # 设置支持向量机数组
  62. supportVArray = np.zeros((1, featureNum), np.float32)
  63. resultArray = np.zeros((1, featureNum), np.float32)
  64. alphaArray[0, 0] = alpha # 一行一列的,所以第一个元素是[0, 0]
  65. resultArray = -1*alphaArray*supportVArray # 计算公式;resultArray 计算,支持向量的个数,只需要当成参数就行
  66. # mydect参数,构建detect
  67. myDetect = np.zeros(3781, np.float32)
  68. for i in range(0, 3780):
  69. # 是一个一维的,myDetect
  70. myDetect[i] = resultArray[0,i]
  71. myDetect[3780] = rho[0]
  72. # myHog的创建很重要
  73. # 构建好Hog,用HOGDescriptor方法构建
  74. myHog = cv2.HOGDescriptor()
  75. # 返回的myHog,用setSVMDetector设置属性
  76. myHog.setSVMDetector(myDetect)
  77. # 待检测图片的加载
  78. imageSrc = cv2.imread('test2.jpg', 1)
  79. # 检测小狮子 (8,8)winds的滑动步长 1.05 缩放系数 (32,32)窗口大小
  80. # 完成检测,返回的目标包含哪些信息,myHog有个方法detectMultiScale,和人脸识别比较类似,缩放。
  81. # 它可以检测出图片中所有的目标,并将目标用vector保存各个目标的坐标、大小(用矩形表示),函数由分类器对象调用;1.05是缩放,(8, 8)windows的滑动步长,(32, 32)窗体大小
  82. # myHog的创建很重要
  83. objs = myHog.detectMultiScale(imageSrc, 0, (8, 8), (32, 32), 1.05, 2)
  84. # 起始位置、宽和高 objs三维信息,获取目标的坐标,是三维的,所以我们需要定义一个三维的坐标,这些信息放在三维中的最后一维
  85. x = int(objs[0][0][0]) # 坐标,w和h是宽高
  86. y = int(objs[0][0][1])
  87. w = int(objs[0][0][2])
  88. h = int(objs[0][0][3])
  89. # 目标的绘制 图片 起始位置 终止位置 颜色,绘制矩形框
  90. cv2.rectangle(imageSrc, (x, y), (x+w, y+h), (255, 0, 0))
  91. # 目标的展示
  92. cv2.imshow('dst', imageSrc)
  93. cv2.waitKey(0)

实验相关数据集点击此处下载

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号