void Gaussian::display1d(void) { double i; glColor3f(1.0,1.0,1.0); glBegin(GL_LINE_STRIP); for(i=-3.0*sigma; i<3.0*sigma; i+=0.1) { glVertex3f(i, gaussian1d(i), 0); } glEnd(); glBegin(GL_POINTS); for(i=-3.0*sigma; i<3.0*sigma; i+=0.1) { glVertex3f(i, gaussian1d(i), 0); } glEnd(); glColor3f(0.0,1.0,0.0); glBegin(GL_LINES); glVertex3f(-3.0*sigma, 0, 0); glVertex3f(3.0*sigma, 0, 0); glEnd(); }
void CPUbilateralFiltering(RGB* data, int width, int height,int radius, float sigma_spatial, float sigma_range) { int numElements = width*height; RGB* res_data = (RGB *)malloc (sizeof(RGB) * width * height); for(int x = 0; x < width; x++) { for(int y = 0; y < height; y++) { int array_idx = y * width + x; RGB currentColor = data[array_idx]; //idx RGB res = makeColor(0.0f,0.0f,0.0f); RGB normalization = makeColor(0.0f,0.0f,0.0f); for(int i = -radius; i <= radius; i++) { for(int j = -radius; j <= radius; j++) { int x_sample = x+i; int y_sample = y+j; //mirror edges if( (x_sample < 0) || (x_sample >= width ) ) { x_sample = x-i; } if( (y_sample < 0) || (y_sample >= height) ) { y_sample = y-j; } RGB tmpColor = data[y_sample * width + x_sample]; float gauss_spatial = gaussian2d(i,j,sigma_spatial); //gaussian1d(i,sigma_spatial)*gaussian1d(j,sigma_spatial);// RGB gauss_range; gauss_range.R = gaussian1d(currentColor.R - tmpColor.R, sigma_range); gauss_range.G = gaussian1d(currentColor.G - tmpColor.G, sigma_range); gauss_range.B = gaussian1d(currentColor.B - tmpColor.B, sigma_range); RGB weight; weight.R = gauss_spatial * gauss_range.R; weight.G = gauss_spatial * gauss_range.G; weight.B = gauss_spatial * gauss_range.B; normalization = normalization + weight; res = res + (tmpColor * weight); } } res_data[array_idx] = res / normalization; } } for(int i = 0; i < numElements; i++) { data[i] = res_data[i]; } free(res_data); }
const vector<float> Gaussian::gaussianmask1Df(float s, float size) { //allocate some storage for our 1D mask fmask1d.resize((int)size); //set our gaussian values float sum = 0; float center=ceil(size/2.0); center--; for(float i=0; i<size; i++) { float x = i-center; fmask1d[(int)i] = (float)gaussian1d((double)x); sum += fmask1d[i]; } //normalise for(int j=0; j<fmask1d.size(); j++) fmask1d[j] /=sum; //return the mask return fmask1d; }
const vector<double> Gaussian::gaussianmask1D(double s, double size) { //allocate some storage for our 1D mask mask1d.resize((int)size); //set our gaussian values double sum = 0; double center=ceil(size/2.0); center--; for(double i=0; i<size; i++) { double x = i-center; mask1d[(int)i] = gaussian1d(x); sum += mask1d[i]; } //normalise for(int j=0; j<mask1d.size(); j++) mask1d[j] /=sum; //return the mask return mask1d; }
static __global__ void bilateralKernel(Param<outType> out, CParam<inType> in, float sigma_space, float sigma_color, int gaussOff, int nBBS0, int nBBS1) { SharedMemory<outType> shared; outType *localMem = shared.getPointer(); outType *gauss2d = localMem + gaussOff; const int radius = max((int)(sigma_space * 1.5f), 1); const int padding = 2 * radius; const int window_size = padding + 1; const int shrdLen = THREADS_X + padding; const float variance_range = sigma_color * sigma_color; const float variance_space = sigma_space * sigma_space; // gfor batch offsets unsigned b2 = blockIdx.x / nBBS0; unsigned b3 = blockIdx.y / nBBS1; const inType* iptr = (const inType *) in.ptr + (b2 * in.strides[2] + b3 * in.strides[3] ); outType* optr = (outType * )out.ptr + (b2 * out.strides[2] + b3 * out.strides[3]); int lx = threadIdx.x; int ly = threadIdx.y; const int gx = THREADS_X * (blockIdx.x-b2*nBBS0) + lx; const int gy = THREADS_Y * (blockIdx.y-b3*nBBS1) + ly; // generate gauss2d spatial variance values for block if (lx<window_size && ly<window_size) { int x = lx - radius; int y = ly - radius; gauss2d[ly*window_size+lx] = exp( ((x*x) + (y*y)) / (-2.f * variance_space)); } // pull image to local memory for (int b=ly, gy2=gy; b<shrdLen; b+=blockDim.y, gy2+=blockDim.y) { // move row_set get_local_size(1) along coloumns for (int a=lx, gx2=gx; a<shrdLen; a+=blockDim.x, gx2+=blockDim.x) { load2ShrdMem<inType, outType>(localMem, iptr, a, b, shrdLen, in.dims[0], in.dims[1], gx2-radius, gy2-radius, in.strides[1], in.strides[0]); } } __syncthreads(); if (gx<in.dims[0] && gy<in.dims[1]) { lx += radius; ly += radius; const outType center_color = localMem[ly*shrdLen+lx]; outType res = 0; outType norm = 0; #pragma unroll for(int wj=0; wj<window_size; ++wj) { int joff = (ly+wj-radius)*shrdLen + (lx-radius); int goff = wj*window_size; #pragma unroll for(int wi=0; wi<window_size; ++wi) { const outType tmp_color = localMem[joff+wi]; const outType gauss_range = gaussian1d(center_color - tmp_color, variance_range); const outType weight = gauss2d[goff+wi] * gauss_range; norm += weight; res += tmp_color * weight; } } optr[gy*out.strides[1]+gx] = res / norm; } }