I am currently implementing pyramids in Lucas Kanade algorithm for optical flow. To be able to build pyramids, I need to pad the images (mirror edge matrix elements) for the required amount of rows/cols determined by parameter half_window
.
I have written this code which works but I am new to C programming and it looks overly complex to me. How would an experienced C programmer write this?
image_t
is a struct for storing image data I am required to use. Rest is my code. It first adjusts sizes of output which is a pointer to struct image_t
object. Then it builds padded image row by row as follows:
- skip first
half_window
rows - mirror first
half_window
columns of the row - copy original elements of that row
- mirror the last
half_window
columns of the row - skip last
half_window
rows
Then
- mirror first
half_window
rows withmemcpy
- mirror last
half_window
rows withmemcpy
struct image_t {
enum image_type type; // The image type
uint16_t w; // Image width
uint16_t h; // Image height
struct timeval ts; // The timestamp of creation
uint8_t buf_idx; // Buffer index for V4L2 freeing
uint32_t buf_size; // The buffer size
void *buf; // Image buffer (depending on the image_type)
};
void pad_image(struct image_t *input, struct image_t *output, uint8_t half_window)
{
uint8_t *input_buf = (uint8_t *)input->buf;
output->h = input->h + 2*half_window;
output->w = input->w + 2*half_window;
output->buf_size = sizeof(uint8_t) * output->h * output->w;
free(output->buf);
output->buf = malloc(output->buf_size);
uint8_t *output_buf = (uint8_t*)output->buf;
for (int i = half_window; i != (output->h-half_window); i++){
for (int j=0; j!=half_window; j++)
output_buf[i*output->w + (half_window -1 - j)] = input_buf[(i-half_window)*input->w + j];
for (int j=half_window; j!=output->w-half_window;j++)
output_buf[i*output->w + j] = input_buf[(i-half_window)*input->w + (j - half_window)];
for (int j=0; j!=half_window;j++)
output_buf[i*output->w + output->w - half_window + j] = output_buf[i*output->w + output->w - half_window -1 - j];
}
for (int i=0; i!=half_window; i++){
memcpy(&output_buf[(half_window-1)*output->w - i*output->w], &output_buf[half_window*output->w + i*output->w], sizeof(uint8_t)*output->w);
memcpy(&output_buf[(output->h - half_window)*output->w + i*output->w], &output_buf[(output->h-half_window-1)*output->w - i*output->w], sizeof(uint8_t)*output->w);
}
}
Input:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
Expected output for half_window = 2
:
6 5 5 6 7 8 8 7 2 1 1 2 3 4 4 3 2 1 1 2 3 4 4 3 6 5 5 6 7 8 8 7 10 9 9 10 11 12 12 11 14 13 13 14 15 16 16 15 14 13 13 14 15 16 16 15 10 9 9 10 11 12 12 11