hogsvm.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. #!/usr/bin/env python
  2. import cv2 as cv
  3. import numpy as np
  4. import sys
  5. import csv
  6. bin_n = 16 # Number of bins
  7. # histogram of gradients
  8. # @param img image
  9. # @returns 64-bit vector with hog
  10. ## [hog]
  11. def hog(img):
  12. gx = cv.Sobel(img, cv.CV_32F, 1, 0)
  13. gy = cv.Sobel(img, cv.CV_32F, 0, 1)
  14. mag, ang = cv.cartToPolar(gx, gy)
  15. bins = np.int32(bin_n*ang/(2*np.pi)) # quantizing binvalues in (0...16)
  16. bin_cells = bins[:10,:10], bins[10:,:10], bins[:10,10:], bins[10:,10:]
  17. mag_cells = mag[:10,:10], mag[10:,:10], mag[:10,10:], mag[10:,10:]
  18. hists = [np.bincount(b.ravel(), m.ravel(), bin_n) for b, m in zip(bin_cells, mag_cells)]
  19. hist = np.hstack(hists) # hist is a 64 bit vector
  20. return hist
  21. ## [hog]
  22. def color_histogram(img):
  23. bins_per_color = 128
  24. chans = cv.split(img)
  25. colors = ("b", "g", "r")
  26. features = []
  27. for (chan, color) in zip(chans, colors):
  28. hist, bins= np.histogram(chan,bins_per_color,[0,256])
  29. features.extend(hist)
  30. return np.array(features).flatten()
  31. def hogcv(img):
  32. winSize = (20,20)
  33. blockSize = (10,10)
  34. blockStride = (5,5)
  35. cellSize = (10,10)
  36. nbins = 8
  37. derivAperture = 1
  38. winSigma = -1.
  39. histogramNormType = 0
  40. L2HysThreshold = 0.5
  41. gammaCorrection = 1
  42. nlevels = 32
  43. signedGradients = True
  44. h = cv.HOGDescriptor(winSize, blockSize, blockStride, cellSize, nbins, derivAperture, winSigma, histogramNormType, L2HysThreshold, gammaCorrection, nlevels, signedGradients)
  45. return h.compute(img)
  46. def feature_vector(img):
  47. features = []
  48. # features.extend(hog(img));
  49. features.extend(hogcv(img));
  50. features.extend(color_histogram(img))
  51. return np.array(features).flatten()
  52. if __name__ == '__main__':
  53. if len(sys.argv) != 2:
  54. print ("usage: {0} anot.csv".format(sys.argv[0]))
  55. print (" anot.csv consits of \"filename,class\\n\"");
  56. sys.exit(1)
  57. anot_file = sys.argv[1];
  58. cells = []
  59. responses = []
  60. classes = []
  61. filenames = []
  62. # reads anotation from csv and load images into cells and extract hog
  63. file_count=0
  64. with open(anot_file, 'rt') as csvfile:
  65. anot_reader = csv.reader(csvfile, delimiter=',')
  66. for row in anot_reader:
  67. img_filename = row[0]
  68. anot = row[1]
  69. img = cv.imread(img_filename)
  70. if img is None:
  71. raise Exception("Error: file {} is not image".format(img_filename))
  72. cells.append(feature_vector(img));
  73. if not anot in classes:
  74. classes.append(anot)
  75. anot_id = classes.index(anot)
  76. responses.append(anot_id);
  77. filenames.append(img_filename);
  78. file_count += 1
  79. # split into training and testing set
  80. ratio = 0.8
  81. train_size = (int)(file_count * ratio)
  82. print ("train_size={0}; test_size={1}".format(train_size, file_count - train_size))
  83. # print("data train + anot = :{0} + {1} = {2}".format(train_size, test_size, file_count))
  84. cells = np.array(cells)
  85. feature_shape = cells[0].shape[0]
  86. train_cells = np.array(cells[:train_size])
  87. test_cells = np.array(cells[train_size:])
  88. train_anot=np.array(responses)[:train_size]
  89. test_anot=np.array(responses)[train_size:]
  90. test_filenames=np.array(filenames)[train_size:]
  91. train_data = np.float32(train_cells).reshape(-1,feature_shape )
  92. test_data = np.float32(test_cells).reshape(-1,feature_shape )
  93. svm = cv.ml.SVM_create()
  94. # svm.setKernel(cv.ml.SVM_LINEAR)
  95. svm.setKernel(cv.ml.SVM_RBF)
  96. svm.setType(cv.ml.SVM_C_SVC)
  97. svm.setC(2.67)
  98. svm.setGamma(5.383)
  99. # print("c = {0}; gamma = {1}; isTrained = {2}".format(svm.getC(), svm.getGamma(), svm.isTrained()))
  100. # train_data.shape = (2500,feature_shape), responses.shape: (2500, 1)
  101. # svm.train(train_data, cv.ml.ROW_SAMPLE, train_anot)
  102. svm.trainAuto(train_data, cv.ml.ROW_SAMPLE, train_anot)
  103. print("c = {0}; gamma = {1}; isTrained = {2}".format(svm.getC(), svm.getGamma(), svm.isTrained()))
  104. svm.save('svm_data.dat')
  105. result = svm.predict(test_data)[1][:,0]
  106. mask = result==test_anot
  107. if 1:
  108. ## print false detections
  109. print ("<h2>false positive</h2>");
  110. for f, r, a, m in zip(test_filenames, result, test_anot, mask):
  111. if not m and a:
  112. print("<img src=\"file://{}\"/>".format(f))
  113. # print(r, a, m, f)
  114. print ("<h2>false negative</h2>");
  115. for f, r, a, m in zip(test_filenames, result, test_anot, mask):
  116. if not m and not a:
  117. print("<img src=\"file://{}\"/>".format(f))
  118. print ("<h2>true negative</h2>");
  119. for f, r, a, m in zip(test_filenames, result, test_anot, mask):
  120. if m and a:
  121. print("<img src=\"file://{}\"/>".format(f))
  122. # print(r, a, m, f)
  123. print ("<h2>true positive </h2>");
  124. for f, r, a, m in zip(test_filenames, result, test_anot, mask):
  125. if m and not a:
  126. print("<img src=\"file://{}\"/>".format(f))
  127. # print(r, a, m, f)
  128. correct = np.count_nonzero(mask)
  129. print("accuracy = {}".format(correct*100.0/result.size))