Skip to content

Commit

Permalink
README.md: Typo
Browse files Browse the repository at this point in the history
dsp/p_conv_f32: Remove an extra element in the result, Fix a problem in involving uninitialize memory addresses in computation.
image/p_conv2d_f32: Returns incorrect values as it doesn't flip the kernel in vertical and horizontal directions, Support for rectangular kernels.
image/p_median3x3.c: For 3x3 median filter, I replaced it with hardwired median search described here: http:users.utcluj.ro/~baruch/resources/Image/xl23_16.pdf

Extra information
    Signed-off-by: Hamid Ebadi <[email protected]>

Counter example for p_conv_f32

Response from FreeMat:
--> x = [1, 2, 3, 4];
--> h = [5,6,7];
--> r = conv(x, h)
r =
  5 16 34 52 45 28

Response from pal:
   float x[4] = {1,2,3,4};
   float h[3] = {5,6,7} ;
   float r[10] = {100,100,100,100,100,100, 100, 100,100, 100};
   p_conv_f32( x, h , r ,4 ,3);
   printf ("%f, %f, %f, %f, %f, %f, %f, %f", r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7]);
   100.000000, 105.000000, 116.000000, 134.000000, 152.000000, 145.000000, 128.000000, 100.000000

Counter example for p_conv2d_f32

Response from FreeMat:
--> A= [17 24 1 8 15; 23 5 7 14 16; 4 6 13 20 22;10 12 19 21 3; 11 18 25 2 9]
--> B=[1 3 1; 0 5 0; 2 1 2]
--> E=[0 0 0; 0 1 0; 0 0 0]
--> C2 = conv2(A,E,'valid')   <-- works correctly since kernel is symmetric
--> C1 = conv2(A,B,'valid')   <-- Doesn't work correctly

120, 165, 205,
160, 200, 245,
190, 255, 235,

Response from pal:
155.0, 135.0, 200.0,
145.0, 190.0, 230.0,
185.0, 225.0, 270.0,

int main(int argc, char *argv[])
{
   int i, j;
   float src[5*5] = {17,24,1,8,15,
                    23,5,7,14,16,
                    4,6,13,20,22,
                    10,12,19,21,3,
                    11,18,25,2,9 };
   float kernel[3*3] = {
          1,3,1,
          0,5,0,
          2,1,2 };
    float dest[3*3];
    p_conv2d_f32(src, kernel, dest, 5, 5, 3);

    for (i = 0; i < W; i++) {
        for (j = 0; j < W; j++) {
        	printf("%.1f, ", src[i*W+j]);
        }
        printf("\n");
    }

    printf("\n");

    for (i = 0; i < W2; i++) {
        for (j = 0; j < W2; j++) {
        	printf("%.1f, ", dest[i*W2+j]);
        }
        printf("\n");
    }
}
  • Loading branch information
ebadi committed Jun 16, 2015
1 parent fcb69c4 commit dca21ba
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 27 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ FUNCTION | NOTES
[p_max()](src/math/p_max.c) | finds max val
[p_min()](src/math/p_min.c) | finds min val
[p_mean()](src/math/p_mean.c) | mean operation
[p_median()](src/math/p_mean.c) | finds middle value
[p_median()](src/math/p_median.c) | finds middle value
[p_mode()](src/math/p_mode.c) | finds most common value
[p_mul()](src/math/p_mul.c) | multiplication
[p_popcount()](src/math/p_popcount.c) | count the number of bits set
Expand Down
2 changes: 1 addition & 1 deletion include/pal_image.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

/*2d convolution */
void p_conv2d_f32(const float *x, float *m, float *r, int rows, int cols,
int msize);
int mrows, int mcols);

/*2d box (i.e mean) filter(3x3) */
void p_box3x3_f32(const float *x, float *r, int rows, int cols);
Expand Down
12 changes: 8 additions & 4 deletions src/dsp/p_conv.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,15 @@ void p_conv_f32(const float *x, const float *h, float *r, int nx, int nh)
{
const float *xc = x;
float *rx = r;
for ( int i = 0; i < nx; i++) {
int i,j ;
for ( i = 0; i < nx+nh-1; i++) { *(rx++) = 0; }
rx = r ;
for ( i = 0; i < nx; i++) {
float xv = *xc++;
rx++;
for (int j = 0; j < nh; j++) {
*(rx + j) += xv * *(h + j);

for (j = 0; j < nh; j++) {
*(rx + j) += xv * *(h + j);
}
rx++;
}
}
34 changes: 14 additions & 20 deletions src/image/p_conv2d.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,36 +19,30 @@
*/

void p_conv2d_f32(const float *x, float *m, float *r, int rows, int cols,
int msize)
int mrows, int mcols)

{
int i, j, k;
float P, part;
int i, j, ki, kj;
float P;
const float *px, *pm;
float *pr;

px = x;
pm = m;
pr = r;

for (i = msize * 0.5; i < (rows - msize * 0.5); i++) {
for (j = msize * 0.5; j < (cols - msize * 0.5); j++) {
for (i = 0; i < rows - mrows+1 ; i++) {
for (j = 0; j < cols - mcols+1 ; j++) {
P = 0.0f;
pm = m;
for (k = 0; k < msize; k++) {
p_dot_f32(px, pm, &part, msize);
P += part;
px += cols;
pm += msize;
pm = m+(mcols * mrows)-1;
for (ki=0 ; ki< mrows ; ki++){
for (kj=0 ; kj< mcols ; kj++){
P+= (*px++)* (*pm--) ;
}
px += cols - mcols;
}
*pr = P;
pr++;
// move image pointer one index forward compared to
// the position from before `for` loop
px += 1 - msize * cols;
px -= (mrows * cols) -1 ;
*(pr++) = P;
}
// move image pointer to the beginning of line
// beneath the current line
px += (int)(msize * 0.5) * 2;
px+=mcols-1 ;
}
}
40 changes: 39 additions & 1 deletion src/image/p_median3x3.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,43 @@
#include <pal.h>
/*
* The following routines have been built from knowledge gathered
* around the Web. I am not aware of any copyright problem with
* them, so use it as you want.
* N. Devillard - 1998
*/

typedef float pixelvalue ;

#define PIX_SORT(a,b) { if ((a)>(b)) PIX_SWAP((a),(b)); }
#define PIX_SWAP(a,b) { pixelvalue temp=(a);(a)=(b);(b)=temp; }

/*----------------------------------------------------------------------------
Function : opt_med9()
In : pointer to an array of 9 pixelvalues
Out : a pixelvalue
Job : optimized search of the median of 9 pixelvalues
Notice : in theory, cannot go faster without assumptions on the
signal.
Formula from:
XILINX XCELL magazine, vol. 23 by John L. Smith
The input array is *NOT* modified in the process
The result array is guaranteed to contain the median
value
---------------------------------------------------------------------------*/

pixelvalue opt_med9(pixelvalue * pointer)
{
pixelvalue p[9];
memcpy(p, pointer, 9*sizeof(pixelvalue) );
PIX_SORT(p[1], p[2]) ; PIX_SORT(p[4], p[5]) ; PIX_SORT(p[7], p[8]) ;
PIX_SORT(p[0], p[1]) ; PIX_SORT(p[3], p[4]) ; PIX_SORT(p[6], p[7]) ;
PIX_SORT(p[1], p[2]) ; PIX_SORT(p[4], p[5]) ; PIX_SORT(p[7], p[8]) ;
PIX_SORT(p[0], p[3]) ; PIX_SORT(p[5], p[8]) ; PIX_SORT(p[4], p[7]) ;
PIX_SORT(p[3], p[6]) ; PIX_SORT(p[1], p[4]) ; PIX_SORT(p[2], p[5]) ;
PIX_SORT(p[4], p[7]) ; PIX_SORT(p[4], p[2]) ; PIX_SORT(p[6], p[4]) ;
PIX_SORT(p[4], p[2]) ; return(p[4]) ;
}
/*
* A median 3x3 filter.
*
Expand Down Expand Up @@ -50,7 +88,7 @@ void p_median3x3_f32(const float *x, float *r, int rows, int cols)
buffer[buffer_col + 3] = *(px + cols);
buffer[buffer_col + 6] = *(px + cols + cols);

p_median_f32(buffer, pr, 9);
*pr = opt_med9(buffer);
pr++;
px++;
}
Expand Down

2 comments on commit dca21ba

@kranfix
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In p_conv.c, why is it necessary to declare rx and xc in lines 23 and 24?

23 const float *xc = x;
24 float *rx = r;

I tried with neither xc nor rx and it works.

@ebadi
Copy link
Contributor Author

@ebadi ebadi commented on dca21ba Jun 28, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I re-factored the code and removed xc. However I cannot see why rx is unnecessary ?
https://github.com/ebadi/pal/blob/6f5b040f409f9f71bc4b0088d56965d703626492/src/dsp/p_conv.c

Please sign in to comment.