11 int randomWindowScaleFloor,
12 int randomWindowScaleCeil)
14 std::cout <<
"a HoG class constructed" << std::endl;
15 numberOfBins = numOfBing;
16 sampleTimes = sampleTime;
17 numberOfHistory = numOfHistory;
18 minimumRandomWindow = minRandomWindow;
19 randomWindowScaleRateFloor = randomWindowScaleFloor;
20 randomWindowScaleRateCeil = randomWindowScaleCeil;
27 doLoadTrainingData(path +
"t_training/", trainingHistTable, 6);
28 doLoadTrainingData(path +
"n_training/", trainingHistTableNegative, 12);
32 HoG::doLoadTrainingData(std::string path, std::vector<std::vector<float>>& histTable,
int scaling)
35 CByteImage *origin, *greyImage;
36 CFloatImage *hogImg, *amplitude;
37 std::vector<float> trainHist(numberOfBins, 0);
38 std::vector<float> trainHistNorm(numberOfBins, 0);
40 std::vector<std::string> fileNames;
42 for (std::filesystem::recursive_directory_iterator end, dir(path); dir != end; ++dir)
44 if (dir->path().extension() ==
".bmp")
46 fileNames.push_back(dir->path().string());
51 for (std::string
filename : fileNames)
53 CBitmapCapture capture(
filename.c_str());
55 if (capture.OpenCamera() ==
false)
57 std::cout <<
"error: could not open camera. Positive examples. " <<
filename
61 origin =
new CByteImage(capture.GetWidth(), capture.GetHeight(), CByteImage::eRGB24);
62 capture.CaptureImage(&origin);
64 for (
int j = 2; j < scaling; j++)
66 width = capture.GetWidth() / j;
67 height = capture.GetHeight() / j;
69 CByteImage* image =
new CByteImage(width, height, CByteImage::eRGB24);
70 greyImage =
new CByteImage(width, height, CByteImage::eGrayScale);
71 hogImg =
new CFloatImage(width, height, 1);
72 amplitude =
new CFloatImage(width, height, 1);
74 ImageProcessor::Resize(origin, image);
75 HoG::preprocess(image, greyImage);
76 HoG::hogDescriptor(greyImage, hogImg, amplitude);
77 HoG::calculateHist(360, numberOfBins, hogImg, &trainHist, amplitude);
78 HoG::histogramNorm(&trainHist, &trainHistNorm);
80 histTable.push_back(trainHistNorm);
95 int width = origin->width;
96 int height = origin->height;
98 CByteImage tempSaliencyImage(width, height, CByteImage::eGrayScale);
99 CByteImage* saliencyImageOrigin =
new CByteImage(width, height, CByteImage::eGrayScale);
100 CFloatImage* hogImg =
new CFloatImage(width, height, 1);
101 CFloatImage* amplitude =
new CFloatImage(width, height, 1);
102 CByteImage* greyImage =
new CByteImage(width, height, CByteImage::eGrayScale);
104 HoG::preprocess(origin, greyImage);
105 HoG::hogDescriptor(greyImage, hogImg, amplitude);
106 ImageProcessor::Zero(saliencyImageOrigin);
114 for (
int i = 0; i < numberOfHistory; i++)
116 for (
int i = 0; i < saliencyImageOrigin->width * saliencyImageOrigin->height; i++)
118 saliencyImageOrigin->pixels[i] /= 3;
121 #pragma omp parallel for
122 for (
int i = 0; i < sampleTimes; i++)
124 int sampleWindowSize, windowCenterX, windowCenterY;
126 minimumRandomWindow + rand() % (
std::min(width, height) - minimumRandomWindow);
129 windowCenterX = sampleWindowSize / 2 + rand() % (width - sampleWindowSize);
130 windowCenterY = sampleWindowSize / 2 + rand() % (height - sampleWindowSize);
132 for (
int j = randomWindowScaleRateFloor; j < randomWindowScaleRateCeil; j++)
135 sampleWindowSize /= j;
136 CByteImage* sampleWindow =
137 new CByteImage(sampleWindowSize, sampleWindowSize, CByteImage::eGrayScale);
138 CFloatImage* sampleHogImg =
139 new CFloatImage(sampleWindow->width, sampleWindow->height, 1);
140 CFloatImage* sampleAmplitude =
141 new CFloatImage(sampleWindow->width, sampleWindow->height, 1);
142 for (
int wIn = windowCenterX - (sampleWindowSize / 2), wOut = 0;
143 wOut < sampleWindowSize;
146 for (
int hIn = windowCenterY - (sampleWindowSize / 2), hOut = 0;
147 hOut < sampleWindowSize;
150 sampleWindow->pixels[hOut * sampleWindowSize + wOut] =
151 greyImage->pixels[hIn * width + wIn];
152 sampleHogImg->pixels[hOut * sampleWindowSize + wOut] =
153 hogImg->pixels[hIn * width + wIn];
154 sampleAmplitude->pixels[hOut * sampleWindowSize + wOut] =
155 amplitude->pixels[hIn * width + wIn];
159 std::vector<float> sampleHist(numberOfBins, 0);
160 std::vector<float> sampleHistNorm(numberOfBins, 0);
162 HoG::calculateHist(360, numberOfBins, sampleHogImg, &sampleHist, sampleAmplitude);
163 HoG::histogramNorm(&sampleHist, &sampleHistNorm);
170 knn(trainingHistTable, trainingHistTableNegative, sampleHistNorm);
174 for (
int j = -1; j <= 1; j++)
176 for (
int k = -1; k <= 1; k++)
179 ->pixels[width * (windowCenterY + j) + (windowCenterX + k)] =
186 if (useHoughDetector)
204 delete sampleAmplitude;
209 for (
int j = 0; j < 3; j++)
212 ImageProcessor::GaussianSmooth5x5(saliencyImageOrigin, &tempSaliencyImage);
213 ImageProcessor::GaussianSmooth5x5(&tempSaliencyImage, saliencyImageOrigin);
215 ImageProcessor::HistogramStretching(saliencyImageOrigin, &tempSaliencyImage, 0.0, 1.0);
216 ImageProcessor::CopyImage(&tempSaliencyImage, saliencyImageOrigin);
218 for (
int i = 0; i < saliencyImage->width * saliencyImage->height; i++)
220 saliencyImage->pixels[i] = (
float)saliencyImageOrigin->pixels[i] / 255;
228 delete saliencyImageOrigin;
232 HoG::hogDescriptor(CByteImage* origin, CFloatImage* outImage, CFloatImage* amplitude)
235 width = origin->width;
236 height = origin->height;
237 CShortImage sobelXImage(width, height);
238 CShortImage sobelYImage(width, height);
241 ImageProcessor::SobelX(origin, &sobelXImage,
false);
242 ImageProcessor::SobelY(origin, &sobelYImage,
false);
244 for (
int i = 0; i < width * height; i++)
248 outImage->pixels[i] = atan2((
float)sobelXImage.pixels[i], (
float)sobelYImage.pixels[i]);
249 outImage->pixels[i] = (outImage->pixels[i] * 180) /
M_PI;
250 if (outImage->pixels[i] < 0)
252 outImage->pixels[i] += 360;
254 amplitude->pixels[i] =
sqrt((
float)sobelXImage.pixels[i] * (
float)sobelXImage.pixels[i] +
255 (
float)sobelYImage.pixels[i] * (
float)sobelYImage.pixels[i]);
261 HoG::calculateHist(
int range,
263 CFloatImage* inputImg,
264 std::vector<float>* output,
265 CFloatImage* amplitude)
269 std::vector<float>::iterator it;
270 binRange = ceil((
float)range / (
float)bin);
272 for (it = output->begin(); it < output->end(); it++)
277 for (
int i = 0; i < inputImg->height * inputImg->width; i++)
279 index = inputImg->pixels[i] / binRange;
280 output->at(
index) = output->at(
index) + amplitude->pixels[i];
285 HoG::histogramNorm(std::vector<float>*
input, std::vector<float>* normOutput)
288 for (
size_t i = 0; i < normOutput->size(); i++)
290 normOutput->at(i) = 0;
292 for (
size_t i = 0; i <
input->size(); i++)
294 sum = sum +
input->at(i);
296 for (
size_t i = 0; i <
input->size(); i++)
298 normOutput->at(i) =
input->at(i) / sum;
303 HoG::knn(std::vector<std::vector<float>> trainingHistTable,
304 std::vector<std::vector<float>> trainingHistTableNegative,
305 std::vector<float> testWindow)
307 float nearstDistance, secondDistance, thirdDistance;
317 std::pair<std::vector<float>*,
int> nearstNeighborPtr, secondNeighborPtr, thirdNeighborPtr;
318 nearstNeighborPtr.second = -1;
319 secondNeighborPtr.second = -1;
320 thirdNeighborPtr.second = -1;
325 findThreeNearstNeighbors(testWindow,
334 findThreeNearstNeighbors(testWindow,
335 trainingHistTableNegative,
345 sum = thirdNeighborPtr.second + secondNeighborPtr.second + nearstNeighborPtr.second;
350 if (nearstNeighborPtr.second == 1 && secondNeighborPtr.second == 1 && nearstDistance < 0.15)
364 HoG::preprocess(
const CByteImage* origin, CByteImage* outImage)
366 ImageProcessor::ConvertImage(origin, outImage);
367 for (
int i = 0; i < 4; i++)
369 ImageProcessor::GaussianSmooth5x5(outImage, outImage);
378 HoG::distanceBetweenPoints(std::vector<float> firstPoint,
379 std::vector<float> secondPoint,
383 float manhattanDistance = 0;
384 float multiplicationSumme = 0;
385 float squareSummeFirst = 0;
386 float squareSummeSecond = 0;
389 if (firstPoint.size() != secondPoint.size())
394 for (
size_t i = 0; i < firstPoint.size(); i++)
396 distance += pow(firstPoint[i] - secondPoint[i], 2);
397 manhattanDistance += fabs(firstPoint[i] - secondPoint[i]);
398 multiplicationSumme += firstPoint[i] * secondPoint[i];
399 squareSummeFirst += pow(firstPoint[i], 2);
400 squareSummeSecond += pow(secondPoint[i], 2);
401 if ((firstPoint[i] + secondPoint[i]) != 0)
403 chiSquare += (firstPoint[i] - secondPoint[i]) * (firstPoint[i] - secondPoint[i]) /
404 (firstPoint[i] + secondPoint[i]);
421 result = manhattanDistance;
425 result = (1 - multiplicationSumme / (
sqrt(squareSummeFirst) *
sqrt(squareSummeSecond)));
440 HoG::findThreeNearstNeighbors(std::vector<float> testWindow,
441 std::vector<std::vector<float>> trainingHistTable,
443 std::pair<std::vector<float>*,
int>* nearstNeighbor,
444 std::pair<std::vector<float>*,
int>* secondNeighbor,
445 std::pair<std::vector<float>*,
int>* thirdNeighbor,
446 float* nearstDistance,
447 float* secondDistance,
448 float* thirdDistance)
451 std::vector<std::vector<float>>::iterator hisIt;
452 for (hisIt = trainingHistTable.begin(); hisIt < trainingHistTable.end(); hisIt++)
454 distance = distanceBetweenPoints(*hisIt, testWindow, 4);
459 else if (
distance < *nearstDistance)
461 *thirdNeighbor = *secondNeighbor;
462 *thirdDistance = *secondDistance;
463 *secondNeighbor = *nearstNeighbor;
464 *secondDistance = *nearstDistance;
466 nearstNeighbor->first = &(*hisIt);
467 nearstNeighbor->second = lable;
470 else if (
distance < *secondDistance)
472 *thirdNeighbor = *secondNeighbor;
473 *thirdDistance = *secondDistance;
475 secondNeighbor->first = &(*hisIt);
476 secondNeighbor->second = lable;
482 thirdNeighbor->first = &(*hisIt);
483 thirdNeighbor->second = lable;
490 HoG::histogramRotationInvariant(std::vector<float>* inputHist, std::vector<float>* outputHist)
492 std::vector<float> newHistogram;
493 float max = 0, second = 0;
494 for (
size_t i = 0; i < inputHist->size(); i++)
496 if (inputHist->at(i) > inputHist->at(
max))
500 else if (inputHist->at(i) > inputHist->at(second))
510 for (
size_t i =
max; i < inputHist->size(); i++)
512 newHistogram.push_back(inputHist->at(i));
514 for (
int i = 0; i <
max; i++)
516 newHistogram.push_back(inputHist->at(i));
519 for (
size_t i = 0; i < newHistogram.size(); i++)
521 outputHist->at(i) = newHistogram.at(i);
529 useHoughDetector = useHough;
530 useHoGDetector = useHoG;