1

Let me start by saying I am very newbie at C++ and so I don't really know the best practices or handle very well with the syntax. I'm trying to read a black and white image, and using the sobel algorithm to detect its edges and output the result, but halfway my execution I get an error:

munmap_chunk(): invalid pointer
Aborted (core dumped)

Though the image is outputted, it's only half of it and I can't seem to figure out whats causing this.

I wrote the following code:

#include <iostream>
#include <omp.h>
#include "CImg.h"
using namespace std;
using namespace cimg_library;

int main() {
    const int x_mask [9] = {
        -1, 0, 1,
        -2, 0, 2,
        -1, 0, 1
    };

    const int y_mask [9] = {
        -1, -2, -1,
        0, 0, 0,
        1, 2, 1
    };

    const char* fileName = "test.png";
    CImg<float> img = CImg<float>(fileName);
    
    int cols = img.width();
    int lines = img.height();
    CImg<float> output = CImg<float>(cols, lines, 1, 1, 0.0);
    printf("Loading %d x %d image...\n", cols, lines);
    const int mask_size = 3;

    int gradient_x;
    int gradient_y;
    // Loop through image ignoring borders
    for(int i = 1; i<cols-1; i++) {
        for(int j = 1; j<lines-1; j++){
            output(j,i) = 0;
            gradient_x = 0;
            gradient_y = 0;

            // Find the x_gradient and y_gradient
            for(int m = 0; m < mask_size; m++) {
                for(int n = 0; n < mask_size; n++) {
                    // Neighbourgh pixels
                    int np_x = j + (m - 1);
                    int np_y = i + (n - 1);

                    float v = img(np_x,np_y);

                    int mask_index = (m*3) + n;

                    gradient_x = gradient_x + (x_mask[mask_index] * v);
                    gradient_y = gradient_y + (y_mask[mask_index] * v);
                }
            }
            float gradient_sum = sqrt((gradient_x * gradient_x) + (gradient_y * gradient_y));
            if(gradient_sum >= 255) {
                gradient_sum = 255;
            } else if(gradient_sum <= 0) {
                gradient_sum = 0;
            }
            output(j, i) = gradient_sum;
        }
    }
    printf("Outputed image of size %d x %d\n", output.width(), output.height());
    output.save("test_edges.png");
 return 0;
}

Applied to this image:

Input image

I get this ouput: Output

1201ProgramAlarm
  • 32,384
  • 7
  • 42
  • 56
Phil
  • 175
  • 8
  • You create `img` with "cols, lines" order, but when indexing you use "lines, cols" order which could mean that you have the indexes swapped. Also, since the images seems to be roughly square this could indicate you have the indexing reversed. – 1201ProgramAlarm Mar 30 '21 at 14:26
  • @1201ProgramAlarm Could you be more explicit? I don't think I have it swapped – Phil Mar 30 '21 at 14:31
  • because j only goes up to the number of lines? – user253751 Mar 30 '21 at 14:34
  • [`operator()`](https://cimg.eu/reference/structcimg__library_1_1CImg.html#accb8526e4303186fb6246ac1301fdf66) for CImg is ordered `x, y` just like in the constructor. You need to index with `output(i,j)'. – 1201ProgramAlarm Mar 30 '21 at 14:39
  • @1201ProgramAlarm If I change it like you say the image is rotated 90º and is duplicated, but i get no errors now – Phil Mar 30 '21 at 14:47
  • @1201ProgramAlarm I changed how I acessed my initial image and so everything is correct now. Thank you very much – Phil Mar 30 '21 at 14:50
  • The moral of this tale, perhaps. Naming variables `(x,y)` or `(row,col)` may be less error-prone than the more abstract `(i,j)` – Tim Randall Mar 30 '21 at 15:02

0 Answers0