I'm trying to write a convolution function in C for my computer vision study. In this function, every pixel in the convolved image is a sum of product of original image and filter kernel like in this image and this gif.
In the code below pixel values are float. get_pixel()
function gets the pixel value at given indexes. set_pixel()
function sets the value to given indexes.
image convolve(image im, image filter) {
// imx, imy, imc: indexes of image pixels
// fix, fiy: indexes of filter pixels
// rx, ry: relative indexes of pixels
image convolved_img = make_image(im.w, im.h, im.c); // image with same dimensions
float value = 0; // pixel value
int oxo = floor(filter.w / 2); // half of the kernel width
int xox = floor(filter.h / 2); // half of the kernel height
// Convolution Loop
for(int imc = 0; imc < im.c; imc++) { // for every channel
for(int imx = 0; imx < im.w; imx++) {
for(int imy = 0; imy < im.h; imy++) { // for every pixel
value = 0;
for(int fix = 0; fix < filter.w; fix++) {
for(int fiy = 0; fiy < filter.h; fiy++) {
int rx = imx - oxo + fix;
int ry = imy - xox + fiy;
value += get_pixel(filter, fix, fiy, 0) * get_pixel(im, rx, ry, imc);
}
}
set_pixel(convolved_img, imx, imy, imc, value);
}
}
}
return convolved_img;
}
I'm getting segmentation fault (core dumped) error. After debugging I realized its because of line:
value += get_pixel(filter, fix, fiy, 0) * get_pixel(im, rx, ry, imc);
When I gave fixed values of rx
and ry
, the program executes successfully. Inside the loop I printed the values of imx, imy, fix, fiy, rx, ry
and everything works until a portion of the image has processed; after uncertain time of loop then program crushes without any reason.
I'm sure that it cannot be a index bounds related because I truncated indexes inside get_pixel()
function below which I get stored value from a long array of floats.
float get_pixel(image im, int x, int y, int c) {
if(x > im.w) {x = im.w;}
else if(y > im.h) {y = im.h;}
else if(c > im.c) {c = im.c;}
else if(x < 0) {x = 0;}
else if(y < 0) {y = 0;}
else if(c < 0) {c = 0;}
int index = (c * (im.h * im.w)) + (y * im.w) + x;
return im.data[index];
}
Here is my thought about this operation as pseudo-code:
create convolved_image with same dimensions
for every pixel (imx, imy) in image {
float value = 0;
for every pixel (fix, fiy) in filter {
// calculate relative pixel coordinates
int rx = imx - (filter / 2) + fix;
int ry = imy - (filter / 2) + fiy;
value += filter(fix, fiy) * image(rx, ry);
}
set pixel of convolved_image to value
}
Am I missing something? What is the fault in my approach? Or is there a better way for this operation?