Thread: Edge Detection Of A PPM Image In C?

  1. #1
    Registered User
    Join Date
    Dec 2021
    Posts
    34

    Edge Detection Of A PPM Image In C?

    So far this is what I've got:

    What I'm trying to do is read in a PPM, store it in an array (done), then prompt the user to enter a threshold. Then detect the edges in an image and output to a new internal array image where pixels that are part of an edgeare white, other pixels are black.

    I've been given this formula:
    grad = abs(im(x+1, y) - im(x-1, y)) + abs(im(x, y+1) - im(x, y-1))
    and am told to compare it to a threshold then sum grad over the colour channels. Any pointers would be welcome. Thanks.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    
    #define maxheight 1080
    #define maxwidth 1920
    #define RGB_COMPONENT_COLOUR 255
    #define pgmtype "P2"
    #define ppmtype "P3"
    
    
    typedef struct
    {
        int red, green, blue;
    } PPMPixel;
    
    
    typedef struct
    {
        int x, y;
        //PPMPixel *data;
    } PPMImage;
    
    
    typedef struct 
    {
        int rgb_comp_colour;
        char filetype[3];
        int height;
        int width;
    } PPMHead;
    
    
    PPMHead head[3];
    
    
    PPMPixel r;
    
    
    PPMPixel data; //Defines pointer to PPMPixel
    PPMPixel **EdgeArray;
    
    void edge_detection()
    {
        int i, j;
        FILE *fed;
        char fnameed[100];
        printf("\tEnter first file's name: \n");
        scanf("%s", fnameed);
        fseek(stdin,0,SEEK_END);
        fed = fopen(fnameed, "r");
        if (fed == NULL)
        {   
            printf("\tError while opening the file\n");
        }
        else    
        {
            printf("\tWriting in %s\n", fnameed);
        }
    
    
        fscanf(fed, "%s %d %d %d", head[3].filetype, &head[3].width, &head[3].height, &head[3].rgb_comp_colour);
        printf("%s %d %d %d", head[3].filetype, head[3].width, head[3].height, head[3].rgb_comp_colour);
    
    
        EdgeArray = (PPMPixel **)malloc(head[3].height*sizeof(PPMPixel*)); //Points to malloc
        if((EdgeArray == NULL))
        {
            printf("\tError allocating memory to the array\n");
        }
        else
        {
            printf("\tMemory allocated to the PPM array sucessfully\n");
        }
        for (i=0;i<head[3].height;i++)
        {
            EdgeArray[i] = (PPMPixel *)malloc(head[3].width*sizeof(PPMPixel));
        }
        
        //Initialising each element
        for (j=0;j<head[3].height;j++)
        {
            for (i=0;i<head[3].width;i++)
            {
                fscanf(fed, "%d %d %d ", &r.red, &r.green, &r.blue);
                PPMPixel* data = &EdgeArray[j][i];
                data->red = r.red;
                data->green = r.green;
                data->blue = r.blue;
            }
        }
    }

  2. #2
    Registered User
    Join Date
    Apr 2021
    Posts
    92
    That doesn't look like edge detection. It looks like reading the image from a file.

    Why not pull that out as a separate function, put in a main(), and go from there?

  3. #3
    Registered User
    Join Date
    Sep 2020
    Posts
    339
    I compiled with warnings on - be mindful that C arrays start at element 0!

    Code:
    main.c:64:80: warning: array subscript 3 is above array bounds of ‘PPMHead[3]’ {aka ‘struct <anonymous>[3]’} [-Warray-bounds]
       64 |     printf("%s %d %d %d", head[3].filetype, head[3].width, head[3].height, head[3].rgb_comp_colour);
          |                                                                            ~~~~^~~
    main.c:35:9: note: while referencing ‘head’
       35 | PPMHead head[3];
          |         ^~~~
    main.c:64:64: warning: array subscript 3 is above array bounds of ‘PPMHead[3]’ {aka ‘struct <anonymous>[3]’} [-Warray-bounds]
       64 |     printf("%s %d %d %d", head[3].filetype, head[3].width, head[3].height, head[3].rgb_comp_colour);
          |                                                            ~~~~^~~
    main.c:35:9: note: while referencing ‘head’
       35 | PPMHead head[3];
          |         ^~~~
    main.c:64:49: warning: array subscript 3 is above array bounds of ‘PPMHead[3]’ {aka ‘struct <anonymous>[3]’} [-Warray-bounds]
       64 |     printf("%s %d %d %d", head[3].filetype, head[3].width, head[3].height, head[3].rgb_comp_colour);
          |                                             ~~~~^~~
    main.c:35:9: note: while referencing ‘head’
       35 | PPMHead head[3];
          |         ^~~~
    main.c:67:41: warning: array subscript 3 is above array bounds of ‘PPMHead[3]’ {aka ‘struct <anonymous>[3]’} [-Warray-bounds]
       67 |     EdgeArray = (PPMPixel **)malloc(head[3].height*sizeof(PPMPixel*)); //Points to malloc
          |                                     ~~~~^~~
    main.c:35:9: note: while referencing ‘head’
       35 | PPMHead head[3];
          |         ^~~~
    main.c:76:20: warning: array subscript 3 is above array bounds of ‘PPMHead[3]’ {aka ‘struct <anonymous>[3]’} [-Warray-bounds]
       76 |     for (i=0;i<head[3].height;i++)
          |                ~~~~^~~
    main.c:35:9: note: while referencing ‘head’
       35 | PPMHead head[3];
          |         ^~~~
    main.c:82:20: warning: array subscript 3 is above array bounds of ‘PPMHead[3]’ {aka ‘struct <anonymous>[3]’} [-Warray-bounds]
       82 |     for (j=0;j<head[3].height;j++)
          |                ~~~~^~~
    main.c:35:9: note: while referencing ‘head’
       35 | PPMHead head[3];
          |         ^~~~
    main.c:84:24: warning: array subscript 3 is above array bounds of ‘PPMHead[3]’ {aka ‘struct <anonymous>[3]’} [-Warray-bounds]
       84 |         for (i=0;i<head[3].width;i++)
          |                    ~~~~^~~
    main.c:35:9: note: while referencing ‘head’
       35 | PPMHead head[3];
          |         ^~~~
    main.c:78:47: warning: array subscript 3 is above array bounds of ‘PPMHead[3]’ {aka ‘struct <anonymous>[3]’} [-Warray-bounds]
       78 |         EdgeArray[i] = (PPMPixel *)malloc(head[3].width*sizeof(PPMPixel));
          |                                           ~~~~^~~
    main.c:35:9: note: while referencing ‘head’
       35 | PPMHead head[3];

  4. #4
    Registered User
    Join Date
    Sep 2020
    Posts
    339
    I think you need to do something like this:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    
    typedef struct
    {
        int red, green, blue;
    } PPMPixel;
    
    
    typedef struct
    {
        int rgb_comp_colour;
        char filetype[3];
        int width,height;
        PPMPixel **data;
    } PPMImage;
    
    
    PPMImage *ppm_create(int height, int width) {
       PPMImage *image;
       // TODO: Allocate storage for the header (PPMImage)
       // TODO: Populate header
       // TODO: Allocate storage for the list of lines (image->height * sizeof(PPMPixel *));
       // TODO: Allocate storage for each line  (image->width * sizeof(PPMPixel))
       // TODO: Zero out the data
       return image; // Return NULL if unable to create image
    }
    
    
    PPMImage *ppm_read(char *fname) {
       PPMImage *image;
       // TODO: Allocate storage for the header
       // TODO: Read the header
       // TODO: Allocate storage for the list of lines
       // TODO: Allocate storage for each line
       // TODO: Read in each line
       return image; // Return NULL if unable to read in image
    }
    
    
    void ppm_free(PPMImage *img) {
       // Free lines
       for(int i = 0; i < img->height; i++)
           free(img->data[i]);
    
    
       // Free list of lines
       free(img->data);
    
    
       // Free header
       free(img);
    }
    
    
    int ppm_write(PPMImage *img, char *file_name) {
       // TODO: Open the file, return 0 if fails
       // TODO: Write out the header
       // TODO: Write out the pixel data
       return 1; // Success!
    }
    
    
    void ppm_edge_detect(PPMImage *src, PPMImage *dest)
    {
      // TODO: process the data in 'src' to generate 'dest'
    }
    
    
    int main(int argc, char *argv[]) {
       PPMImage *src, *dest;
    
    
       src  = ppm_read("input.ppm");
       // TODO: need to check src is not NULL
    
    
       dest = ppm_create(src->width, src->height);
       // TODO: need to check dest is not NULL
    
    
       ppm_edge_detect(src,dest);
       ppm_write(dest, "output.ppm");
       // TODO: Need to check that the write succeeds
    
    
       ppm_free(src);
       ppm_free(dest);
       return 0;
    }

  5. #5
    Registered User
    Join Date
    Jan 2022
    Posts
    6
    Code:
    FILE *f = fopen("test.ppm", "r+a+");
    if (f == NULL)
    {
    perror("Unable to open file!");
    exit(1);
    }
    char *line;
    size_t len = 0;
    int n = 0;
    int a, b, c;
    int aa, bb, cc;
    
    while (getline(&line, &len, f) != -1) {
      if (n > 3) {
        if (n % 2 == 0) {
          sscanf(line, "%d %d %d", &a, &b, &c);
        } else {
          sscanf(line, "%d %d %d", &aa, &bb, &cc);
        }
        if (aa - a > threshold || bb - b > threshold || cc - c > threshold) {
          coordinates cord = returnarrayindex(n);
          printf("#%d::%d %d %d at x(%d),y(%d)\n", n, aa - a, bb - b, cc - c,
                 cord.x, cord.y);
          buf[cord.x][cord.y] = "0 0 0";
        }
      } else if (n > 2) {
        sscanf(line, "%d %d %d", &aa, &bb, &cc);
      }
      n++;
    }
    
    fclose(f);
    }
    Last edited by Salem; 01-14-2022 at 10:02 PM. Reason: Removed crayola

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Edge Detection Program//Segmentation fault: 11
    By marshie in forum C Programming
    Replies: 4
    Last Post: 11-03-2020, 01:52 AM
  2. Issues With Edge Detection Program
    By marshie in forum C Programming
    Replies: 2
    Last Post: 11-01-2020, 02:12 PM
  3. Edge Detection done using processes and pipes
    By Bakenshake in forum C Programming
    Replies: 10
    Last Post: 12-04-2014, 09:14 AM
  4. Sobel Edge Detection
    By Bakenshake in forum C Programming
    Replies: 15
    Last Post: 11-23-2014, 01:44 AM
  5. Image Detection
    By Stormcrow in forum C# Programming
    Replies: 0
    Last Post: 04-22-2006, 06:45 AM

Tags for this Thread