EquirectangularToFovVideo.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. // EquirectangularToFovVideo.cpp
  2. #include "EquirectangularToFovVideo.h"
  3. #include "Types.h"
  4. #include "Util.h"
  5. #include <iostream>
  6. #include <cstdlib>
  7. #include <algorithm>
  8. #define PI 3.14159265
  9. using namespace std;
  10. // PUBLIC:
  11. EquirectangularToFovVideo::EquirectangularToFovVideo(Arff* pArff) : EquirectangularToFovBase(pArff)
  12. {
  13. }
  14. /*virtual*/ EquirectangularToFovVideo::~EquirectangularToFovVideo()
  15. {
  16. }
  17. bool EquirectangularToFovVideo::Convert(const QImage *eqImage, long int time, QImage *fovImage)
  18. {
  19. double xEqHead, yEqHead, tiltHead;
  20. GetHeadPos(time, &xEqHead, &yEqHead, &tiltHead);
  21. double horHeadRads, verHeadRads;
  22. EquirectangularToSpherical(xEqHead, yEqHead, m_pArff->WidthPx(), m_pArff->HeightPx(), &horHeadRads, &verHeadRads);
  23. Vec3 headVec(0,0,0);
  24. SphericalToCartesian(horHeadRads, verHeadRads, &headVec);
  25. Vec3 vidVec(-1,0,0); // pointing to the middle of equirectangular projection
  26. double headTiltRads = tiltHead * PI / 180;
  27. Matrix33 rot = HeadToVideoRotation(headVec, headTiltRads, vidVec);
  28. double horRads, verRads;
  29. double vidHorRads, vidVerRads;
  30. unsigned int xEq, yEq;
  31. const uchar *eqImageBits = eqImage->bits();
  32. uchar *fovImageBits = fovImage->bits();
  33. GenerateSampling(fovImage);
  34. for (int y=0; y<fovImage->height(); y++)
  35. {
  36. for (int x=0; x<fovImage->width(); x++)
  37. {
  38. horRads = m_vHorSampling[x];
  39. verRads = m_vVerSampling[y];
  40. // make it point towards center of equirectangular projection
  41. horRads += PI;
  42. verRads += PI/2;
  43. Vec3 pixelVec(0,0,0);
  44. SphericalToCartesian(horRads, verRads, &pixelVec);
  45. Vec3 vidPixelVec = RotatePoint(rot, pixelVec);
  46. CartesianToSpherical(vidPixelVec, &vidHorRads, &vidVerRads);
  47. SphericalToEquirectangular(vidHorRads, vidVerRads, eqImage->width(), eqImage->height(), &xEq, &yEq);
  48. //fovImage->setPixel(x, y, eqImage->pixel(xEq, yEq));
  49. int posEq = yEq*eqImage->bytesPerLine() + xEq*4;
  50. int posFov = y*fovImage->bytesPerLine() + x*4;
  51. *(fovImageBits + posFov) = *(eqImageBits + posEq);
  52. *(fovImageBits + posFov + 1) = *(eqImageBits + posEq + 1);
  53. *(fovImageBits + posFov + 2) = *(eqImageBits + posEq + 2);
  54. *(fovImageBits + posFov + 3) = *(eqImageBits + posEq + 3);
  55. }
  56. }
  57. // *** Placeholder
  58. return true;
  59. }
  60. double EquirectangularToFovVideo::GetAspectRatio()
  61. {
  62. return (double)m_fovWidthPx/m_fovHeightPx;
  63. }
  64. // PRIVATE:
  65. void EquirectangularToFovVideo::GenerateSampling(const QImage *image)
  66. {
  67. if ((int)m_vHorSampling.size() == image->width() && (int)m_vVerSampling.size() == image->height())
  68. return;
  69. m_vHorSampling.resize(image->width());
  70. m_vVerSampling.resize(image->height());
  71. double fovWidthRads = (m_fovWidthDeg * PI / 180);
  72. double fovHeightRads = (m_fovHeightDeg * PI / 180);
  73. Generate1DSampling(fovWidthRads, &m_vHorSampling);
  74. Generate1DSampling(fovHeightRads, &m_vVerSampling);
  75. }
  76. void EquirectangularToFovVideo::Generate1DSampling(double fovRads, vector<double> *samples)
  77. {
  78. for (size_t i=0; i<samples->size(); i++)
  79. (*samples)[i] = i * fovRads / samples->size() - fovRads / 2.0;
  80. }