Thread: Edge Detection done using processes and pipes

  1. #1
    Registered User
    Join Date
    Sep 2013
    Posts
    49

    Edge Detection done using processes and pipes

    I don't think my processes are being created the way I want. I'm trying to create a fan of process (i.e. one parent with multiple children).

    I want the parent to put together the final output image, and the children are supposed to do the edge detection on various regions of the image.

    Here is what I have:

    Code:
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <math.h>
    #include <string.h>
    #include "iplib2New.c"
    #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 apply_vertical_filter(unsigned char small_block[FILTER_SIZE][FILTER_SIZE], int sobel_v[FILTER_SIZE][FILTER_SIZE]);
    int main(int argc, char **argv)
    {
     int f_des[2]; //Two ends of our pipe
     static int message[5]; //message container for our image results to send into the pipe
     int pid, childpid;
     int rows, cols, type, row_pos, col_pos, pixelID; //Basic image info
     image_ptr imagePtr, imagePtr2; //image pointer types
     //image_ptr imageNegPtr;
     int sobel_h[FILTER_SIZE][FILTER_SIZE] = {-1, -2, -1, 0, 0, 0, 1, 2, 1}; //Horizontal Sobel filter
     int sobel_v[FILTER_SIZE][FILTER_SIZE] = {-1, 0, 1, -2, 0, 2, -1, 0, 1}; //Vertical Sobel filter
     unsigned char small_block[FILTER_SIZE][FILTER_SIZE]; //sub block for image
     int i=0, j=0, x=0, y=0, p=0, k=0, l=0, m=0; //Loop variables...big image, small block, # of processes, process management
     int value_h = 0, value_v = 0, value_both = 0, binarized_pixel_value; //pixel values for 3 x 3 small_block horizontally, vertically, and both
     double edge_mean, edge_std_dev, edge_threshold; //Creating the threshold to binarize the image
     int tp; //File type
     double ave=0; //??
     char aveStr[10], *aveStrEnd;
     
     //Create the pipe and check if it fails - gives both ends of the pipe to the child since it's created before the fork()
     if (pipe(f_des) == -1)
     {
      printf("Pipe failed.");
     }
     
     //Check inputs
     if (argc != 6)
     {
      printf("wrong inputs: use %s infile out1 out2 out3 p \n", argv[0]); //p is the # of processes
     } 
     
     //Reading the image in
     printf("\nReading input image... \n");
     //Pointer to access the whole image
     imagePtr = read_pnm(argv[1], &rows, &cols, &type); //Returns ptr from read_pnm - why &type?
     //Notifying the user
     printf("\nYour image was read successfully!\n");
     printf("Info about your image: rows = %d, cols = %d, type = %d\n", rows, cols, type);
     
     //Has to be created here after the image has been read in by read_pnm so rows and cols have correct values
     unsigned char horizontal_edge_image[rows][cols]; 
     unsigned char vertical_edge_image[rows][cols];
     unsigned char both_edges_image[rows][cols];
     unsigned char binarized_edge_image[rows][cols];
     
     //Convert p from string to int atoi()
     p = 4;
     //Outer loop for determining the level of process we're at aka which process we're on
     for(k=0; k<p; k++) //Creating all of our children 
     {
      if((childpid = fork()) <= 0) {} //Create only a child...Note: no braces
     }
     
     pixelID = 0; //Our initial image position
     
     //If child do these 4 for loops to analyse each sub block of the image
     if(childpid == 0)
     {
      //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
       {
        pixelID++;
        if(pixelID%p == k) 
        { 
         //Making sure the right process is doing the correct region of the image
         //Picking up our sub block of the image
         for(y=0; y<FILTER_SIZE; y++) //Width of the sub block - cols
         {
          for(x=0; x<FILTER_SIZE; x++) //Height of the sub block - rows
          {
           small_block[x][y]=imagePtr[(i+x)*cols+(j+y)];
          }
         }
        }
        //Analyze sub blocks horizontally and vertically here
        value_h = apply_horizontal_filter(small_block, sobel_h);
        value_v = apply_vertical_filter(small_block, sobel_v);
        //Both edges together - E(x,y)
        value_both = value_h + value_v;
        
        //Will need to send the above^ 3 values to the pipe aka write this to the pipe
        //array of pipe will be...pixelID, hE, vE, hvE
        
        //Instead of pixelID, sending i,j pos in image
        row_pos = i;
        col_pos = j;
        
        //Putting the values in the message container for the pipe
        row_pos = message[0];
        col_pos = message[1];
        value_h = message[2];
        value_v = message[3];
        value_both = message[4];
        
        //Writing to the pipe
        //before writing, make sure other end is closed
        close(f_des[0]);
        if(write(f_des[1], message, sizeof(message)) != -1)
        {
         printf("Writing to pipe.\n");
         fflush(stdout);
        }
        else
        {
         perror("Write:");
        }
       }
      }
     }
     else
     {
      //Else if parent do these 2 for loops to update the output image
      //The parent will have to read from the pipe to know where and what to update in the output image
      
      for(i=0; i<rows; i++)
      {
       for(j=0; j<cols; j++)
       {
        //Also close the other end of the pipe?
        //Read from the pipe here - will I need to flush the pipe every time it reads?
        //Organize new image
        close(f_des[1]);
        if(read(f_des[0], message, sizeof(message)) != -1)
        {
         printf("Reading pipe.\n");
         fflush(stdout);
        }
        else
        {
         perror("Read:");
        }
        
        //Update output images - The parent will do this now
        //Should be i,j or vars from pipe?
        horizontal_edge_image[message[0]][message[1]] = (unsigned char)abs(message[2]);
        vertical_edge_image[i][j] = (unsigned char)abs(value_v);
        both_edges_image[i][j] = (unsigned char)abs(value_both);
       }
      }
      
      //Now begin writing the image file
      tp = 5; //Setting the file type to be read/write as PGM
      imagePtr2 = (image_ptr)horizontal_edge_image; //Assign pointer to write image
      printf("\nNow writing Horizontal edge image...\n");
      write_pnm(imagePtr2, argv[2], rows, cols, tp); //Creating the horizontal edge
      imagePtr2 = (image_ptr)vertical_edge_image; //Reassigning our ptr for next img
      printf("\nNow writing Vertical edge image...\n");
      write_pnm(imagePtr2, argv[3], rows, cols, tp); //Creating the vertical edge
      imagePtr2 = (image_ptr)both_edges_image; //Reassign the pointer
      printf("\nNow writing Both edges image...\n");
      write_pnm(imagePtr2, argv[4], rows, cols, tp); //Creating the image of both edges
     }
     /* image negatives  */
    // imageNegPtr=(image_ptr)malloc(rows*cols*(sizeof(unsigned char)) );
     // ... codes for image negative here 
     
    // 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[FILTER_SIZE][FILTER_SIZE], int sobel_h[3][3])
    {
     int x = 0;
     int y = 0;
     int pixel_value_h = 0;
     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;
    }
    int apply_vertical_filter(unsigned char small_block[FILTER_SIZE][FILTER_SIZE], int sobel_v[3][3])
    {
     int x = 0;
     int y = 0;
     int pixel_value_v = 0;
     for(x = 0; x<3; x++)
     {
      for(y=0; y<3; y++)
      {
       pixel_value_v += sobel_v[x][y]*small_block[x][y];
      }
     }
     return pixel_value_v;
    }

  2. #2
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    To help others read this:
    Code:
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <math.h>
    #include <string.h>
    #include "iplib2New.c"
    
    #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 apply_vertical_filter(unsigned char small_block[FILTER_SIZE][FILTER_SIZE], int sobel_v[FILTER_SIZE][FILTER_SIZE]);
    
    int main(int argc, char **argv)
    {
        int f_des[2]; //Two ends of our pipe
        static int message[5]; //message container for our image results to send into the pipe
        int pid, childpid;
        int rows, cols, type, row_pos, col_pos, pixelID; //Basic image info
        image_ptr imagePtr, imagePtr2; //image pointer types
        //image_ptr imageNegPtr;
        int sobel_h[FILTER_SIZE][FILTER_SIZE] = { -1, -2, -1, 0, 0, 0, 1, 2, 1}; //Horizontal Sobel filter
        int sobel_v[FILTER_SIZE][FILTER_SIZE] = { -1, 0, 1, -2, 0, 2, -1, 0, 1}; //Vertical Sobel filter
        unsigned char small_block[FILTER_SIZE][FILTER_SIZE]; //sub block for image
        int i = 0, j = 0, x = 0, y = 0, p = 0, k = 0, l = 0, m = 0; //Loop variables...big image, small block, # of processes, process management
        int value_h = 0, value_v = 0, value_both = 0, binarized_pixel_value; //pixel values for 3 x 3 small_block horizontally, vertically, and both
        double edge_mean, edge_std_dev, edge_threshold; //Creating the threshold to binarize the image
        int tp; //File type
        double ave = 0; //??
        char aveStr[10], *aveStrEnd;
    
        //Create the pipe and check if it fails - gives both ends of the pipe to the child since it's created before the fork()
        if (pipe(f_des) == -1)
        {
            printf("Pipe failed.");
        }
    
        //Check inputs
        if (argc != 6)
        {
            printf("wrong inputs: use %s infile out1 out2 out3 p \n", argv[0]); //p is the # of processes
        }
    
        //Reading the image in
        printf("\nReading input image... \n");
        
        //Pointer to access the whole image
        imagePtr = read_pnm(argv[1], &rows, &cols, &type); //Returns ptr from read_pnm - why &type?
        
        //Notifying the user
        printf("\nYour image was read successfully!\n");
        printf("Info about your image: rows = %d, cols = %d, type = %d\n", rows, cols, type);
    
        //Has to be created here after the image has been read in by read_pnm so rows and cols have correct values
        unsigned char horizontal_edge_image[rows][cols];
        unsigned char vertical_edge_image[rows][cols];
        unsigned char both_edges_image[rows][cols];
        unsigned char binarized_edge_image[rows][cols];
    
        //Convert p from string to int atoi()
        p = 4;
    
        //Outer loop for determining the level of process we're at aka which process we're on
        for (k = 0; k < p; k++) //Creating all of our children
        {
            if ((childpid = fork()) <= 0) {} //Create only a child...Note: no braces
        }
    
        pixelID = 0; //Our initial image position
    
        //If child do these 4 for loops to analyse each sub block of the image
        if (childpid == 0)
        {
            //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
                {
                    pixelID++;
                    if (pixelID % p == k)
                    {
                        //Making sure the right process is doing the correct region of the image
                        //Picking up our sub block of the image
                        for (y = 0; y < FILTER_SIZE; y++) //Width of the sub block - cols
                        {
                            for (x = 0; x < FILTER_SIZE; x++) //Height of the sub block - rows
                            {
                                small_block[x][y] = imagePtr[(i + x) * cols + (j + y)];
                            }
                        }
                    }
                    //Analyze sub blocks horizontally and vertically here
                    value_h = apply_horizontal_filter(small_block, sobel_h);
                    value_v = apply_vertical_filter(small_block, sobel_v);
                    //Both edges together - E(x,y)
                    value_both = value_h + value_v;
    
                    //Will need to send the above^ 3 values to the pipe aka write this to the pipe
                    //array of pipe will be...pixelID, hE, vE, hvE
    
                    //Instead of pixelID, sending i,j pos in image
                    row_pos = i;
                    col_pos = j;
    
                    //Putting the values in the message container for the pipe
                    row_pos = message[0];
                    col_pos = message[1];
                    value_h = message[2];
                    value_v = message[3];
                    value_both = message[4];
    
                    //Writing to the pipe
                    //before writing, make sure other end is closed
                    close(f_des[0]);
                    if (write(f_des[1], message, sizeof(message)) != -1)
                    {
                        printf("Writing to pipe.\n");
                        fflush(stdout);
                    }
                    else
                    {
                        perror("Write:");
                    }
                }
            }
        }
        else
        {
            //Else if parent do these 2 for loops to update the output image
            //The parent will have to read from the pipe to know where and what to update in the output image
    
            for (i = 0; i < rows; i++)
            {
                for (j = 0; j < cols; j++)
                {
                    //Also close the other end of the pipe?
                    //Read from the pipe here - will I need to flush the pipe every time it reads?
                    //Organize new image
                    close(f_des[1]);
                    if (read(f_des[0], message, sizeof(message)) != -1)
                    {
                        printf("Reading pipe.\n");
                        fflush(stdout);
                    }
                    else
                    {
                        perror("Read:");
                    }
    
                    //Update output images - The parent will do this now
                    //Should be i,j or vars from pipe?
                    horizontal_edge_image[message[0]][message[1]] = (unsigned char)abs(message[2]);
                    vertical_edge_image[i][j] = (unsigned char)abs(value_v);
                    both_edges_image[i][j] = (unsigned char)abs(value_both);
                }
            }
    
            //Now begin writing the image file
            tp = 5; //Setting the file type to be read/write as PGM
            imagePtr2 = (image_ptr)horizontal_edge_image; //Assign pointer to write image
            printf("\nNow writing Horizontal edge image...\n");
            write_pnm(imagePtr2, argv[2], rows, cols, tp); //Creating the horizontal edge
            imagePtr2 = (image_ptr)vertical_edge_image; //Reassigning our ptr for next img
            printf("\nNow writing Vertical edge image...\n");
            write_pnm(imagePtr2, argv[3], rows, cols, tp); //Creating the vertical edge
            imagePtr2 = (image_ptr)both_edges_image; //Reassign the pointer
            printf("\nNow writing Both edges image...\n");
            write_pnm(imagePtr2, argv[4], rows, cols, tp); //Creating the image of both edges
        }
        /* image negatives  */
        // imageNegPtr=(image_ptr)malloc(rows*cols*(sizeof(unsigned char)) );
        // ... codes for image negative here
    
        // 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;
    }//main
    
    int apply_horizontal_filter(unsigned char small_block[FILTER_SIZE][FILTER_SIZE], int sobel_h[3][3])
    {
        int x = 0;
        int y = 0;
        int pixel_value_h = 0;
        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;
    }//apply_horizontal_filter
    
    int apply_vertical_filter(unsigned char small_block[FILTER_SIZE][FILTER_SIZE], int sobel_v[3][3])
    {
        int x = 0;
        int y = 0;
        int pixel_value_v = 0;
        for (x = 0; x < 3; x++)
        {
            for (y = 0; y < 3; y++)
            {
                pixel_value_v += sobel_v[x][y] * small_block[x][y];
            }
        }
        return pixel_value_v;
    }//apply_vertical_filter
    And - http://www.csee.wvu.edu/~adjeroh/cla...fo/iplib2New.c

    gg

  3. #3
    Registered User
    Join Date
    Sep 2013
    Posts
    49
    Thanks and sorry about that. Any help would be appreciated.

    Code:
    /*************************************************************************** 
     * File: iplib.c                                                           *
     *                                                                         *
     * Desc: general routines for reading and writing ppm files.               *
     * Modified from: Crane R, "A simplified approach to image processing",1997*
     ***************************************************************************/
    
    #include <stdio.h>
    #include <stdlib.h>
    
    /* file types*/
    #define PBM 4
    #define PGM 5
    #define PPM 6
    
    typedef unsigned char *image_ptr;
    
    
    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 ROWS, COLS, TYPE;
    
    /***************************************************************************
     * Func: read_pnm                                                          *
     *                                                                         *
     * Desc: reads a portable bitmap file                                      *
     *                                                                         *
     * Params: filename - name of image file to read                           *
     *         rows - number of rows in the image                              *
     *         cols - number of columns in the image                           *
     *         type - file type                                                *
     *                                                                         *
     * Returns: pointer to the image just read into memory                     *
     ***************************************************************************/
    
    image_ptr read_pnm(char *filename, int *rows, int *cols, int *type)
        {
        int i;                     /* index variable */
        int row_size;              /* size of image row in bytes */
        int maxval;                /* maximum value of pixel */
        FILE *fp;                  /* input file pointer */
        int firstchar, secchar;    /* first 2 characters in the input file */
        image_ptr ptr;             /* pointer to image buffer */
        unsigned long offset;      /* offset into image buffer */
        unsigned long total_size;  /* size of image in bytes */
        unsigned long total_bytes; /* number of total bytes written to file */
        float scale;               /* number of bytes per pixel */
    
     
        /* open input file */
         if((fp = fopen(filename, "rb")) == NULL)
        {
        printf("Unable to open %s for reading\n",filename);
        exit(1);
        }
    
        firstchar = getc(fp);
        secchar = getc(fp);
        printf("Second char %d \n", secchar); 
        
        if(firstchar != 'P')
        {
        printf("Sorry... This is not a PPM file!\n");
        exit(1);
        }
    
    
         *cols = getnum(fp);
         *rows = getnum(fp);
         *type = secchar - '0';
        
        ROWS = *rows; COLS = *cols; TYPE = *type; 
     
        switch(secchar)
        {
        case '4':            /* PBM */
            scale = 0.125;
            maxval = 1;
            break;
        case '5':            /* PGM */
            scale = 1.0;
            maxval = getnum(fp);
            break;
        case '6':             /* PPM */
            scale = 3.0;
            maxval = getnum(fp);
            break;
        default :             /* Error */
            printf("read_pnm: This is not a Portable bitmap RAWBITS file\n");
            exit(1);
            break;
        }
        
        row_size = (*cols) * scale;
        total_size = (unsigned long) (*rows) * row_size;
    
        ptr = (image_ptr) malloc(total_size);
    
        if(ptr == NULL)
        {
        printf("Unable to malloc %lu bytes\n",total_size);
        exit(1);
        }
    
        total_bytes=0;
        offset = 0;
        for(i=0; i<(*rows); i++)
        {
        total_bytes+=fread(ptr+offset, 1, row_size, fp);
        offset += row_size;
        }
    
        if(total_size != total_bytes)
        {
        printf("Failed miserably trying to read %ld bytes\nRead %ld bytes\n",
            total_size, total_bytes);
        exit(1);
        }
    
        fclose(fp);
        return ptr;
        }
    
    /***************************************************************************
     * Func: getnum                                                            *
     *                                                                         *
     * Desc: reads an ASCII number from a portable bitmap file header          *
     *                                                                         *
     * Param: fp - pointer to file being read                                  *
     *                                                                         *
     * Returns: the number read                                                *
     ***************************************************************************/
    
    int getnum(FILE *fp)
        {
        char c;               /* character read in from file */
        int i;                /* number accumulated and returned */
    
        do
        {
        c = getc(fp);
        }
        while((c==' ') || (c=='\t') || (c=='\n') || (c=='\r'));
    
        if((c<'0') || (c>'9'))
        if(c == '#')                   /* chew off comments */
            {
            while(c == '#')
            {
            while(c != '\n')
                c = getc(fp);
            c = getc(fp);
            }
            }
        else
            {
            printf("Garbage in ASCII fields\n");
            exit(1);
            }
        i=0;
        do
        {
        i=i*10+(c-'0');         /* convert ASCII to int */
        c = getc(fp);
        }
        while((c>='0') && (c<='9'));
      
        return i;
        }
    
    /***************************************************************************
     * Func: write_pnm                                                         *
     *                                                                         *
     * Desc: writes out a portable bitmap file                                 *
     *                                                                         *
     * Params: ptr - pointer to image in memory                                *
     *         filename _ name of file to write image to                       *
     *         rows - number of rows in the image                              *
     *         cols - number of columns in the image                           *
     *         magic_number - number that defines what type of file it is      *
     *                                                                         *
     * Returns: nothing                                                        *
     ***************************************************************************/
    
    void write_pnm(image_ptr ptr, char *filename, int rows, 
               int cols, int magic_number)
        {
        FILE *fp;             /* file pointer for output file */
        long offset;          /* current offset into image buffer */
        long total_bytes;     /* number of bytes written to output file */
        long total_size;      /* size of image buffer */
        int row_size;         /* size of row in bytes */
        int i;                /* index variable */
        float scale;          /* number of bytes per image pixel */
    
        switch(magic_number)
        {
        case 4:            /* PBM */
            scale = 0.125;
            break;
        case 5:            /* PGM */
            scale = 1.0;
            break;
        case 6:             /* PPM */
            scale = 3.0;
            break;
        default :             /* Error */
            printf("write_pnm: This is not a Portable bitmap RAWBITS file\n");
            exit(1);
            break;
        }
    
        /* open new output file */
        if((fp=fopen(filename, "wb")) == NULL)
        {
        printf("Unable to open %s for output\n",filename);
        exit(1);
        }
    
        /* print out the portable bitmap header */
        fprintf(fp, "P%d\n%d %d\n", magic_number, cols, rows);
        if(magic_number != 4)
        fprintf(fp, "255\n");
    
        row_size = cols * scale;
        total_size = (long) row_size *rows;
        offset = 0;
        total_bytes = 0;
        for(i=0; i<rows; i++)
        {
        total_bytes += fwrite(ptr+offset, 1, row_size, fp);
        offset += row_size;
        }
    
        if(total_bytes != total_size)
        printf("Tried to write %ld bytes...Only wrote %ld\n",
            total_size, total_bytes);
    
        fclose(fp);
        }
    Last edited by Bakenshake; 11-30-2014 at 09:33 PM.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Well these assignments are the wrong way round in the child.
    Code:
                    //Putting the values in the message container for the pipe
                    row_pos = message[0];
                    col_pos = message[1];
                    value_h = message[2];
                    value_v = message[3];
                    value_both = message[4];
    Also, you only need to close the unused end of the pipe ONCE inside the parent/children, not every time around the loop.

    Also, did you bother to prototype this in a small program, such as
    Code:
    int main(int argc, char **argv)
    {
        int f_des[2]; //Two ends of our pipe
        static int message[5]; //message container for our image results to send into the pipe
        int pid, childpid;
    
        //Create the pipe and check if it fails - gives both ends of the pipe to the child since it's created before the fork()
        if (pipe(f_des) == -1)
        {
            printf("Pipe failed.");
        }
    
        //Convert p from string to int atoi()
        p = 4;
    
        //Outer loop for determining the level of process we're at aka which process we're on
        for (k = 0; k < p; k++) //Creating all of our children
        {
            if ((childpid = fork()) <= 0) {} //Create only a child...Note: no braces
        }
    
        //If child do these 4 for loops to analyse each sub block of the image
        if (childpid == 0)
        {
            close(f_des[0]);
            //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
                {
                    message[0] = i;
                    message[1] = j;
                    message[2] = k;  // a unique child ID
                    if (write(f_des[1], message, sizeof(message)) != -1)
                    {
                        printf("Writing to pipe.\n");
                        fflush(stdout);
                    }
                    else
                    {
                        perror("Write:");
                    }
                }
            }
        }
        else
        {
            close(f_des[1]);
            for (i = 0; i < rows; i++)
            {
                for (j = 0; j < cols; j++)
                {
                    //Also close the other end of the pipe?
                    //Read from the pipe here - will I need to flush the pipe every time it reads?
                    //Organize new image
                    if (read(f_des[0], message, sizeof(message)) != -1)
                    {
                        printf("Reading pipe.\n");
                        fflush(stdout);
                    }
                    else
                    {
                        perror("Read:");
                    }
    
    //                print the message
                }
            }
        }
        return 0;
    }
    Get this working first, then merge it with your algorithm.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Sep 2013
    Posts
    49
    Quote Originally Posted by Salem View Post
    Well these assignments are the wrong way round in the child.
    Code:
                    //Putting the values in the message container for the pipe
                    row_pos = message[0];
                    col_pos = message[1];
                    value_h = message[2];
                    value_v = message[3];
                    value_both = message[4];
    I fixed this already after posting it. Haha, but that's not the only problem. Pretty sure it's with my pipe and my parent loops

    Also, you only need to close the unused end of the pipe ONCE inside the parent/children, not every time around the loop.
    Why is this? Should I clos the pipe before the loops but after the if statement then?

    Also, did you bother to prototype this in a small program, such as..
    It was working before without the processes, so I know that logic and algorithm for the image processing works but no I did not. So that should be my next step?

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Yes, your next step is to write a simple program using pipes in a 'fan' arrangement as you call it, to make sure you understand all the things that happen.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Registered User
    Join Date
    Sep 2013
    Posts
    49
    So now I'm running this, but even with the printouts...I'm not sure if I'm creating the right structure.

    Can someone verify for me?

    Code:
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <math.h>
    #include <string.h>
    
    int main(int argc, char **argv)
    {
        int f_des[2]; //Two ends of our pipe
        static int message[5]; //message container for our image results to send into the pipe
        int pid, childpid, i, j, k, p;
        //Create the pipe and check if it fails - gives both ends of the pipe to the child since it's created before the fork()
    
        if (pipe(f_des) == -1)
        {
            printf("Pipe failed.");
        }
    
        //Convert p from string to int atoi()
        p = 4;
    
        //Outer loop for determining the level of process we're at aka which process we're on
        for (k = 0; k < p; k++) //Creating all of our children
        {
            if ((childpid = fork()) <= 0) {} //Create only a child...Note: no braces
        }
    
        //If child do these 4 for loops to analyse each sub block of the image
        if (childpid == 0)
        {
            close(f_des[0]);
            //Going over the whole image
            for (i = 0; i < 5; i++) //The height of the image
            {
                for (j = 0; j < 5; j++) //The width of the image
                {
                    message[0] = i;
                    message[1] = j;
                    message[2] = k;  // a unique child ID
                    
                    if (write(f_des[1], message, sizeof(message)) != -1)
                    {
                        printf("C: I am process %ld with parent %ld\n", (long)getpid(), (long)getppid());
                        fflush(stdout);
                    }
                    else
                    {
                        perror("Write:");
                    }
                }
            }
        }
        else
        {
            close(f_des[1]);
            for (i = 0; i < 5; i++)
            {
                for (j = 0; j < 5; j++)
                {
                    //Also close the other end of the pipe?
                    //Read from the pipe here - will I need to flush the pipe every time it reads?
                    //Organize new image
                    if (read(f_des[0], message, sizeof(message)) != -1)
                    {
                        printf("P: I am process %ld with parent %ld\n", (long)getpid(), (long)getppid());
                        fflush(stdout);
                    }
                    else
                    {
                        perror("Read:");
                    }
                }
            }
        }
        return 0;
    }

  8. #8
    Registered User
    Join Date
    Sep 2013
    Posts
    49
    I don't think that I am. My professor talked about using the k for loops and the pixel position by using the var pixelID to make sure the right child worked on only one specific region of the image. I'm not seeing how this is....Can someone help?

  9. #9
    Registered User
    Join Date
    Sep 2013
    Posts
    49
    Got it to work. I had my if(pixelID%p ==k) in the wrong place as well as my increment for pixelID. Also, needed to take out the braces on the k for loop and put a break statement after creating my fork() if statement.

  10. #10
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    > If child do these 4 for loops to analyse each sub block of the image
    Consider this

    Your child (4 of them) runs for 5 * 5 iterations - 25 per child, 100 in total.

    Your parent only runs for 5 * 5 iterations.

    You seem to be missing a lot of messages.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  11. #11
    Registered User
    Join Date
    Sep 2013
    Posts
    49
    Quote Originally Posted by Salem View Post
    > If child do these 4 for loops to analyse each sub block of the image
    Consider this

    Your child (4 of them) runs for 5 * 5 iterations - 25 per child, 100 in total.

    Your parent only runs for 5 * 5 iterations.

    You seem to be missing a lot of messages.
    The 5 was arbitrary to make sure I was doing all the processing correctly. I wasn't even sending anything to the pipe in that previous example. It was separate from the my project.

    I'm getting the correct results now.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Sobel Edge Detection
    By Bakenshake in forum C Programming
    Replies: 15
    Last Post: 11-23-2014, 01:44 AM
  2. Pipes between child processes
    By nikey007 in forum C Programming
    Replies: 2
    Last Post: 05-06-2014, 10:56 AM
  3. Replies: 4
    Last Post: 11-17-2013, 01:30 PM
  4. Edge Detect
    By 250co in forum C Programming
    Replies: 0
    Last Post: 05-22-2006, 08:51 PM
  5. Replies: 4
    Last Post: 09-21-2003, 03:00 PM