8 HoG::HoG(
int numOfBing,
int sampleTime,
int numOfHistory,
int minRandomWindow,
int randomWindowScaleFloor,
int randomWindowScaleCeil)
10 std::cout <<
"a HoG class constructed" << std::endl;
11 numberOfBins = numOfBing;
12 sampleTimes = sampleTime;
13 numberOfHistory = numOfHistory;
14 minimumRandomWindow = minRandomWindow;
15 randomWindowScaleRateFloor = randomWindowScaleFloor;
16 randomWindowScaleRateCeil = randomWindowScaleCeil;
22 doLoadTrainingData(path +
"t_training/", trainingHistTable, 6);
23 doLoadTrainingData(path +
"n_training/", trainingHistTableNegative, 12);
27 void HoG::doLoadTrainingData(std::string path, std::vector<std::vector<float> >& histTable,
int scaling)
30 CByteImage* origin, *greyImage;
31 CFloatImage* hogImg, *amplitude;
32 std::vector<float> trainHist(numberOfBins, 0);
33 std::vector<float> trainHistNorm(numberOfBins, 0);
35 std::vector<std::string> fileNames;
37 for (std::filesystem::recursive_directory_iterator end, dir(path);
40 if (dir->path().extension() ==
".bmp")
42 fileNames.push_back(dir->path().string());
47 for (std::string
filename : fileNames)
49 CBitmapCapture capture(
filename.c_str());
51 if (capture.OpenCamera() ==
false)
53 std::cout <<
"error: could not open camera. Positive examples. " <<
filename << std::endl;
56 origin =
new CByteImage(capture.GetWidth(), capture.GetHeight(), CByteImage::eRGB24);
57 capture.CaptureImage(&origin);
59 for (
int j = 2; j < scaling; j++)
61 width = capture.GetWidth() / j;
62 height = capture.GetHeight() / j;
64 CByteImage* image =
new CByteImage(width, height, CByteImage::eRGB24);
65 greyImage =
new CByteImage(width, height, CByteImage::eGrayScale);
66 hogImg =
new CFloatImage(width, height, 1);
67 amplitude =
new CFloatImage(width, height, 1);
69 ImageProcessor::Resize(origin, image);
70 HoG::preprocess(image, greyImage);
71 HoG::hogDescriptor(greyImage, hogImg, amplitude);
72 HoG::calculateHist(360, numberOfBins, hogImg, &trainHist, amplitude);
73 HoG::histogramNorm(&trainHist, &trainHistNorm);
75 histTable.push_back(trainHistNorm);
94 int width = origin->width;
95 int height = origin->height;
97 CByteImage tempSaliencyImage(width, height, CByteImage::eGrayScale);
98 CByteImage* saliencyImageOrigin =
new CByteImage(width, height, CByteImage::eGrayScale);
99 CFloatImage* hogImg =
new CFloatImage(width, height, 1);
100 CFloatImage* amplitude =
new CFloatImage(width, height, 1);
101 CByteImage* greyImage =
new CByteImage(width, height, CByteImage::eGrayScale);
103 HoG::preprocess(origin, greyImage);
104 HoG::hogDescriptor(greyImage, hogImg, amplitude);
105 ImageProcessor::Zero(saliencyImageOrigin);
113 for (
int i = 0; i < numberOfHistory; i++)
115 for (
int i = 0; i < saliencyImageOrigin->width * saliencyImageOrigin->height; i++)
117 saliencyImageOrigin->pixels[i] /= 3;
120 #pragma omp parallel for
121 for (
int i = 0; i < sampleTimes; i++)
123 int sampleWindowSize, windowCenterX, windowCenterY;
124 sampleWindowSize = minimumRandomWindow + rand() % (
std::min(width, height) - minimumRandomWindow);
127 windowCenterX = sampleWindowSize / 2 + rand() % (width - sampleWindowSize);
128 windowCenterY = sampleWindowSize / 2 + rand() % (height - sampleWindowSize);
130 for (
int j = randomWindowScaleRateFloor; j < randomWindowScaleRateCeil; j++)
133 sampleWindowSize /= j;
134 CByteImage* sampleWindow =
new CByteImage(sampleWindowSize, sampleWindowSize, CByteImage::eGrayScale);
135 CFloatImage* sampleHogImg =
new CFloatImage(sampleWindow->width, sampleWindow->height, 1);
136 CFloatImage* sampleAmplitude =
new CFloatImage(sampleWindow->width, sampleWindow->height, 1);
137 for (
int wIn = windowCenterX - (sampleWindowSize / 2), wOut = 0; wOut < sampleWindowSize; wIn++, wOut++)
139 for (
int hIn = windowCenterY - (sampleWindowSize / 2), hOut = 0; hOut < sampleWindowSize; hIn++, hOut++)
141 sampleWindow->pixels[hOut * sampleWindowSize + wOut] = greyImage->pixels[hIn * width + wIn];
142 sampleHogImg->pixels[hOut * sampleWindowSize + wOut] = hogImg->pixels[hIn * width + wIn];
143 sampleAmplitude->pixels[hOut * sampleWindowSize + wOut] = amplitude->pixels[hIn * width + wIn];
147 std::vector<float> sampleHist(numberOfBins, 0);
148 std::vector<float> sampleHistNorm(numberOfBins, 0);
150 HoG::calculateHist(360, numberOfBins, sampleHogImg, &sampleHist, sampleAmplitude);
151 HoG::histogramNorm(&sampleHist, &sampleHistNorm);
157 bool predict = knn(trainingHistTable, trainingHistTableNegative, sampleHistNorm);
161 for (
int j = -1; j <= 1; j++)
163 for (
int k = -1; k <= 1; k++)
165 saliencyImageOrigin->pixels[width * (windowCenterY + j) + (windowCenterX + k)] = 255;
171 if (useHoughDetector)
176 hough.
openCVHoughSaliency(sampleWindow, saliencyImageOrigin, sampleWindowSize, width, height, windowCenterX, windowCenterY);
183 delete sampleAmplitude;
188 for (
int j = 0; j < 3; j++)
191 ImageProcessor::GaussianSmooth5x5(saliencyImageOrigin, &tempSaliencyImage);
192 ImageProcessor::GaussianSmooth5x5(&tempSaliencyImage, saliencyImageOrigin);
194 ImageProcessor::HistogramStretching(saliencyImageOrigin, &tempSaliencyImage, 0.0, 1.0);
195 ImageProcessor::CopyImage(&tempSaliencyImage, saliencyImageOrigin);
197 for (
int i = 0; i < saliencyImage->width * saliencyImage->height; i++)
199 saliencyImage->pixels[i] = (
float)saliencyImageOrigin->pixels[i] / 255;
207 delete saliencyImageOrigin;
210 bool HoG::hogDescriptor(CByteImage* origin, CFloatImage* outImage, CFloatImage* amplitude)
213 width = origin->width;
214 height = origin->height;
215 CShortImage sobelXImage(width, height);
216 CShortImage sobelYImage(width, height);
219 ImageProcessor::SobelX(origin, &sobelXImage,
false);
220 ImageProcessor::SobelY(origin, &sobelYImage,
false);
222 for (
int i = 0; i < width * height; i++)
226 outImage->pixels[i] = atan2((
float)sobelXImage.pixels[i], (
float)sobelYImage.pixels[i]);
227 outImage->pixels[i] = (outImage->pixels[i] * 180) /
M_PI;
228 if (outImage->pixels[i] < 0)
230 outImage->pixels[i] += 360;
232 amplitude->pixels[i] =
sqrt((
float)sobelXImage.pixels[i] * (
float)sobelXImage.pixels[i] + (
float)sobelYImage.pixels[i] * (
float)sobelYImage.pixels[i]);
237 void HoG::calculateHist(
int range,
int bin, CFloatImage* inputImg, std::vector<float>* output, CFloatImage* amplitude)
241 std::vector<float>::iterator it;
242 binRange = ceil((
float)range / (
float)bin);
244 for (it = output->begin(); it < output->end(); it++)
249 for (
int i = 0; i < inputImg->height * inputImg->width; i++)
251 index = inputImg->pixels[i] / binRange;
252 output->at(
index) = output->at(
index) + amplitude->pixels[i];
256 void HoG::histogramNorm(std::vector<float>*
input, std::vector<float>* normOutput)
259 for (
size_t i = 0; i < normOutput->size(); i++)
261 normOutput->at(i) = 0;
263 for (
size_t i = 0; i <
input->size(); i++)
265 sum = sum +
input->at(i);
267 for (
size_t i = 0; i <
input->size(); i++)
269 normOutput->at(i) =
input->at(i) / sum;
273 bool HoG::knn(std::vector<std::vector<float> > trainingHistTable, std::vector<std::vector<float> > trainingHistTableNegative, std::vector<float> testWindow)
275 float nearstDistance, secondDistance, thirdDistance;
285 std::pair <std::vector<float>*,
int> nearstNeighborPtr, secondNeighborPtr, thirdNeighborPtr;
286 nearstNeighborPtr.second = -1;
287 secondNeighborPtr.second = -1;
288 thirdNeighborPtr.second = -1;
293 findThreeNearstNeighbors(testWindow, trainingHistTable, 1, &nearstNeighborPtr, &secondNeighborPtr, &thirdNeighborPtr, &nearstDistance, &secondDistance, &thirdDistance);
294 findThreeNearstNeighbors(testWindow, trainingHistTableNegative, 0, &nearstNeighborPtr, &secondNeighborPtr, &thirdNeighborPtr, &nearstDistance, &secondDistance, &thirdDistance);
297 sum = thirdNeighborPtr.second + secondNeighborPtr.second + nearstNeighborPtr.second;
302 if (nearstNeighborPtr.second == 1 && secondNeighborPtr.second == 1 && nearstDistance < 0.15)
316 void HoG::preprocess(
const CByteImage* origin, CByteImage* outImage)
318 ImageProcessor::ConvertImage(origin, outImage);
319 for (
int i = 0; i < 4; i++)
321 ImageProcessor::GaussianSmooth5x5(outImage, outImage);
331 float HoG::distanceBetweenPoints(std::vector<float> firstPoint, std::vector<float> secondPoint,
int metrics)
334 float manhattanDistance = 0;
335 float multiplicationSumme = 0;
336 float squareSummeFirst = 0;
337 float squareSummeSecond = 0;
340 if (firstPoint.size() != secondPoint.size())
345 for (
size_t i = 0; i < firstPoint.size(); i++)
347 distance += pow(firstPoint[i] - secondPoint[i], 2);
348 manhattanDistance += fabs(firstPoint[i] - secondPoint[i]);
349 multiplicationSumme += firstPoint[i] * secondPoint[i];
350 squareSummeFirst += pow(firstPoint[i], 2);
351 squareSummeSecond += pow(secondPoint[i], 2);
352 if ((firstPoint[i] + secondPoint[i]) != 0)
354 chiSquare += (firstPoint[i] - secondPoint[i]) * (firstPoint[i] - secondPoint[i]) / (firstPoint[i] + secondPoint[i]);
371 result = manhattanDistance;
375 result = (1 - multiplicationSumme / (
sqrt(squareSummeFirst) *
sqrt(squareSummeSecond)));
389 void HoG::findThreeNearstNeighbors(std::vector<float> testWindow, std::vector<std::vector<float> > trainingHistTable,
int lable, std::pair <std::vector<float>*,
int>* nearstNeighbor, std::pair <std::vector<float>*,
int>* secondNeighbor, std::pair <std::vector<float>*,
int>* thirdNeighbor,
float* nearstDistance,
float* secondDistance,
float* thirdDistance)
392 std::vector<std::vector<float> >::iterator hisIt;
393 for (hisIt = trainingHistTable.begin(); hisIt < trainingHistTable.end(); hisIt++)
395 distance = distanceBetweenPoints(*hisIt, testWindow, 4);
398 else if (
distance < *nearstDistance)
400 *thirdNeighbor = *secondNeighbor;
401 *thirdDistance = *secondDistance;
402 *secondNeighbor = *nearstNeighbor;
403 *secondDistance = *nearstDistance;
405 nearstNeighbor->first = &(*hisIt);
406 nearstNeighbor->second = lable;
410 else if (
distance < *secondDistance)
412 *thirdNeighbor = *secondNeighbor;
413 *thirdDistance = *secondDistance;
415 secondNeighbor->first = &(*hisIt);
416 secondNeighbor->second = lable;
422 thirdNeighbor->first = &(*hisIt);
423 thirdNeighbor->second = lable;
430 void HoG::histogramRotationInvariant(std::vector<float>* inputHist, std::vector<float>* outputHist)
432 std::vector<float> newHistogram;
433 float max = 0, second = 0;
434 for (
size_t i = 0; i < inputHist->size(); i++)
436 if (inputHist->at(i) > inputHist->at(
max))
440 else if (inputHist->at(i) > inputHist->at(second))
450 for (
size_t i =
max; i < inputHist->size(); i++)
452 newHistogram.push_back(inputHist->at(i));
454 for (
int i = 0; i <
max; i++)
456 newHistogram.push_back(inputHist->at(i));
459 for (
size_t i = 0; i < newHistogram.size(); i++)
461 outputHist->at(i) = newHistogram.at(i);
469 useHoughDetector = useHough;
470 useHoGDetector = useHoG;