Floating point exception of my C program - c

This is the part causing the problem. I am really not able to find anything not ok. This part is for the mel binning function for a front end construction.
The original document is at http://www.ee.columbia.edu/~stanchen/fall12/e6870/labs/lab1.html
Thanks for any help in advance!
double fmax = 0;
double w = 0; // half of the length of the bottom line of each bin of triangular
fmax = 1127*log(1+1/(1400*samplePeriod));
w = fmax/27;
double f = 0;
double fmel = 0;
double xf = 0;
double H = 0;
double sum = 0;
for (int frmIdx = 0; frmIdx < inFrameCnt; ++frmIdx)
for (int dimIdx = 0; dimIdx < outDimCnt; ++dimIdx){
sum = 0;
for (int j = 0; j < 256; ++j){
f = j/(256/20000);
fmel = 1127*log(1+f/700);
xf = sqrt(inFeats(frmIdx,2*j)*inFeats(frmIdx,2*j)+inFeats(frmIdx,2*j+1)*inFeats(frmIdx,2*j+1));
if (fmel > dimIdx*w && fmel < (dimIdx+1)*w){
H = (fmel- dimIdx*w)/w;
}
else if(fmel > ((dimIdx+1)*w) && fmel < ((dimIdx+2)*w)){
H = ( (dimIdx+2)*w-fmel)/w;
}
else {
H = 0;
}
sum = sum + xf*H;
}
outFeats(frmIdx,dimIdx)=sum;
if (doLog == true){
outFeats(frmIdx,dimIdx) = log(outFeats(frmIdx,dimIdx));
}
else{
outFeats(frmIdx,dimIdx) = outFeats(frmIdx,dimIdx);
}
}

Check that there are no divisions by zero.
this is the first one that is 0 by definition:
f = j/(256/20000); // (256 and 20000 are treated as integers)
256. / 20000. (or 256.0 / 20000.0 ) would make a float.

Related

Using a single set of random number generators in a loop

Given the code below, is it possible to modify it so that there's a single set of M "random" numbers for x and y that will "restart" at the beginning of the set for every iteration of i?
What I know I can do is pre-generate an array for x and y of length M but I cannot use arrays because of limited memory. I was thinking of using random numbers with seeds somehow but haven't been able to figure it out.
double sampleNormal()
{
double u = ((double) rand() / (RAND_MAX)) * 2 - 1;
double v = ((double) rand() / (RAND_MAX)) * 2 - 1;
double r = u * u + v * v;
if (r == 0 || r > 1) return sampleNormal();
double c = sqrt(-2 * log(r) / r);
return u * c;
}
...
double x = 0;
double y = 0;
double a = 0;
double f = 100e6;
double t = 0;
double fsamp = 2e9;
for(int i = 0; i < N; i++)
{
for(int j = 0; j < M; j++)
{
x = sampleNormal();
y = sampleNormal();
t = j/fsamp;
a = x*cos(2*pi*f*t)+y*sin(2*pi*f*t);
}
}
that will "restart" at the beginning of the set for every iteration of i
was thinking of using random numbers with seeds somehow but haven't been able to figure it out.
Code could abuse srand()
// Get some state info from rand() for later.
unsigned start = rand();
start = start*(RAND_MAX + 1u) + rand();
for(int i = 0; i < N; i++) {
// Initialize the random number generator to produce the same sequence.
srand(42); // Use your favorite constant.
for(int j = 0; j < M; j++) {
x = sampleNormal();
y = sampleNormal();
t = j/fsamp;
a = x*cos(2*pi*f*t)+y*sin(2*pi*f*t);
}
}
// Re-seed so other calls to `rand()` are not so predictable.
srand(start);

how to produce -400,-200,-400 in sequential order

I am trying to write a for loop in the second version which produce the same result in the original code but i am not sure how to get -400,-200,-400 in sequential order.
original code:
p->m_p[0] = randFloat(-400.0f, 400.0);
p->m_p[1] = randFloat(-200.0f, 200.0);
p->m_p[2] = randFloat(-400.0f, 400.0);
second version:
float x = -800;
float y = 800;
for(int i = 0; i < 4; i++)
{
plNew->m_fPosition[i] = randFloat(x / 2,y / 2);
}
If you need it to work in C (or in C++ before C++11), this would work:
#define NUMBER_OF_VALUES 3
float bounds[NUMBER_OF_VALUES] = { 400.0f, 200.0f, 400.0f };
for (int i = 0; i < NUMBER_OF_VALUES; i++)
{
plNew->m_fPosition[i] = randFloat(-bounds[i], bounds[i]);
}
You can extend this to make NUMBER_OF_VALUES be 4 or a larger number as long as you initialize all the members of bounds[NUMBER_OF_VALUES] with the desired constants.
A nice feature of this is that the sequence of constants can be anything you like,
not limited to alternating 400, 200, 400 or any other regular sequence.
Something like this?
for (int i = 0; i < 4; i++) {
float x, y;
if (i % 2) {
x = -400.0f;
y = 400.0f;
} else {
x = -200.0f;
y = 200.0f;
}
p->m_p[i] = randFloat(x, y);
}
What about?
float x = -800;
float y = 800;
for(int i = 0; i < 4; i++)
{
float z = 2.0 * ((float)((i + 1) % 2 + 1));
plNew->m_fPosition[i] = randFloat(x / z, y / z);
}
I would suggest keeping it simple, using something like the following :
const float arr3[] = {-400.0f, -200.0f, -400.0f};
for(int i = 0; i < 3; i++)
{
plNew->m_fPosition[i] = arr3[i];
}
float x = -400;
float y = 400;
for(int i = 0; i < 3; i++)
{
plNew->m_fPosition[i] = randFloat(x / (1 + (i & 1)), y / (1 + (i & 1)));
}

What's wrong with my code: wrong value output when I try to calculate Euler's number, e, in C?

I'm trying to approximate Euler's number in C using a loop that terminates when the difference between two successive values of e is less than 0.0000001. The value I get is 2.99.. I tried setting it up so that with each iteration, e will be compared with the previous value of itself (held in e1) and if the difference is greater than 0.0000001 it will add another term 1/(n!). What's the issue? I'm new to programming so any advice/critiquing is appreciated.
#include <stdio.h>
int main()
{
float e1 = 0, e2 = 1;
int n = 1, nfact;
while ((e2 - e1) > 0.0000001)
{
e1 = e2;
nfact = 1;
for (int count = 1; count < n; count++)
{
nfact = n * count;
}
n = n + 1;
e2 = e1 + (1.0 / nfact);
}
printf("Approximated value of e = %f", e2);
return 0;
}
nfact = 1;
for (int count = 1; count < n; count++)
{
nfact = n * count;
}
won´t calculate n!.
nfact gets a completely new value every iteration.
Surely you mean
nfact = 1;
for (int count = 2; count <= n; count++)
{
nfact *= count;
}
This is not how you calculate the factorial of a number:
for (int count = 1; count < n; count++)
{
nfact = n * count;
}
Notice that you always assign to nfact on each iteration to the value of n*count, obliterating the previous value of nfact. This piece of code is equivalent to:
nfact = n*(n-1);
Since that's the last value of count.
I think you wanted this instead:
nfact = n;
for (int count = n-1; count > 0; count--)
{
nfact = nfact * count;
}
This is my code for
estimates the value of the mathematical constant e by using the formula:
e = 1 + 1/1! + 1/2! + 1/3! + ....
#include <stdio.h>
int main(void) {
int n = 0; /* loop counter for accuracy */
int accuracy = 10; /* current n factorial */
int fact = 1; /* degree of accuracy */
double e = 0; /* current estimated value of e */
/* loop until degree of accuracy */
while (n <= accuracy) {
if (n == 0) {
fact *= 1;
} else {
fact *= n;
}
e += 1.0 / fact;
++n;
}
printf("e is %f", e);
return 0;
}

High Pass Filter using FFTW in C

I have a question regarding FFT. I already manage to do FFT forward and backward using FFTW in C. Now, I want to apply high pass filter for edge detection, some of my source said that just zeroing the centre of the magnitude.
This is my input image
http://i62.tinypic.com/2wnxvfl.jpg
Basically what I do are :
Forward FFT
Convert the output to 2D array
Do forward FFT shifting
Make the real and imag value to 0 when the distance from the centre is 25% of the height
Generate the magnitude
Do backward FFT shifting
Convert into 1D array
Do Backward FFT.
This is the original magnitude, the processed magnitude, and the result
http://i58.tinypic.com/aysx9s.png
can someone help me, to tell me which part is wrong and how to do the high pass filtering using FFTW in C.
Thank You.
The Source Code:
unsigned char **FFT2(int width,int height, unsigned char **pixel, char line1[100],char line2[100], char line3[100],char filename[100])
{
fftw_complex* in, * dft, * idft, * dft2;
//fftw_complex tmp1,tmp2;
fftw_plan plan_f,plan_i;
int i,j,k,w,h,N,w2,h2;
w = width;
h = height;
N = w*h;
unsigned char **pixel_out;
pixel_out = malloc(h*sizeof(unsigned char*));
for(i = 0 ; i<h;i++)
pixel_out[i]=malloc(w*sizeof(unsigned char));
in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) *N);
dft = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) *N);
dft2 = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) *N);
idft = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) *N);
/*run forward FFT*/
plan_f = fftw_plan_dft_2d(w,h,in,dft,FFTW_FORWARD,FFTW_ESTIMATE);
for(i = 0,k = 0 ; i < h ; i++)
{
for(j = 0 ; j < w ; j++,k++)
{
in[k][0] = pixel[i][j];
in[k][1] = 0.0;
}
}
fftw_execute(plan_f);
double maxReal = 0.0;
for(i = 0 ; i < N ; i++)
maxReal = dft[i][0] > maxReal ? dft[i][0] : maxReal;
printf("MAX REAL : %f\n",maxReal);
/*fftshift*/
//convert to 2d
double ***temp1;
temp1 = malloc(h * sizeof (double**));
for (i = 0;i < h; i++){
temp1[i] = malloc(w*sizeof (double*));
for (j = 0; j < w; j++){
temp1[i][j] = malloc(2*sizeof(double));
}
}
double ***temp2;
temp2 = malloc(h * sizeof (double**));
for (i = 0;i < h; i++){
temp2[i] = malloc(w*sizeof (double*));
for (j = 0; j < w; j++){
temp2[i][j] = malloc(2*sizeof(double));
}
}
for (i = 0;i < h; i++){
for (j = 0; j < w; j++){
temp1[i][j][0] = dft[i*w+j][0];
temp1[i][j][1] = dft[i*w+j][1];
}
}
int m2 = h/2;
int n2 = w/2;
//forward shifting
for (i = 0; i < m2; i++)
{
for (k = 0; k < n2; k++)
{
double tmp13[2] = {temp1[i][k][0],temp1[i][k][1]};
temp1[i][k][0] = temp1[i+m2][k+n2][0];
temp1[i][k][1] = temp1[i+m2][k+n2][1];
temp1[i+m2][k+n2][0] = tmp13[0];
temp1[i+m2][k+n2][1] = tmp13[1];
double tmp24[2] = {temp1[i+m2][k][0],temp1[i+m2][k][1]};
temp1[i+m2][k][0] = temp1[i][k+n2][0];
temp1[i+m2][k][1] = temp1[i][k+n2][1];
temp1[i][k+n2][0] = tmp24[0];
temp1[i][k+n2][1] = tmp24[1];
}
}
//process
for (i = 0;i < h; i++){
for (j = 0; j < w; j++){
if(distance_to_center(i,j,m2,n2) < 0.25*h)
{
temp1[i][j][0] = (double)0.0;
temp1[i][j][1] = (double)0.0;
}
}
}
/* copy for magnitude */
for (i = 0;i < h; i++){
for (j = 0; j < w; j++){
temp2[i][j][0] = temp1[i][j][0];
temp2[i][j][1] = temp1[i][j][1];
}
}
//backward shifting
for (i = 0; i < m2; i++)
{
for (k = 0; k < n2; k++)
{
double tmp13[2] = {temp1[i][k][0],temp1[i][k][1]};
temp1[i][k][0] = temp1[i+m2][k+n2][0];
temp1[i][k][1] = temp1[i+m2][k+n2][1];
temp1[i+m2][k+n2][0] = tmp13[0];
temp1[i+m2][k+n2][1] = tmp13[1];
double tmp24[2] = {temp1[i+m2][k][0],temp1[i+m2][k][1]};
temp1[i+m2][k][0] = temp1[i][k+n2][0];
temp1[i+m2][k][1] = temp1[i][k+n2][1];
temp1[i][k+n2][0] = tmp24[0];
temp1[i][k+n2][1] = tmp24[1];
}
}
//convert back to 1d
for (i = 0;i < h; i++){
for (j = 0; j < w; j++){
dft[i*w+j][0] = temp1[i][j][0];
dft[i*w+j][1] = temp1[i][j][1];
dft2[i*w+j][0] = temp2[i][j][0];
dft2[i*w+j][1] = temp2[i][j][1];
}
}
/* magnitude */
double max = 0;
double min = 0;
double mag=0;
for (i = 0, k = 1; i < h; i++){
for (j = 0; j < w; j++, k++){
mag = sqrt(pow(dft2[i*w+j][0],2) + pow(dft2[i*w+j][1],2));
if (max < mag)
max = mag;
}
}
double **magTemp;
magTemp = malloc(h * sizeof (double*));
for (i = 0;i < h; i++){
magTemp[i] = malloc(w*sizeof (double));
}
for(i = 0,k = 0 ; i < h ; i++)
{
for(j = 0 ; j < w ; j++,k++)
{
double mag = sqrt(pow(dft2[i*w+j][0],2) + pow(dft2[i*w+j][1],2));
mag = 255*(mag/max);
//magTemp[i][j] = 255-mag; //Putih
magTemp[i][j] = mag; //Item
}
}
/* brightening magnitude*/
for(i = 0,k = 0 ; i < h ; i++)
{
for(j = 0 ; j < w ; j++,k++)
{
//double temp = magTemp[i][j];
double temp = (double)(255/(log(1+255)))*log(1+magTemp[i][j]);
pixel_out[i][j] = (unsigned char)temp;
}
}
generateImage(width,height,pixel_out,line1,line2,line3,filename,"magnitude");
/* backward fft */
plan_i = fftw_plan_dft_2d(w,h,dft,idft,FFTW_BACKWARD,FFTW_ESTIMATE);
fftw_execute(plan_i);
for(i = 0,k = 0 ; i < h ; i++)
{
for(j = 0 ; j < w ; j++,k++)
{
double temp = idft[i*w+j][0]/N;
pixel_out[i][j] = (unsigned char)temp; //+ pixel[i][j];
}
}
generateImage(width,height,pixel_out,line1,line2,line3,filename,"backward");
return pixel_out;
}
EDIT new source code
I add this part before the forward shifting, the result is as expected also.
//proses
//create filter
unsigned char **pixel_filter;
pixel_filter = malloc(h*sizeof(unsigned char*));
for(i = 0 ; i<h;i++)
pixel_filter[i]=malloc(w*sizeof(unsigned char));
for (i = 0;i < h; i++){
for (j = 0; j < w; j++){
if(distance_to_center(i,j,m2,n2) < 20)
{
pixel_filter[i][j] = 0;
}
else
{
pixel_filter[i][j] = 255;
}
}
}
generateImage(width,height,pixel_filter,line1,line2,line3,filename,"filter1");
for (i = 0; i < m2; i++)
{
for (k = 0; k < n2; k++)
{
unsigned char tmp13 = pixel_filter[i][k];
pixel_filter[i][k] = pixel_filter[i+m2][k+n2];
pixel_filter[i+m2][k+n2] = tmp13;
unsigned char tmp24 = pixel_filter[i+m2][k];
pixel_filter[i+m2][k] = pixel_filter[i][k+n2];
pixel_filter[i][k+n2] = tmp24;
}
}
generateImage(width,height,pixel_filter,line1,line2,line3,filename,"filter2");
for (i = 0;i < h; i++){
for (j = 0; j < w; j++){
temp1[i][j][0] *= pixel_filter[i][j];
temp1[i][j][1] *= pixel_filter[i][j];
}
}
Your general idea is OK. From the output, it's hard to tell whether there's simply an accounting problem in your program, or whether this is perhaps the expected result. Try padding the source image with much more empty space, and filter out a smaller area in the frequency domain.
As a side note, doing this in C appears incredibly painful. Here is an equivalent implementation in Matlab. Not including plotting, it's around 10 lines of code. You might also try Numerical Python (NumPy).
% Demonstrate frequency-domain image filtering in Matlab
% Define the grid
x = linspace(-1, 1, 1001);
y = x;
[X, Y] = meshgrid(x, y);
% Make a square (source image)
rect = (abs(X) < 0.1) & (abs(Y) < 0.1);
% Compute the transform
rect_hat = fft2(rect);
% Make the high-pass filter
R = sqrt(X.^2 + Y.^2);
filt = (R > 0.05);
% Apply the filter
rect_hat_filtered = rect_hat .* ifftshift(filt);
% Compute the inverse transform
rect_filtered = ifft2(rect_hat_filtered);
%% Plot everything
figure(1)
imagesc(rect);
title('source');
axis square
saveas(gcf, 'fig1.png');
figure(2)
imagesc(abs(fftshift(rect_hat)));
title('fft(source)');
axis square
saveas(gcf, 'fig2.png');
figure(3)
imagesc(filt);
title('filter (frequency domain)');
axis square
saveas(gcf, 'fig3.png');
figure(4)
imagesc(fftshift(abs(rect_hat_filtered)));
title('fft(source) .* filter');
axis square
saveas(gcf, 'fig4.png');
figure(5)
imagesc(abs(rect_filtered))
title('result');
axis square
saveas(gcf, 'fig5.png');
The source image:
Fourier transform of the source image:
The filter:
Result of applying (multiplying) the filter with the fourier transform of the source image:
Taking the inverse transform gives the final result:

simple blur of RGB raw image

I'm trying to make a simple blur effect in c. I have an image loaded in an 512*512 array of RGB pixels and I'm using 3x3 kernel to blur that image
here is the kernel
float matrix[9] = {1.0f/9.0f, 1.0f/9.0f, 1.0f/9.0f, 1.0f/9.0f, 1.0f/9.0f, 1.0f/9.0f, 1.0f/9.0f, 1.0f/9.0f, 1.0f/9.0f};
and here is the code that is doing the bluring
void useBlur(){
for(int i = 0; i < ARRAY_SIZE; i++){
float r = 0;
float g = 0;
float b = 0;
int m, n;
for(int y = -1, m = 0; y <= 1; y++, m++){
for(int z = -1, n = 0; z <= 1; z++, n++){
r += (float)orig_image[i + 512 * y + z].r * (float)matrix[m*3+n];
g += (float)orig_image[i + 512 * y + z].g * (float)matrix[m*3+n];
b += (float)orig_image[i + 512 * y + z].b * (float)matrix[m*3+n];
}
}
image[i].r = r;
image[i].g = g;
image[i].b = b;
}
}
I'm not sure what is wrong with that code, but it is producing result:
Any ideas why the colors are wrong? And how to fix it?
EDIT:
fixed matrix[7] from 9.0/9.0 to 1.0/9.0 and uploaded new image
I tried your code with some changes, the images I have are BGRA and I am using opencv for my image container but the structure of the code is the same and it works perfectly.
for (int i = 2*image.cols; i < image.rows*image.cols-2*image.cols; i++)
{
float r = 0;
float g = 0;
float b = 0;
for (int y = -1; y <=1; y++)
{
for (int z = -1; z <=1; z++)
{
b += (float)image.at<cv::Vec4b>(i + image.cols*y+z)(0)*(1.0/9);
g += (float)image.at<cv::Vec4b>(i + image.cols*y+z)(1)*(1.0/9);
r += (float)image.at<cv::Vec4b>(i + image.cols*y+z)(2)*(1.0/9);
}
}
image.at<cv::Vec4b>(i)(0) = b;
image.at<cv::Vec4b>(i)(1) = g;
image.at<cv::Vec4b>(i)(2) = r;
}
I would assume that means the problem is either not in the code you posted, or somehow the opencv cv::Mat class is handling something your image container is not. The obvious candidate for that would be that you seem to be implicitly converting from float to uchar at the end of your code. Could you test running this loop over your image but without modifying it? It could look like this, or any number of other ways. This is ugly, but a quick conversion.
void useBlur(){
for(int i = 0; i < ARRAY_SIZE; i++){
float r = 0;
float g = 0;
float b = 0;
int m, n;
for(int y = -1, m = 0; y <= 1; y++, m++){
for(int z = -1, n = 0; z <= 1; z++, n++){
if(y == 0 && z == 0)
{
r += (float)orig_image[i + 512 * y + z].r * (float)matrix[m*3+n]*9;
g += (float)orig_image[i + 512 * y + z].g * (float)matrix[m*3+n]*9;
b += (float)orig_image[i + 512 * y + z].b * (float)matrix[m*3+n]*9;
}
}
}
image[i].r = r;
image[i].g = g;
image[i].b = b;
}
}
Theoretically nothing should change about the image when you do that, so if the image is changing it is because of some conversion error. I admit the theory is unlikely but the structure of your code seems sound so I don't know what else to suggest.

Resources