28 #include <Calibration/Calibration.h>
29 #include <Image/ByteImage.h>
30 #include <Image/ImageProcessor.h>
44 void FindLocalMaxima(
const std::vector<Vec3d>& aPoints3D,
const std::vector<Vec2d>& aPointsInImage, std::vector<Vec3d>& aMaxima,
const int nBinSizeInPx, CByteImage* pMaximumnessImage)
48 const int nNumBinsTotal = nNumBinsX * nNumBinsY;
50 float* pAverageZ =
new float[nNumBinsTotal];
52 for (
int i = 0; i < nNumBinsTotal; i++)
57 int* pBinPointCounters =
new int[nNumBinsTotal];
59 for (
int i = 0; i < nNumBinsTotal; i++)
61 pBinPointCounters[i] = 0;
66 for (
int i = 0; i < nNumBinsTotal; i++)
68 Math3d::SetVec(pBinMaxima[i], 0, 0, 0);
71 char* pBinMaximumnessValues =
new char[nNumBinsTotal];
73 for (
int i = 0; i < nNumBinsTotal; i++)
75 pBinMaximumnessValues[i] = 0;
80 int nIndexX, nIndexY, nIndex;
81 const float fBinSizeInv = 1.0f / nBinSizeInPx;
83 for (
size_t i = 0; i < aPoints3D.size(); i++)
85 nIndexX = (int)(aPointsInImage.at(i).x * fBinSizeInv);
86 nIndexY = (int)(aPointsInImage.at(i).y * fBinSizeInv);
87 nIndex = nIndexY * nNumBinsX + nIndexX;
89 if (0 <= nIndex && nIndex < nNumBinsTotal)
91 pAverageZ[nIndex] += aPoints3D.at(i).z;
92 pBinPointCounters[nIndex]++;
94 if (pBinMaxima[nIndex].z < aPoints3D.at(i).z)
96 Math3d::SetVec(pBinMaxima[nIndex], aPoints3D.at(i));
101 for (
int i = 0; i < nNumBinsTotal; i++)
103 if (pBinPointCounters[i] != 0)
105 pAverageZ[i] /= pBinPointCounters[i];
111 float* pBinMaximaTemp =
new float[nNumBinsTotal];
113 for (
int i = 0; i < nNumBinsTotal; i++)
115 pBinMaximaTemp[i] = 0;
120 for (
int i = 1; i < nNumBinsY - 1; i++)
122 for (
int j = 1; j < nNumBinsX - 1; j++)
124 const float z = pAverageZ[i * nNumBinsX + j];
126 int nMaximumnessValue = 0;
128 for (
int k = -1; k <= 1; k++)
130 for (
int l = -1; l <= 1; l++)
132 const float z1 = pAverageZ[(i + k) * nNumBinsX + (j + l)];
134 if ((z > z1 + fMinHeightDifference) && (z1 != 0))
147 pBinMaximaTemp[i * nNumBinsX + j] = pAverageZ[i * nNumBinsX + j];
151 pBinMaximaTemp[i * nNumBinsX + j] = 0;
154 pBinMaximumnessValues[i * nNumBinsX + j] = nMaximumnessValue;
159 for (
int i = 0; i < nNumBinsTotal; i++)
161 if (pBinMaximaTemp[i] != 0)
163 aMaxima.push_back(pBinMaxima[i]);
171 for (
int i = 0; i < nNumBinsY; i++)
173 for (
int j = 0; j < nNumBinsX; j++)
176 const int nValue = 31 * pBinMaximumnessValues[i * nNumBinsX + j];
178 for (
int k = i * nBinSizeInPx; k < (i + 1)*nBinSizeInPx && k <
OLP_IMG_HEIGHT; k++)
180 for (
int l = j * nBinSizeInPx; l < (j + 1)*nBinSizeInPx && l <
OLP_IMG_WIDTH; l++)
189 delete[] pBinPointCounters;
191 delete[] pBinMaximaTemp;
192 delete[] pBinMaximumnessValues;
198 void FindLocalMaxima(
const std::vector<CHypothesisPoint*>& aPoints,
const Mat3d mCameraToWorldRotation,
const Vec3d vCameraToWorldTranslation,
199 const CCalibration* calibration, std::vector<Vec3d>& aMaxima, CByteImage* pMaximumnessImage,
const int nBinSizeInPx)
201 std::vector<Vec3d> aPointsTransformed;
202 aPointsTransformed.resize(aPoints.size());
204 for (
size_t i = 0; i < aPoints.size(); i++)
206 Math3d::MulMatVec(mCameraToWorldRotation, aPoints.at(i)->vPosition, vCameraToWorldTranslation, aPointsTransformed.at(i));
209 std::vector<Vec2d> aPointsInImage;
210 aPointsInImage.resize(aPoints.size());
212 for (
size_t i = 0; i < aPoints.size(); i++)
214 calibration->WorldToImageCoordinates(aPoints.at(i)->vPosition, aPointsInImage.at(i),
false);
218 FindLocalMaxima(aPointsTransformed, aPointsInImage, aMaxima, nBinSizeInPx, pMaximumnessImage1);
220 FindLocalMaxima(aPointsTransformed, aPointsInImage, aMaxima, 2 * nBinSizeInPx, pMaximumnessImage2);
222 FindLocalMaxima(aPointsTransformed, aPointsInImage, aMaxima, 4 * nBinSizeInPx, pMaximumnessImage3);
224 FindLocalMaxima(aPointsTransformed, aPointsInImage, aMaxima, 8 * nBinSizeInPx, pMaximumnessImage4);
228 pMaximumnessImage->pixels[i] = (pMaximumnessImage1->pixels[i] + pMaximumnessImage2->pixels[i] + pMaximumnessImage3->pixels[i] + pMaximumnessImage4->pixels[i]) / 4;
232 for (
int i = 0; i < 10; i++)
234 ImageProcessor::GaussianSmooth3x3(pMaximumnessImage, pMaximumnessImage1);
235 ImageProcessor::GaussianSmooth3x3(pMaximumnessImage1, pMaximumnessImage);
242 Math3d::Transpose(mCameraToWorldRotation, mRotInv);
244 for (
size_t i = 0; i < aMaxima.size(); i++)
246 Math3d::SubtractVecVec(aMaxima.at(i), vCameraToWorldTranslation, vTemp);
247 Math3d::MulMatVec(mRotInv, vTemp, aMaxima.at(i));
276 CByteImage* pSmallerImage =
new CByteImage(nWidth, nHeight, CByteImage::eGrayScale);
277 ImageProcessor::Resize(pGrayImage, pSmallerImage);
279 for (
int i = 0; i < nWidth * nHeight; i++)
281 pTempArray1[i].
r = pSmallerImage->pixels[i];
282 pTempArray1[i].
i = 0;
285 const double fWidthInv = 1.0 / nWidth;
286 const double fHeightInv = 1.0 / nHeight;
288 #pragma omp parallel for
289 for (
int v = 0;
v < nHeight;
v++)
291 for (
int u = 0; u < nWidth; u++)
295 for (
int j = 0; j < nWidth; j++)
302 pTempArray2[
v * nWidth + u].
r = fWidthInv * vSum.
r;
303 pTempArray2[
v * nWidth + u].
i = fWidthInv * vSum.
i;
307 #pragma omp parallel for
308 for (
int u = 0; u < nWidth; u++)
310 for (
int v = 0;
v < nHeight;
v++)
314 for (
int j = 0; j < nHeight; j++)
321 pTempArray1[
v * nWidth + u].
r = fHeightInv * vSum.
r;
322 pTempArray1[
v * nWidth + u].
i = fHeightInv * vSum.
i;
326 for (
int i = 0; i < nWidth * nHeight; i++)
328 pTransformed[i].
r =
sqrt(pTempArray1[i].r * pTempArray1[i].r + pTempArray1[i].i * pTempArray1[i].i);
329 pTransformed[i].
i = atan2(pTempArray1[i].i, pTempArray1[i].r);
335 float fMinPhase = pTransformed[0].
i;
336 float fMaxPhase = pTransformed[0].
i;
338 for (
int i = 0; i < nWidth * nHeight; i++)
340 if (pTransformed[i].r > fMaxAbs)
342 fMaxAbs = pTransformed[i].
r;
345 if (pTransformed[i].i < fMinPhase)
347 fMinPhase = pTransformed[i].
i;
350 if (pTransformed[i].i > fMaxPhase)
352 fMaxPhase = pTransformed[i].
i;
356 const float fMaxAbsInv = 255.0f / logf(fMaxAbs + 1);
357 const float fPhaseDiffInv = 255.0f / (fMaxPhase - fMinPhase);
359 CByteImage* pOutAbs =
new CByteImage(nWidth, nHeight, CByteImage::eGrayScale);
360 CByteImage* pOutPhase =
new CByteImage(nWidth, nHeight, CByteImage::eGrayScale);
362 for (
int i = 0; i < nWidth * nHeight; i++)
364 pOutAbs->pixels[i] = fMaxAbsInv * logf(pTransformed[i].r + 1);
365 pOutPhase->pixels[i] = fPhaseDiffInv * (pTransformed[i].
i - fMinPhase);
372 delete[] pTempArray1;
373 delete[] pTempArray2;
388 for (
int i = 0; i < nWidth * nHeight; i++)
390 pTempArray1[i].
r = pTransformed[i].
r * cosf(pTransformed[i].i);
391 pTempArray1[i].
i = pTransformed[i].
r * sinf(pTransformed[i].i);
396 const double fWidthInv = 1.0 / nWidth;
397 const double fHeightInv = 1.0 / nHeight;
399 #pragma omp parallel for
400 for (
int j = 0; j < nWidth; j++)
402 for (
int i = 0; i < nHeight; i++)
406 for (
int v = 0;
v < nHeight;
v++)
413 pTempArray2[i * nWidth + j].
r = vSum.
r;
414 pTempArray2[i * nWidth + j].
i = vSum.
i;
418 #pragma omp parallel for
419 for (
int i = 0; i < nHeight; i++)
421 for (
int j = 0; j < nWidth; j++)
425 for (
int u = 0; u < nWidth; u++)
432 pTempArray1[i * nWidth + j].
r = vSum.
r;
433 pTempArray1[i * nWidth + j].
i = vSum.
i;
437 CByteImage* pSmallerImage =
new CByteImage(nWidth, nHeight, CByteImage::eGrayScale);
439 for (
int i = 0; i < nWidth * nHeight; i++)
441 pSmallerImage->pixels[i] = (pTempArray1[i].
r < 0) ? 0 : ((pTempArray1[i].r > 255) ? 255 : pTempArray1[i].
r);
445 ImageProcessor::Resize(pSmallerImage, pGrayImage);
448 delete pSmallerImage;
449 delete[] pTempArray1;
450 delete[] pTempArray2;
461 double* pTempArray1 =
new double[nWidth * nHeight];
462 double* pTempArray2 =
new double[nWidth * nHeight];
464 for (
int i = 0; i < nWidth * nHeight; i++)
466 pTempArray1[i] = log(pTransformed[i].r);
470 const double fFactor1 = 0.12;
471 const double fFactor2 = 0.11;
472 const double fFactor3 = 0.11;
474 for (
int i = 1; i < nHeight - 1; i++)
476 for (
int j = 1; j < nWidth - 1; j++)
478 pTempArray2[i * nWidth + j] = fFactor3 * pTempArray1[(i - 1) * nWidth + j - 1] + fFactor2 * pTempArray1[(i - 1) * nWidth + j] + fFactor3 * pTempArray1[(i - 1) * nWidth + j + 1]
479 + fFactor2 * pTempArray1[i * nWidth + j - 1] + fFactor1 * pTempArray1[i * nWidth + j] + fFactor2 * pTempArray1[i * nWidth + j + 1]
480 + fFactor3 * pTempArray1[(i + 1) * nWidth + j - 1] + fFactor2 * pTempArray1[(i + 1) * nWidth + j] + fFactor3 * pTempArray1[(i + 1) * nWidth + j + 1];
485 for (
int i = 0; i < nWidth; i++)
487 pTempArray2[i] = pTempArray1[i];
488 pTempArray2[(nHeight - 1)*nWidth + i] = pTempArray1[(nHeight - 1) * nWidth + i];
491 for (
int i = 0; i < nHeight; i++)
493 pTempArray2[i * nWidth] = pTempArray1[i * nWidth];
494 pTempArray2[i * nWidth + nWidth - 1] = pTempArray1[i * nWidth + nWidth - 1];
498 for (
int i = 0; i < nWidth * nHeight; i++)
500 pTransformed[i].
r = exp(pTempArray1[i] - pTempArray2[i]);
503 delete[] pTempArray1;
504 delete[] pTempArray2;
519 for (
int i = 0; i < 3; i++)
523 pOneColorChannelImage->pixels[j] = pImageRGB->pixels[3 * j + i];
533 pSaliencySum[j] += pOneColorChannelImage->pixels[j] * pOneColorChannelImage->pixels[j];
537 int nMin = pSaliencySum[0], nMax = pSaliencySum[0];
541 if (pSaliencySum[i] < nMin)
543 nMin = pSaliencySum[i];
546 if (pSaliencySum[i] > nMax)
548 nMax = pSaliencySum[i];
552 const double fFactor = 255.0 / (nMax - nMin);
556 pSaliencyImage->pixels[i] = fFactor * (pSaliencySum[i] - nMin);
559 const float fSigma = 3;
560 const int nKernelSize = 4 * fSigma + 2;
561 ImageProcessor::GaussianSmooth(pSaliencyImage, pSaliencyImage, fSigma * fSigma, nKernelSize);
565 delete pOneColorChannelImage;
566 delete[] pSaliencySum;
587 ImageProcessor::CalculateHSVImage(pImageRGB, pImageHSV);
591 const int nNumChannels = 9;
594 #pragma omp parallel for
597 pAllColorChannels[nNumChannels * i] = pImageRGB->pixels[3 * i];
598 pAllColorChannels[nNumChannels * i + 1] = pImageRGB->pixels[3 * i + 1];
599 pAllColorChannels[nNumChannels * i + 2] = pImageRGB->pixels[3 * i + 2];
601 pAllColorChannels[nNumChannels * i + 3] = pImageHSV->pixels[3 * i];
602 pAllColorChannels[nNumChannels * i + 4] = pImageHSV->pixels[3 * i + 1];
603 pAllColorChannels[nNumChannels * i + 5] = pImageHSV->pixels[3 * i + 1];
605 pAllColorChannels[nNumChannels * i + 6] = pImageLab->pixels[3 * i];
606 pAllColorChannels[nNumChannels * i + 7] = pImageLab->pixels[3 * i + 1];
607 pAllColorChannels[nNumChannels * i + 8] = pImageLab->pixels[3 * i + 2];
617 const int nParallelityFactor = omp_get_num_procs();
618 omp_set_num_threads(nParallelityFactor);
619 CByteImage** pOneColorChannelImages =
new CByteImage*[nParallelityFactor];
620 CByteImage** pSmoothedImages =
new CByteImage*[nParallelityFactor];
621 CByteImage** pExtremelySmoothedImages =
new CByteImage*[nParallelityFactor];
623 for (
int i = 0; i < nParallelityFactor; i++)
630 const float fSigma1 = 80;
631 const float fSigma2 = 10;
632 const int nKernelSize1 = 4 * fSigma1 + 1;
633 const int nKernelSize2 = 4 * fSigma2 + 1;
635 #pragma omp parallel for
636 for (
int i = 0; i < nNumChannels; i++)
638 const int nThreadNumber = omp_get_thread_num();
643 pOneColorChannelImages[nThreadNumber]->pixels[j] = pAllColorChannels[nNumChannels * j + i];
649 ImageProcessor::GaussianSmooth(pOneColorChannelImages[nThreadNumber], pExtremelySmoothedImages[nThreadNumber], fSigma1 * fSigma1, nKernelSize1);
651 ImageProcessor::GaussianSmooth(pOneColorChannelImages[nThreadNumber], pSmoothedImages[nThreadNumber], fSigma2 * fSigma2, nKernelSize2);
656 pSaliencySum[j] += (pExtremelySmoothedImages[nThreadNumber]->pixels[j] - pSmoothedImages[nThreadNumber]->pixels[j]) * (pExtremelySmoothedImages[nThreadNumber]->pixels[j] - pSmoothedImages[nThreadNumber]->pixels[j]);
661 #pragma omp parallel for
664 pSaliencySum[j] =
sqrt(pSaliencySum[j]);
669 int nMin = pSaliencySum[0], nMax = pSaliencySum[0];
673 if (pSaliencySum[i] < nMin)
675 nMin = pSaliencySum[i];
678 if (pSaliencySum[i] > nMax)
680 nMax = pSaliencySum[i];
684 const double fFactor = (nMax > nMin) ? 255.0 / (nMax - nMin) : 1.0;
686 #pragma omp parallel for
689 pSaliencyImage->pixels[i] = fFactor * (pSaliencySum[i] - nMin);
698 delete[] pAllColorChannels;
700 for (
int i = 0; i < nParallelityFactor; i++)
702 delete pOneColorChannelImages[i];
703 delete pSmoothedImages[i];
704 delete pExtremelySmoothedImages[i];
707 delete[] pOneColorChannelImages;
708 delete[] pSmoothedImages;
709 delete[] pExtremelySmoothedImages;
720 const double xn = 0.95;
722 const double zn = 1.09;
723 const double dOneThird = 1.0 / 3.0;
727 r = pImageRGB->pixels[3 * i];
728 g = pImageRGB->pixels[3 * i + 1];
729 b = pImageRGB->pixels[3 * i + 2];
730 x = 0.4124564 * r + 0.3575761 * g + 0.1804375 * b;
731 y = 0.2126729 * r + 0.7151522 * g + 0.0721750 * b;
732 z = 0.0193339 * r + 0.1191920 * g + 0.9503041 * b;
733 L = 116 * pow(y / yn, dOneThird) - 16;
734 A = 500 * (pow(x / xn, dOneThird) - pow(y / yn, dOneThird));
735 B = 200 * (pow(y / yn, dOneThird) - pow(z / zn, dOneThird));
736 pImageLab->pixels[3 * i] = L;
737 pImageLab->pixels[3 * i + 1] =
A + 150;
738 pImageLab->pixels[3 * i + 2] = B + 100;