1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
| #include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "convolution.h"
#define true 1
#define false 0
typedef int bool;
bool convolve2D(double* in, double* out, int signalSizeX, int signalSizeY,
double* kernel, int kernelSizeX, int kernelSizeY)
{
int i, j, m, n;
double *inPtr, *inPtr2, *outPtr, *kPtr;
int kCenterX, kCenterY;
int rowMin, rowMax; // to check boundary of input array
int colMin, colMax; //
// check validity of params
if(!in || !out || !kernel)
return false;
if(signalSizeX <= 0 || kernelSizeX <= 0)
return false;
// find center position of kernel (half of kernel size)
kCenterX = kernelSizeX >> 1;
kCenterY = kernelSizeY >> 1;
// init working pointers
inPtr = inPtr2 = &in[signalSizeX * kCenterY + kCenterX]; // note that it is shifted (kCenterX, kCenterY),
outPtr = out;
kPtr = kernel;
// start convolution
for(i= 0; i < signalSizeY; ++i) // number of rows
{
// compute the range of convolution, the current row of kernel should be between these
rowMax = i + kCenterY;
rowMin = i - signalSizeY + kCenterY;
for(j = 0; j < signalSizeX; ++j) // number of columns
{
// compute the range of convolution, the current column of kernel should be between these
colMax = j + kCenterX;
colMin = j - signalSizeX + kCenterX;
*outPtr = 0; // set to 0 before accumulate
// flip the kernel and traverse all the kernel values
// multiply each kernel value with underlying input data
for(m = 0; m < kernelSizeY; ++m) // kernel rows
{
// check if the index is out of bound of input array
if(m <= rowMax && m > rowMin)
{
for(n = 0; n < kernelSizeX; ++n)
{
// check the boundary of array
if(n <= colMax && n > colMin)
*outPtr += *(inPtr - n) * *kPtr;
++kPtr; // next kernel
}
}
else
kPtr += kernelSizeX; // out of bound, move to next row of kernel
inPtr -= signalSizeX; // move input data 1 raw up
}
kPtr = kernel; // reset kernel to (0,0)
inPtr = ++inPtr2; // next input
++outPtr; // next output
}
}
return true;
} |
Partager