//-------------------------------------------------------------------------------------- // Name: GetSampleOffsets_Star() // Desc: Get the texcoord offsets to be used inside the Star pixel shader. //-------------------------------------------------------------------------------------- VOID PostProcess::GetSampleOffsets_Star( DWORD dwTexSize, XMVECTOR* pvTexCoordOffsets, XMVECTOR* pvColorWeights, FLOAT fDeviation ) { FLOAT tu = 1.0f / ( FLOAT )dwTexSize; // Fill the center texel FLOAT fWeight = 1.0f * GaussianDistribution( 0, 0, fDeviation ); pvColorWeights[0] = XMVectorSet( fWeight, fWeight, fWeight, 1.0f ); pvTexCoordOffsets[0] = XMVectorSet( 0.0f, 0.0f, 0.0f, 0.0f ); // Fill the first half for( DWORD i = 1; i < 8; i++ ) { // Get the Gaussian intensity for this offset fWeight = 1.0f * GaussianDistribution( ( FLOAT )i, 0, fDeviation ); pvColorWeights[i] = XMVectorSet( fWeight, fWeight, fWeight, 1.0f ); pvTexCoordOffsets[i] = XMVectorSet( i * tu, 0.0f, 0.0f, 0.0f ); } // Mirror to the second half for( DWORD i = 8; i < 15; i++ ) { pvColorWeights[i] = pvColorWeights[i - 7]; pvTexCoordOffsets[i] = -pvTexCoordOffsets[i - 7]; } }
HRESULT GetSampleOffsets_Bloom_D3D11( DWORD dwD3DTexSize, float afTexCoordOffset[15], XMFLOAT4* avColorWeight, float fDeviation, float fMultiplier ) { int i = 0; float tu = 1.0f / ( float )dwD3DTexSize; // Fill the center texel float weight = 1.0f * GaussianDistribution( 0, 0, fDeviation ); avColorWeight[7] = XMFLOAT4( weight, weight, weight, 1.0f ); afTexCoordOffset[7] = 0.0f; // Fill one side for( i = 1; i < 8; i++ ) { weight = fMultiplier * GaussianDistribution( ( float )i, 0, fDeviation ); afTexCoordOffset[7-i] = -i * tu; avColorWeight[7-i] = XMFLOAT4( weight, weight, weight, 1.0f ); } // Copy to the other side for( i = 8; i < 15; i++ ) { avColorWeight[i] = avColorWeight[14 - i]; afTexCoordOffset[i] = -afTexCoordOffset[14 - i]; } return S_OK; }
//-------------------------------------------------------------------------------------- // Name: GetSampleOffsets_Bloom() // Desc: Get the texcoord offsets to be used inside the Bloom pixel shader. //-------------------------------------------------------------------------------------- VOID PostProcess::GetSampleOffsets_Bloom( DWORD dwTextureWidth, DWORD dwTextureHeight, FLOAT fAngle, XMVECTOR* pvTexCoordOffsets, XMVECTOR* pvColorWeights, FLOAT fDeviation, FLOAT fMultiplier ) { FLOAT tu = cosf( fAngle ) / ( FLOAT )dwTextureWidth; FLOAT tv = sinf( fAngle ) / ( FLOAT )dwTextureHeight; // Fill the center texel FLOAT fWeight = fMultiplier * GaussianDistribution( 0, 0, fDeviation ); pvColorWeights[0] = XMVectorSet( fWeight, fWeight, fWeight, 1.0f ); pvTexCoordOffsets[0] = XMVectorSet( 0.0f, 0.0f, 0.0f, 0.0f ); // Fill the first half for( DWORD i = 1; i < 8; i++ ) { // Get the Gaussian intensity for this offset fWeight = fMultiplier * GaussianDistribution( ( FLOAT )i, 0, fDeviation ); pvColorWeights[i] = XMVectorSet( fWeight, fWeight, fWeight, 1.0f ); pvTexCoordOffsets[i] = XMVectorSet( i * tu, i * tv, 0.0f, 0.0f ); } // Mirror to the second half for( DWORD i = 8; i < 15; i++ ) { pvColorWeights[i] = pvColorWeights[i - 7]; pvTexCoordOffsets[i] = -pvTexCoordOffsets[i - 7]; } }
bool HDR_Pipeline::getSampleOffsets_Star (unsigned texSize, float texCoordOffset[15], ATOM_Vector4f *colorWeight, float deviation) { int i = 0; float tu = 1.0f / ( float )texSize; // Fill the center texel float weight = 1.0f * GaussianDistribution( 0, 0, deviation ); colorWeight[0].set( weight, weight, weight, 1.0f ); texCoordOffset[0] = 0.0f; // Fill the first half for( i = 1; i < 8; i++ ) { // Get the Gaussian intensity for this offset weight = 1.0f * GaussianDistribution( ( float )i, 0, deviation ); texCoordOffset[i] = i * tu; colorWeight[i].set( weight, weight, weight, 1.0f ); } // Mirror to the second half for( i = 8; i < 15; i++ ) { colorWeight[i] = colorWeight[i - 7]; texCoordOffset[i] = -texCoordOffset[i - 7]; } return true; }
/** * Create a Conditional Gaussian distribution with conditional mean function * obtained by running RegressionFunction on predictors, responses. * * @param predictors Matrix of predictors (X). * @param responses Vector of responses (y). */ RegressionDistribution(const arma::mat& predictors, const arma::vec& responses) : rf(regression::LinearRegression(predictors, responses)) { err = GaussianDistribution(1); arma::mat cov(1, 1); cov(0, 0) = rf.ComputeError(predictors, responses); err.Covariance(std::move(cov)); }
//-------------------------------------------------------------------------------------- // Name: GetSampleOffsets_GaussBlur5x5() // Desc: Get the texcoord offsets to be used inside the GaussBlur5x5 pixel shader. //-------------------------------------------------------------------------------------- VOID PostProcess::GetSampleOffsets_GaussBlur5x5( DWORD dwTexWidth, DWORD dwTexHeight, XMVECTOR* pvTexCoordOffsets, XMVECTOR* pvSampleWeights, FLOAT fMultiplier ) { FLOAT tu = 1.0f / ( FLOAT )dwTexWidth; FLOAT tv = 1.0f / ( FLOAT )dwTexHeight; XMVECTOR vWhite = XMVectorSet( 1.0f, 1.0f, 1.0f, 1.0f ); FLOAT fTotalWeight = 0.0f; DWORD index = 0; for( int x = -2; x <= 2; x++ ) { for( int y = -2; y <= 2; y++ ) { // Exclude pixels with a block distance greater than 2. This will // create a kernel which approximates a 5x5 kernel using only 13 // sample points instead of 25; this is necessary since 2.0 shaders // only support 16 texture grabs. if( fabs( ( FLOAT )x ) + fabs( ( FLOAT )y ) > 2.0f ) continue; // Get the unscaled Gaussian intensity for this offset pvTexCoordOffsets[index].x = ( FLOAT )x * tu; pvTexCoordOffsets[index].y = ( FLOAT )y * tv; pvTexCoordOffsets[index].z = 0.0f; pvTexCoordOffsets[index].w = 0.0f; pvSampleWeights[index] = vWhite * GaussianDistribution( ( FLOAT )x, ( FLOAT )y, 1.0f ); fTotalWeight += pvSampleWeights[index].x; index++; } } // Divide the current weight by the total weight of all the samples; Gaussian // blur kernels add to 1.0f to ensure that the intensity of the image isn't // changed when the blur occurs. An optional multiplier variable is used to // add or remove image intensity during the blur. for( DWORD i = 0; i < index; i++ ) { pvSampleWeights[i] /= fTotalWeight; pvSampleWeights[i] *= fMultiplier; } }
bool HDR_Pipeline::getSampleOffsets_GaussBlur5x5 (unsigned texWidth, unsigned texHeight, ATOM_Vector2f *texCoordOffset, ATOM_Vector4f *sampleWeight, float multiplier) { float tu = 1.0f / ( float )texWidth; float tv = 1.0f / ( float )texHeight; ATOM_Vector4f vWhite( 1.0f, 1.0f, 1.0f, 1.0f ); float totalWeight = 0.0f; int index = 0; for( int x = -2; x <= 2; x++ ) { for( int y = -2; y <= 2; y++ ) { // Exclude pixels with a block distance greater than 2. This will // create a kernel which approximates a 5x5 kernel using only 13 // sample points instead of 25; this is necessary since 2.0 shaders // only support 16 texture grabs. if( ATOM_abs( x ) + abs( y ) > 2 ) continue; // Get the unscaled Gaussian intensity for this offset texCoordOffset[index] = ATOM_Vector2f( x * tu, y * tv ); sampleWeight[index] = vWhite * GaussianDistribution( ( float )x, ( float )y, 1.0f ); totalWeight += sampleWeight[index].x; index++; } } // Divide the current weight by the total weight of all the samples; Gaussian // blur kernels add to 1.0f to ensure that the intensity of the image isn't // changed when the blur occurs. An optional multiplier variable is used to // add or remove image intensity during the blur. for( int i = 0; i < index; i++ ) { sampleWeight[i] /= totalWeight; sampleWeight[i] *= multiplier; } return true; }
vector<GaussianDistribution> EMGaussianClustering(vector<Feature>& points, int K, int maxIter, float tolerance) { if (K >= points.size()) { vector<GaussianDistribution> dist(points.size()); for (int i = 0; i < points.size(); ++i) { dist[i].mu = points[i]; vector<Feature> f(1, points[i]); dist[i].sgm = Covariance::computeCovariance(f); } return dist; } int N = points[0].length(); Feature zero(N); //initialize the Gaussian distributions from K-means vector<Feature> centers = KmeansClustering(points, K, tolerance); //use K-means for initialization K = centers.size(); Feature zero2(K); vector<int> labels(points.size()); for (int i = 0; i < points.size(); ++i) { labels[i] = selectKmeansCluster(points[i], centers); } vector<GaussianDistribution> dist(centers.size()); for (int i = 0; i < centers.size(); ++i) { vector<Feature> x; for (int j = 0; j < labels.size(); ++j) { if (labels[j] == i) { x.push_back(points[j]); } } dist[i] = GaussianDistribution(x); } int iter = 0; while (true) { iter++; if (iter >= maxIter) { //printf("EMGaussian: Maximum iteration reached before convergence.\n"); break; } //E-step: compute the weights vector<Feature> w(points.size(), zero2); for (int i = 0; i < points.size(); ++i) { float sum = 0; for (int j = 0; j < K; ++j) { float pval = dist[j].eval(points[i]); w[i].vals[j] = pval; sum += pval; } for (int j = 0; j < K; ++j) { w[i].vals[j] /= sum; } } //M-step: //Compute the means vector<GaussianDistribution> dist2(K); vector<float> vsum(K); for (int i = 0; i < K; ++i) { Feature m = zero; float sum = 0; for (int j = 0; j < points.size(); ++j) { for (int k = 0; k < m.length(); ++k) { m.vals[k] += w[j].vals[i] * points[j].vals[k]; } sum += w[j].vals[i]; } for (int k = 0; k < m.length(); ++k) { m.vals[k] /= sum; } dist2[i].mu = m; vsum[i] = sum; } //Compute the covariances for (int i = 0; i < K; ++i) { techsoft::matrix<float> cov(N, N, 0.0f); techsoft::matrix<float> m = Feature::toColumnVector(dist2[i].mu); float sum = 0; for (int j = 0; j < points.size(); ++j) { techsoft::matrix<float> df(N, 1); for (int k = 0; k < N; ++k) { df(k,0) = points[j].vals[k] - m(k, 0); } cov = cov + w[j].vals[i] * (df * (~df)); } cov /= vsum[i]; dist2[i].sgm = Covariance(K); dist2[i].sgm.mat = cov; dist2[i].sgm.imat = !cov; } dist = dist2; } return dist; }