Thread: Issues With Edge Detection Program

  1. #1
    Registered User
    Join Date
    Oct 2020
    Posts
    3

    Issues With Edge Detection Program

    Hi, I am new to C programming and have only started learning the language in early September.

    I am trying to apply a horizontal filter to a small piece of an image and then apply the filter to the whole image. However, I am getting a weird output image and think it is due to my implementation of the Sobel edge detection.

    This is what I have so far:

    Code:
    #include <stdio.h>#include <stdlib.h>
    #include "iplib2New.c"
    
    
    # define n 3
    #define FILTER_SIZE 3
    
    
    //Function prototypes
    image_ptr read_pnm(char *filename, int *rows, int *cols, int *type);
    int getnum(FILE *fp);
    void write_pnm(image_ptr ptr, char *filename, int rows, int cols, int type);
    int apply_horizontal_filter(unsigned char small_block[FILTER_SIZE][FILTER_SIZE], int sobel_h[FILTER_SIZE][FILTER_SIZE], int sobel_v[FILTER_SIZE][FILTER_SIZE]);
    
    
    int ROWS, COLS, TYPE;
    
    
    int main(int argc, char **argv){
        int rows, cols, type;
        int i=0, j=0, x=0, y=0, value_h = 0; //Loop vars and conditions
        int tp; //File type
        double ave=0;
        char aveStr[10], *aveStrEnd;
        unsigned char small_block[n][n]; //sub block for image
    
    
        image_ptr imagePtr, imagePtr2; //image pointer types
        image_ptr imageNegPtr;
    
    
        //Creating sobel filters
        int sobel_h[3][3] = {-1, -2, -1, 0, 0, 0, 1, 2, 1}; //Horizontal
        int sobel_v[3][3] = {-1, 0, 1, -2, 0, 2, -1, 0, 1}; //Vertical
    
    
        /* check inputs */
        if (argc != 4){
            printf("wrong inputs: use %s infile out1 out2 \n", argv[0]);  
            return 0;
        }
    
    
        /* first read-in the image */
        printf("\nReading input image... \n");
    
    
        //Pointer to access the whole image
        imagePtr = read_pnm(argv[1], &rows, &cols, &type); //Returns ptr from read_pnm
    
    
        printf("\nYour image was read successfully!\n");
        printf("Info about your image: rows = %d, cols = %d, type = %d\n", rows, cols, type);
        unsigned char image2[rows][cols];  /* space for output image */
    
    
        //Going over the whole image
        for(i=0; i<rows; i++) //The height of the image
        {
            for(j=0; j<cols; j++) //The width of the image
            {
    
    
                //Picking up our sub block of the image
                for(y=0; y<n; y++) //Width of the sub block - cols
                {
                    for(x=0; x<n; x++) //Height of the sub block - rows
                    {
                        small_block[x][y]=imagePtr[(i+x)*cols+(j+y)];
                    }
                }
                //Analyze sub block here
                //printf("Analyzing a sub block...\n");
                value_h = apply_horizontal_filter(small_block, sobel_h, sobel_v);
                
                //Update output image
                image2[i][j] = value_h;
            }
        }
    
    
        printf("\nPicked up a piece of image.\n");
    
    
        tp = 5;
    
    
        imagePtr2 = (image_ptr)image2;
    
    
        printf("\nNow writing to image file ... \n");
        printf("rows=%d, cols=%d, type=%d \n", rows, cols, tp);
    
    
        write_pnm(imagePtr2, argv[2], rows, cols, tp); //Creating the out1.pgm
     
        /* image negatives  */
        imageNegPtr=(image_ptr)malloc(rows*cols*(sizeof(unsigned char)) );
    
    
        printf("\nNow writing negative image file ... \n");
        printf("rows=%d, cols=%d, type=%d \n", rows, cols, type);
     
        write_pnm(imageNegPtr, argv[3], rows, cols, type);  //Creating the out2.pgm
    
    
        return 0;
    }
    
    
    int apply_horizontal_filter(unsigned char small_block[n][n], int sobel_h[3][3], int sobel_v[3][3]){
        int x = 0;
        int y = 0;
        int pixel_value_h = 0;
        unsigned char filtered_block[3][3];
    
    
        for(x = 0; x<3; x++){
            for(y=0; y<3; y++){
                pixel_value_h += sobel_h[x][y]*small_block[x][y];
            }
        }
        return pixel_value_h;
    }


    This is the image I am testing as well as the output my code produces for
    Issues With Edge Detection Program-screen-shot-2020-11-01-1-38-57-pm-jpg
    Last edited by marshie; 11-01-2020 at 12:43 PM.

  2. #2
    Registered User
    Join Date
    Sep 2020
    Posts
    425
    Hi,

    The Sobel operator will return both + and - gradient values, but if you use the raw values you will have an overflow, causing bright values.

    Try this for line 123:



    Code:
    return abs(pixel_value_h);
    Please let me know how you get on...
    Last edited by hamster_nz; 11-01-2020 at 02:14 PM.

  3. #3
    Registered User
    Join Date
    Sep 2020
    Posts
    425
    Also, you might find that 'soft' pictures like this are a bad test case. you need some hard edges for the effect to be most visible.

    Just to show off a little, here's a project I did on an FPGA:

    Real-time 1080p edge detection in FPGA - YouTube

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Windows 10 Microsoft Edge Browser Issues
    By Osman Zakir in forum Tech Board
    Replies: 7
    Last Post: 08-05-2015, 06:50 PM
  2. repeated word detection program - help needed
    By Osman Zakir in forum C++ Programming
    Replies: 3
    Last Post: 04-02-2015, 02:26 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. Help with simple deadlock detection program
    By deheerwassenaar in forum C Programming
    Replies: 4
    Last Post: 05-02-2013, 03:06 AM

Tags for this Thread