hogsvm.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  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 = 64
  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 ptc".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(hog(img))
  73. cells.append(feature_vector(img));
  74. if not anot in classes:
  75. classes.append(anot)
  76. anot_id = classes.index(anot)
  77. responses.append(anot_id);
  78. filenames.append(img_filename);
  79. file_count += 1
  80. # split into training and testing set
  81. ratio = 0.8
  82. train_size = (int)(file_count * ratio)
  83. print ("train_size={0}; test_size={1}".format(train_size, file_count - train_size))
  84. # print("data train + anot = :{0} + {1} = {2}".format(train_size, test_size, file_count))
  85. cells = np.array(cells)
  86. feature_shape = cells[0].shape[0]
  87. train_cells = np.array(cells[:train_size])
  88. test_cells = np.array(cells[train_size:])
  89. train_anot=np.array(responses)[:train_size]
  90. test_anot=np.array(responses)[train_size:]
  91. test_filenames=np.array(filenames)[train_size:]
  92. train_data = np.float32(train_cells).reshape(-1,feature_shape )
  93. test_data = np.float32(test_cells).reshape(-1,feature_shape )
  94. svm = cv.ml.SVM_create()
  95. svm.setKernel(cv.ml.SVM_LINEAR)
  96. # svm.setKernel(cv.ml.SVM_RBF)
  97. svm.setType(cv.ml.SVM_C_SVC)
  98. # svm.setC(2.67)
  99. # svm.setGamma(5.383)
  100. print("c = {0}; gamma = {1}; isTrained = {2}".format(svm.getC(), svm.getGamma(), svm.isTrained()))
  101. # train_data.shape = (2500,feature_shape), responses.shape: (2500, 1)
  102. # svm.train(train_data, cv.ml.ROW_SAMPLE, train_anot)
  103. svm.trainAuto(train_data, cv.ml.ROW_SAMPLE, train_anot)
  104. print("c = {0}; gamma = {1}; isTrained = {2}".format(svm.getC(), svm.getGamma(), svm.isTrained()))
  105. svm.save('svm_data.dat')
  106. result = svm.predict(test_data)[1][:,0]
  107. mask = result==test_anot
  108. if 1:
  109. ## print false detections
  110. print ("<h2>false positive</h2>");
  111. for f, r, a, m in zip(test_filenames, result, test_anot, mask):
  112. if not m and a:
  113. print("<img src=\"file://{}\"/>".format(f))
  114. # print(r, a, m, f)
  115. print ("<h2>false negative</h2>");
  116. for f, r, a, m in zip(test_filenames, result, test_anot, mask):
  117. if not m and not a:
  118. print("<img src=\"file://{}\"/>".format(f))
  119. print ("<h2>true negative</h2>");
  120. for f, r, a, m in zip(test_filenames, result, test_anot, mask):
  121. if m and a:
  122. print("<img src=\"file://{}\"/>".format(f))
  123. # print(r, a, m, f)
  124. print ("<h2>true positive </h2>");
  125. for f, r, a, m in zip(test_filenames, result, test_anot, mask):
  126. if m and not a:
  127. print("<img src=\"file://{}\"/>".format(f))
  128. # print(r, a, m, f)
  129. correct = np.count_nonzero(mask)
  130. print("accuracy = {}".format(correct*100.0/result.size))