28 #include <Calibration/Calibration.h>
29 #include <Image/ByteImage.h>
30 #include <Image/ImageProcessor.h>
44 const std::vector<Vec2d>& aPointsInImage,
45 std::vector<Vec3d>& aMaxima,
46 const int nBinSizeInPx,
47 CByteImage* pMaximumnessImage)
51 const int nNumBinsTotal = nNumBinsX * nNumBinsY;
53 float* pAverageZ =
new float[nNumBinsTotal];
55 for (
int i = 0; i < nNumBinsTotal; i++)
60 int* pBinPointCounters =
new int[nNumBinsTotal];
62 for (
int i = 0; i < nNumBinsTotal; i++)
64 pBinPointCounters[i] = 0;
69 for (
int i = 0; i < nNumBinsTotal; i++)
71 Math3d::SetVec(pBinMaxima[i], 0, 0, 0);
74 char* pBinMaximumnessValues =
new char[nNumBinsTotal];
76 for (
int i = 0; i < nNumBinsTotal; i++)
78 pBinMaximumnessValues[i] = 0;
83 int nIndexX, nIndexY, nIndex;
84 const float fBinSizeInv = 1.0f / nBinSizeInPx;
86 for (
size_t i = 0; i < aPoints3D.size(); i++)
88 nIndexX = (int)(aPointsInImage.at(i).x * fBinSizeInv);
89 nIndexY = (int)(aPointsInImage.at(i).y * fBinSizeInv);
90 nIndex = nIndexY * nNumBinsX + nIndexX;
92 if (0 <= nIndex && nIndex < nNumBinsTotal)
94 pAverageZ[nIndex] += aPoints3D.at(i).z;
95 pBinPointCounters[nIndex]++;
97 if (pBinMaxima[nIndex].z < aPoints3D.at(i).z)
99 Math3d::SetVec(pBinMaxima[nIndex], aPoints3D.at(i));
104 for (
int i = 0; i < nNumBinsTotal; i++)
106 if (pBinPointCounters[i] != 0)
108 pAverageZ[i] /= pBinPointCounters[i];
114 float* pBinMaximaTemp =
new float[nNumBinsTotal];
116 for (
int i = 0; i < nNumBinsTotal; i++)
118 pBinMaximaTemp[i] = 0;
121 const float fMinHeightDifference =
124 for (
int i = 1; i < nNumBinsY - 1; i++)
126 for (
int j = 1; j < nNumBinsX - 1; j++)
128 const float z = pAverageZ[i * nNumBinsX + j];
130 int nMaximumnessValue = 0;
132 for (
int k = -1; k <= 1; k++)
134 for (
int l = -1; l <= 1; l++)
136 const float z1 = pAverageZ[(i + k) * nNumBinsX + (j + l)];
138 if ((z > z1 + fMinHeightDifference) && (z1 != 0))
151 pBinMaximaTemp[i * nNumBinsX + j] = pAverageZ[i * nNumBinsX + j];
155 pBinMaximaTemp[i * nNumBinsX + j] = 0;
158 pBinMaximumnessValues[i * nNumBinsX + j] = nMaximumnessValue;
163 for (
int i = 0; i < nNumBinsTotal; i++)
165 if (pBinMaximaTemp[i] != 0)
167 aMaxima.push_back(pBinMaxima[i]);
175 for (
int i = 0; i < nNumBinsY; i++)
177 for (
int j = 0; j < nNumBinsX; j++)
180 const int nValue = 31 * pBinMaximumnessValues[i * nNumBinsX + j];
182 for (
int k = i * nBinSizeInPx; k < (i + 1) * nBinSizeInPx && k <
OLP_IMG_HEIGHT;
185 for (
int l = j * nBinSizeInPx; l < (j + 1) * nBinSizeInPx && l <
OLP_IMG_WIDTH;
195 delete[] pBinPointCounters;
197 delete[] pBinMaximaTemp;
198 delete[] pBinMaximumnessValues;
203 const Mat3d mCameraToWorldRotation,
204 const Vec3d vCameraToWorldTranslation,
205 const CCalibration* calibration,
206 std::vector<Vec3d>& aMaxima,
207 CByteImage* pMaximumnessImage,
208 const int nBinSizeInPx)
210 std::vector<Vec3d> aPointsTransformed;
211 aPointsTransformed.resize(aPoints.size());
213 for (
size_t i = 0; i < aPoints.size(); i++)
215 Math3d::MulMatVec(mCameraToWorldRotation,
216 aPoints.at(i)->vPosition,
217 vCameraToWorldTranslation,
218 aPointsTransformed.at(i));
221 std::vector<Vec2d> aPointsInImage;
222 aPointsInImage.resize(aPoints.size());
224 for (
size_t i = 0; i < aPoints.size(); i++)
226 calibration->WorldToImageCoordinates(
227 aPoints.at(i)->vPosition, aPointsInImage.at(i),
false);
230 CByteImage* pMaximumnessImage1 =
233 aPointsTransformed, aPointsInImage, aMaxima, nBinSizeInPx, pMaximumnessImage1);
234 CByteImage* pMaximumnessImage2 =
237 aPointsTransformed, aPointsInImage, aMaxima, 2 * nBinSizeInPx, pMaximumnessImage2);
238 CByteImage* pMaximumnessImage3 =
241 aPointsTransformed, aPointsInImage, aMaxima, 4 * nBinSizeInPx, pMaximumnessImage3);
242 CByteImage* pMaximumnessImage4 =
245 aPointsTransformed, aPointsInImage, aMaxima, 8 * nBinSizeInPx, pMaximumnessImage4);
249 pMaximumnessImage->pixels[i] =
250 (pMaximumnessImage1->pixels[i] + pMaximumnessImage2->pixels[i] +
251 pMaximumnessImage3->pixels[i] + pMaximumnessImage4->pixels[i]) /
256 for (
int i = 0; i < 10; i++)
258 ImageProcessor::GaussianSmooth3x3(pMaximumnessImage, pMaximumnessImage1);
259 ImageProcessor::GaussianSmooth3x3(pMaximumnessImage1, pMaximumnessImage);
266 Math3d::Transpose(mCameraToWorldRotation, mRotInv);
268 for (
size_t i = 0; i < aMaxima.size(); i++)
270 Math3d::SubtractVecVec(aMaxima.at(i), vCameraToWorldTranslation, vTemp);
271 Math3d::MulMatVec(mRotInv, vTemp, aMaxima.at(i));
298 CByteImage* pSmallerImage =
new CByteImage(nWidth, nHeight, CByteImage::eGrayScale);
299 ImageProcessor::Resize(pGrayImage, pSmallerImage);
301 for (
int i = 0; i < nWidth * nHeight; i++)
303 pTempArray1[i].
r = pSmallerImage->pixels[i];
304 pTempArray1[i].
i = 0;
307 const double fWidthInv = 1.0 / nWidth;
308 const double fHeightInv = 1.0 / nHeight;
310 #pragma omp parallel for
311 for (
int v = 0;
v < nHeight;
v++)
313 for (
int u = 0; u < nWidth; u++)
317 for (
int j = 0; j < nWidth; j++)
319 vTemp =
MultCompl(pTempArray1[
v * nWidth + j],
325 pTempArray2[
v * nWidth + u].
r = fWidthInv * vSum.
r;
326 pTempArray2[
v * nWidth + u].
i = fWidthInv * vSum.
i;
330 #pragma omp parallel for
331 for (
int u = 0; u < nWidth; u++)
333 for (
int v = 0;
v < nHeight;
v++)
337 for (
int j = 0; j < nHeight; j++)
339 vTemp =
MultCompl(pTempArray2[j * nWidth + u],
345 pTempArray1[
v * nWidth + u].
r = fHeightInv * vSum.
r;
346 pTempArray1[
v * nWidth + u].
i = fHeightInv * vSum.
i;
350 for (
int i = 0; i < nWidth * nHeight; i++)
353 sqrt(pTempArray1[i].r * pTempArray1[i].r + pTempArray1[i].i * pTempArray1[i].i);
354 pTransformed[i].
i = atan2(pTempArray1[i].i, pTempArray1[i].r);
360 float fMinPhase = pTransformed[0].
i;
361 float fMaxPhase = pTransformed[0].
i;
363 for (
int i = 0; i < nWidth * nHeight; i++)
365 if (pTransformed[i].r > fMaxAbs)
367 fMaxAbs = pTransformed[i].
r;
370 if (pTransformed[i].i < fMinPhase)
372 fMinPhase = pTransformed[i].
i;
375 if (pTransformed[i].i > fMaxPhase)
377 fMaxPhase = pTransformed[i].
i;
381 const float fMaxAbsInv = 255.0f / logf(fMaxAbs + 1);
382 const float fPhaseDiffInv = 255.0f / (fMaxPhase - fMinPhase);
384 CByteImage* pOutAbs =
new CByteImage(nWidth, nHeight, CByteImage::eGrayScale);
385 CByteImage* pOutPhase =
new CByteImage(nWidth, nHeight, CByteImage::eGrayScale);
387 for (
int i = 0; i < nWidth * nHeight; i++)
389 pOutAbs->pixels[i] = fMaxAbsInv * logf(pTransformed[i].r + 1);
390 pOutPhase->pixels[i] = fPhaseDiffInv * (pTransformed[i].
i - fMinPhase);
397 delete[] pTempArray1;
398 delete[] pTempArray2;
412 for (
int i = 0; i < nWidth * nHeight; i++)
414 pTempArray1[i].
r = pTransformed[i].
r * cosf(pTransformed[i].i);
415 pTempArray1[i].
i = pTransformed[i].
r * sinf(pTransformed[i].i);
420 const double fWidthInv = 1.0 / nWidth;
421 const double fHeightInv = 1.0 / nHeight;
423 #pragma omp parallel for
424 for (
int j = 0; j < nWidth; j++)
426 for (
int i = 0; i < nHeight; i++)
430 for (
int v = 0;
v < nHeight;
v++)
432 vTemp =
MultCompl(pTempArray1[
v * nWidth + j],
438 pTempArray2[i * nWidth + j].
r = vSum.
r;
439 pTempArray2[i * nWidth + j].
i = vSum.
i;
443 #pragma omp parallel for
444 for (
int i = 0; i < nHeight; i++)
446 for (
int j = 0; j < nWidth; j++)
450 for (
int u = 0; u < nWidth; u++)
452 vTemp =
MultCompl(pTempArray2[i * nWidth + u],
458 pTempArray1[i * nWidth + j].
r = vSum.
r;
459 pTempArray1[i * nWidth + j].
i = vSum.
i;
463 CByteImage* pSmallerImage =
new CByteImage(nWidth, nHeight, CByteImage::eGrayScale);
465 for (
int i = 0; i < nWidth * nHeight; i++)
467 pSmallerImage->pixels[i] =
468 (pTempArray1[i].
r < 0) ? 0 : ((pTempArray1[i].r > 255) ? 255 : pTempArray1[i].
r);
472 ImageProcessor::Resize(pSmallerImage, pGrayImage);
475 delete pSmallerImage;
476 delete[] pTempArray1;
477 delete[] pTempArray2;
486 double* pTempArray1 =
new double[nWidth * nHeight];
487 double* pTempArray2 =
new double[nWidth * nHeight];
489 for (
int i = 0; i < nWidth * nHeight; i++)
491 pTempArray1[i] = log(pTransformed[i].r);
495 const double fFactor1 = 0.12;
496 const double fFactor2 = 0.11;
497 const double fFactor3 = 0.11;
499 for (
int i = 1; i < nHeight - 1; i++)
501 for (
int j = 1; j < nWidth - 1; j++)
503 pTempArray2[i * nWidth + j] = fFactor3 * pTempArray1[(i - 1) * nWidth + j - 1] +
504 fFactor2 * pTempArray1[(i - 1) * nWidth + j] +
505 fFactor3 * pTempArray1[(i - 1) * nWidth + j + 1] +
506 fFactor2 * pTempArray1[i * nWidth + j - 1] +
507 fFactor1 * pTempArray1[i * nWidth + j] +
508 fFactor2 * pTempArray1[i * nWidth + j + 1] +
509 fFactor3 * pTempArray1[(i + 1) * nWidth + j - 1] +
510 fFactor2 * pTempArray1[(i + 1) * nWidth + j] +
511 fFactor3 * pTempArray1[(i + 1) * nWidth + j + 1];
516 for (
int i = 0; i < nWidth; i++)
518 pTempArray2[i] = pTempArray1[i];
519 pTempArray2[(nHeight - 1) * nWidth + i] = pTempArray1[(nHeight - 1) * nWidth + i];
522 for (
int i = 0; i < nHeight; i++)
524 pTempArray2[i * nWidth] = pTempArray1[i * nWidth];
525 pTempArray2[i * nWidth + nWidth - 1] = pTempArray1[i * nWidth + nWidth - 1];
529 for (
int i = 0; i < nWidth * nHeight; i++)
531 pTransformed[i].
r = exp(pTempArray1[i] - pTempArray2[i]);
534 delete[] pTempArray1;
535 delete[] pTempArray2;
541 CByteImage* pOneColorChannelImage =
550 for (
int i = 0; i < 3; i++)
554 pOneColorChannelImage->pixels[j] = pImageRGB->pixels[3 * j + i];
565 pOneColorChannelImage->pixels[j] * pOneColorChannelImage->pixels[j];
569 int nMin = pSaliencySum[0], nMax = pSaliencySum[0];
573 if (pSaliencySum[i] < nMin)
575 nMin = pSaliencySum[i];
578 if (pSaliencySum[i] > nMax)
580 nMax = pSaliencySum[i];
584 const double fFactor = 255.0 / (nMax - nMin);
588 pSaliencyImage->pixels[i] = fFactor * (pSaliencySum[i] - nMin);
591 const float fSigma = 3;
592 const int nKernelSize = 4 * fSigma + 2;
593 ImageProcessor::GaussianSmooth(
594 pSaliencyImage, pSaliencyImage, fSigma * fSigma, nKernelSize);
598 delete pOneColorChannelImage;
599 delete[] pSaliencySum;
617 ImageProcessor::CalculateHSVImage(pImageRGB, pImageHSV);
621 const int nNumChannels = 9;
624 #pragma omp parallel for
627 pAllColorChannels[nNumChannels * i] = pImageRGB->pixels[3 * i];
628 pAllColorChannels[nNumChannels * i + 1] = pImageRGB->pixels[3 * i + 1];
629 pAllColorChannels[nNumChannels * i + 2] = pImageRGB->pixels[3 * i + 2];
631 pAllColorChannels[nNumChannels * i + 3] = pImageHSV->pixels[3 * i];
632 pAllColorChannels[nNumChannels * i + 4] = pImageHSV->pixels[3 * i + 1];
633 pAllColorChannels[nNumChannels * i + 5] = pImageHSV->pixels[3 * i + 1];
635 pAllColorChannels[nNumChannels * i + 6] = pImageLab->pixels[3 * i];
636 pAllColorChannels[nNumChannels * i + 7] = pImageLab->pixels[3 * i + 1];
637 pAllColorChannels[nNumChannels * i + 8] = pImageLab->pixels[3 * i + 2];
647 const int nParallelityFactor = omp_get_num_procs();
648 omp_set_num_threads(nParallelityFactor);
649 CByteImage** pOneColorChannelImages =
new CByteImage*[nParallelityFactor];
650 CByteImage** pSmoothedImages =
new CByteImage*[nParallelityFactor];
651 CByteImage** pExtremelySmoothedImages =
new CByteImage*[nParallelityFactor];
653 for (
int i = 0; i < nParallelityFactor; i++)
655 pOneColorChannelImages[i] =
659 pExtremelySmoothedImages[i] =
663 const float fSigma1 = 80;
664 const float fSigma2 = 10;
665 const int nKernelSize1 = 4 * fSigma1 + 1;
666 const int nKernelSize2 = 4 * fSigma2 + 1;
668 #pragma omp parallel for
669 for (
int i = 0; i < nNumChannels; i++)
671 const int nThreadNumber = omp_get_thread_num();
676 pOneColorChannelImages[nThreadNumber]->pixels[j] =
677 pAllColorChannels[nNumChannels * j + i];
683 ImageProcessor::GaussianSmooth(pOneColorChannelImages[nThreadNumber],
684 pExtremelySmoothedImages[nThreadNumber],
688 ImageProcessor::GaussianSmooth(pOneColorChannelImages[nThreadNumber],
689 pSmoothedImages[nThreadNumber],
696 pSaliencySum[j] += (pExtremelySmoothedImages[nThreadNumber]->pixels[j] -
697 pSmoothedImages[nThreadNumber]->pixels[j]) *
698 (pExtremelySmoothedImages[nThreadNumber]->pixels[j] -
699 pSmoothedImages[nThreadNumber]->pixels[j]);
704 #pragma omp parallel for
707 pSaliencySum[j] =
sqrt(pSaliencySum[j]);
712 int nMin = pSaliencySum[0], nMax = pSaliencySum[0];
716 if (pSaliencySum[i] < nMin)
718 nMin = pSaliencySum[i];
721 if (pSaliencySum[i] > nMax)
723 nMax = pSaliencySum[i];
727 const double fFactor = (nMax > nMin) ? 255.0 / (nMax - nMin) : 1.0;
729 #pragma omp parallel for
732 pSaliencyImage->pixels[i] = fFactor * (pSaliencySum[i] - nMin);
741 delete[] pAllColorChannels;
743 for (
int i = 0; i < nParallelityFactor; i++)
745 delete pOneColorChannelImages[i];
746 delete pSmoothedImages[i];
747 delete pExtremelySmoothedImages[i];
750 delete[] pOneColorChannelImages;
751 delete[] pSmoothedImages;
752 delete[] pExtremelySmoothedImages;
761 const double xn = 0.95;
763 const double zn = 1.09;
764 const double dOneThird = 1.0 / 3.0;
768 r = pImageRGB->pixels[3 * i];
769 g = pImageRGB->pixels[3 * i + 1];
770 b = pImageRGB->pixels[3 * i + 2];
771 x = 0.4124564 * r + 0.3575761 * g + 0.1804375 * b;
772 y = 0.2126729 * r + 0.7151522 * g + 0.0721750 * b;
773 z = 0.0193339 * r + 0.1191920 * g + 0.9503041 * b;
774 L = 116 * pow(y / yn, dOneThird) - 16;
775 A = 500 * (pow(x / xn, dOneThird) - pow(y / yn, dOneThird));
776 B = 200 * (pow(y / yn, dOneThird) - pow(z / zn, dOneThird));
777 pImageLab->pixels[3 * i] = L;
778 pImageLab->pixels[3 * i + 1] =
A + 150;
779 pImageLab->pixels[3 * i + 2] = B + 100;