GradientAnisotropic2.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. // David Eberly, Geometric Tools, Redmond WA 98052
  2. // Copyright (c) 1998-2020
  3. // Distributed under the Boost Software License, Version 1.0.
  4. // https://www.boost.org/LICENSE_1_0.txt
  5. // https://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
  6. // Version: 4.0.2020.01.11
  7. #pragma once
  8. #include <Mathematics/PdeFilter2.h>
  9. #include <Mathematics/Math.h>
  10. namespace WwiseGTE
  11. {
  12. template <typename Real>
  13. class GradientAnisotropic2 : public PdeFilter2<Real>
  14. {
  15. public:
  16. GradientAnisotropic2(int xBound, int yBound, Real xSpacing, Real ySpacing,
  17. Real const* data, bool const* mask, Real borderValue,
  18. typename PdeFilter<Real>::ScaleType scaleType, Real K)
  19. :
  20. PdeFilter2<Real>(xBound, yBound, xSpacing, ySpacing, data, mask,
  21. borderValue, scaleType),
  22. mK(K)
  23. {
  24. ComputeParameter();
  25. }
  26. virtual ~GradientAnisotropic2()
  27. {
  28. }
  29. protected:
  30. void ComputeParameter()
  31. {
  32. Real gradMagSqr = (Real)0;
  33. for (int y = 1; y <= this->mYBound; ++y)
  34. {
  35. for (int x = 1; x <= this->mXBound; ++x)
  36. {
  37. Real ux = this->GetUx(x, y);
  38. Real uy = this->GetUy(x, y);
  39. gradMagSqr += ux * ux + uy * uy;
  40. }
  41. }
  42. gradMagSqr /= (Real)this->mQuantity;
  43. mParameter = (Real)1 / (mK * mK * gradMagSqr);
  44. mMHalfParameter = (Real)-0.5 * mParameter;
  45. }
  46. virtual void OnPreUpdate() override
  47. {
  48. ComputeParameter();
  49. }
  50. virtual void OnUpdateSingle(int x, int y) override
  51. {
  52. this->LookUp9(x, y);
  53. // one-sided U-derivative estimates
  54. Real uxFwd = this->mInvDx * (this->mUpz - this->mUzz);
  55. Real uxBwd = this->mInvDx * (this->mUzz - this->mUmz);
  56. Real uyFwd = this->mInvDy * (this->mUzp - this->mUzz);
  57. Real uyBwd = this->mInvDy * (this->mUzz - this->mUzm);
  58. // centered U-derivative estimates
  59. Real uxCenM = this->mHalfInvDx * (this->mUpm - this->mUmm);
  60. Real uxCenZ = this->mHalfInvDx * (this->mUpz - this->mUmz);
  61. Real uxCenP = this->mHalfInvDx * (this->mUpp - this->mUmp);
  62. Real uyCenM = this->mHalfInvDy * (this->mUmp - this->mUmm);
  63. Real uyCenZ = this->mHalfInvDy * (this->mUzp - this->mUzm);
  64. Real uyCenP = this->mHalfInvDy * (this->mUpp - this->mUpm);
  65. Real uxCenZSqr = uxCenZ * uxCenZ;
  66. Real uyCenZSqr = uyCenZ * uyCenZ;
  67. Real gradMagSqr;
  68. // estimate for C(x+1,y)
  69. Real uyEstP = (Real)0.5 * (uyCenZ + uyCenP);
  70. gradMagSqr = uxCenZSqr + uyEstP * uyEstP;
  71. Real cxp = std::exp(mMHalfParameter * gradMagSqr);
  72. // estimate for C(x-1,y)
  73. Real uyEstM = (Real)0.5 * (uyCenZ + uyCenM);
  74. gradMagSqr = uxCenZSqr + uyEstM * uyEstM;
  75. Real cxm = std::exp(mMHalfParameter * gradMagSqr);
  76. // estimate for C(x,y+1)
  77. Real uxEstP = (Real)0.5 * (uxCenZ + uxCenP);
  78. gradMagSqr = uyCenZSqr + uxEstP * uxEstP;
  79. Real cyp = std::exp(mMHalfParameter * gradMagSqr);
  80. // estimate for C(x,y-1)
  81. Real uxEstM = (Real)0.5 * (uxCenZ + uxCenM);
  82. gradMagSqr = uyCenZSqr + uxEstM * uxEstM;
  83. Real cym = std::exp(mMHalfParameter * gradMagSqr);
  84. this->mBuffer[this->mDst][y][x] = this->mUzz + this->mTimeStep * (
  85. cxp * uxFwd - cxm * uxBwd +
  86. cyp * uyFwd - cym * uyBwd);
  87. }
  88. // These are updated on each iteration, since they depend on the
  89. // current average of the squared length of the gradients at the
  90. // pixels.
  91. Real mK; // k
  92. Real mParameter; // 1/(k^2*average(gradMagSqr))
  93. Real mMHalfParameter; // -0.5*mParameter
  94. };
  95. }