void AtrousGabor::_image_prod(IMAGE_PTR i1, IMAGE_PTR i2, IMAGE_PTR out) { #ifdef USE_IPP IppiSize roiSize = {m_i_colsext, m_i_linesext}; ippiMul_32f_C1R(i1, m_i_strideext, i2, m_i_strideext, out, m_i_strideext, roiSize); #else int i, j; for(i = 0; i < m_i_linesext; i++) for(j = 0; j < m_i_colsext; j++) out[i*m_i_stridepix+j] = i1[i*m_i_stridepix+j]*i2[i*m_i_stridepix+j]; #endif }
Ipp32f (*ParticleStatistics(Image2D &image_localmax, Image2D &image_in, const int mask_radius, const int feature_radius, int &counter))[8] { IppStatus status; //setup kernels Convolution_Kernel ConvolutionKernels(mask_radius, image_localmax.get_width(), image_localmax.get_length()); //Convert 32-bit FP image data in image_localmax to 8-bit integer data Ipp8u *localmaxdata = ippsMalloc_8u((int) image_localmax.get_numberofpixels()); int stepsize = image_localmax.get_width(); IppiSize fullROI = image_localmax.get_ROIfull(); status = ippiConvert_32f8u_C1R(image_localmax.get_image2D(), image_localmax.get_stepsize(), localmaxdata, stepsize, fullROI, ippRndNear); //Determine the number of particles (raw; not yet excluded from border region) Ipp64f numberofmaxima = 0; status = ippiSum_8u_C1R(localmaxdata, stepsize, image_localmax.get_ROIfull(), &numberofmaxima); //Set up structures for counting particle data int numberofpixels = image_localmax.get_numberofpixels(); Ipp32f (*particledata)[8] = new Ipp32f[(int) numberofmaxima + 1][8]; //border region (local maxima here are excluded from future operations) int border = feature_radius; //minimum distance from the border, in pixels int minx = border, miny = border; int maxx = image_localmax.get_width() - minx; int maxy = image_localmax.get_height() - miny; int xval = 0; int yval = 0; counter = 0; //index that keeps track of which particle int imagewidth = image_in.get_width(); //determine integer x and y values (in pixels) for each local maximum outside //of border exclusion area for(int j = 0; j < numberofpixels; j++) { if(localmaxdata[j] == 1) { xval = image_in.getx(j); yval = image_in.gety(j); if (xval > minx && xval < maxx && yval > miny && yval < maxy) { particledata[counter][0] = j; particledata[counter][1] = xval; particledata[counter][2] = yval; counter++; } } } //extract local region around each maximum int extract_radius = mask_radius; int extract_diameter = 2 * extract_radius + 1; int extract_size = extract_diameter * extract_diameter; int extract_step = 4 * extract_diameter; IppiSize extract_ROI = {extract_diameter, extract_diameter}; int extract_offset = extract_radius * (1 + image_in.get_width()); //calculate _relative_ offset (in pixels) of the array index Ipp32f *extracted_square = ippsMalloc_32f(extract_size); Ipp32f *multiply_result = ippsMalloc_32f(extract_size); Ipp32f *inputimage = ippsMalloc_32f(image_in.get_numberofpixels()); status = ippiCopy_32f_C1R(image_in.get_image2D(), image_in.get_stepsize(), inputimage, image_in.get_stepsize(), image_in.get_ROIfull()); for(int i = 0; i < counter; i++) { int extract_index = particledata[i][0]; int copy_offset = extract_index - extract_offset; //this is the starting point for ROI (in pixels!!) status = ippiCopy_32f_C1R(inputimage + copy_offset, image_in.get_stepsize(), extracted_square, extract_step, extract_ROI); //Calculate mass Ipp64f total_mass = 0; status = ippiMul_32f_C1R(extracted_square, extract_step, ConvolutionKernels.get_circle_kernel(), ConvolutionKernels.get_kernel_step(), multiply_result, extract_step, extract_ROI); status = ippiSum_32f_C1R(multiply_result, extract_step, extract_ROI, &total_mass, ippAlgHintNone); //Calculate x-offset (to be added to integral position) Ipp64f x_sum = 0; status = ippiMul_32f_C1R(extracted_square, extract_step, ConvolutionKernels.get_ramp_x_kernel(), ConvolutionKernels.get_kernel_step(), multiply_result, extract_step, extract_ROI); status = ippiSum_32f_C1R(multiply_result, extract_step, extract_ROI, &x_sum, ippAlgHintNone); Ipp32f x_offset = (x_sum / total_mass) - extract_radius - 1; //Calculate y-offset (to be added to integral position) Ipp64f y_sum = 0; status = ippiMul_32f_C1R(extracted_square, extract_step, ConvolutionKernels.get_ramp_y_kernel(), ConvolutionKernels.get_kernel_step(), multiply_result, extract_step, extract_ROI); status = ippiSum_32f_C1R(multiply_result, extract_step, extract_ROI, &y_sum, ippAlgHintNone); Ipp32f y_offset = (y_sum / total_mass) - extract_radius - 1; //Calculate r^2 Ipp64f r2_sum = 0; status = ippiMul_32f_C1R(extracted_square, extract_step, ConvolutionKernels.get_r2_kernel(), ConvolutionKernels.get_kernel_step(), multiply_result, extract_step, extract_ROI); status = ippiSum_32f_C1R(multiply_result, extract_step, extract_ROI, &r2_sum, ippAlgHintNone); Ipp32f r2_val = r2_sum / total_mass; //Calculate "multiplicity": how many particles are within the area calculated by the masks Ipp64f multiplicity = 0; status = ippiSum_32f_C1R(image_localmax.get_image2D()+copy_offset, image_localmax.get_stepsize(), extract_ROI, &multiplicity, ippAlgHintNone); Ipp32f multiplicity_val = multiplicity; //assign values to particle data array if (total_mass > 0) { particledata[i][1] += x_offset; particledata[i][2] += y_offset; particledata[i][3] = x_offset; particledata[i][4] = y_offset; particledata[i][5] = total_mass; particledata[i][6] = r2_val; particledata[i][7] = multiplicity_val; } } //Cleanup memory (this part is critical---program otherwise crashes!!) ippsFree(extracted_square); extracted_square = NULL; ippsFree(multiply_result); multiply_result = NULL; ippsFree(inputimage); inputimage = NULL; ippsFree(localmaxdata); localmaxdata = NULL; return particledata; }