Implement a Sobel filter edge detection using C threads The
Implement a Sobel filter edge detection using C++ threads. The algorithm takes a grayscale image as input and outputs an image with edge outlines.
The solution must work as follows:
1. Read command line argument to fetch names of the input and output image (.pgm images).
2. Read the image file into a 2-D array.
3. Generate the two 3x3 Sobel masks, one for each dimension.
4. Implement the Sobel filter algorithm that process the entire image (You must be able to expose parallelism here!).
a.Use dynamic scheduling by distributing parts of the image to different threads [More about this in discussion]
5. Generate the output image.
Solution
#include <stdio.h>
#include <stdlib.h>
#include \"iplib2New.c\"
#define n 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);
unsigned char apply_filter(unsigned char small_block[n][n], int sobel_h[3][3], int sobel_v[3][3]);
int ROWS, COLS, TYPE;
int main(int argc, char **argv)
{
int rows, cols, type;
int i=0, j=0, x=0, y=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 \ \", argv[0]);
return 0;
}
/* first read-in the image */
printf(\"\ Reading input image... \ \");
//Pointer to access the whole image
imagePtr = read_pnm(argv[1], &rows, &cols, &type); //Returns ptr from read_pnm
printf(\"\ Your image was read successfully!\ \");
printf(\"Info about your image: rows = %d, cols = %d, type = %d\ \", 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...\ \");
small_block[x][y] = apply_filter(small_block, sobel_h, sobel_v);
//Update output image here
image2[i][j] = small_block[x][y];
}
}
printf(\"\ Picked up a piece of image.\ \");
/*
/* now write a small image subblock to a file - to argv[2]
/* simply use the first rr x cc pixel block in the input image
*/
tp = 5;
imagePtr2 = (image_ptr)image2;
//...
// you can do calculations on the image pixels here
//...
printf(\"\ Now writing to image file ... \ \");
printf(\"rows=%d, cols=%d, type=%d \ \", 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)) );
// ... codes for image negative here
printf(\"\ Now writing negative image file ... \ \");
printf(\"rows=%d, cols=%d, type=%d \ \", rows, cols, type);
write_pnm(imageNegPtr, argv[3], rows, cols, type); //Creating the out2.pgm
return 0;
}
unsigned char apply_filter(unsigned char small_block[n][n], int sobel_h[3][3], int sobel_v[3][3])
{
int x = 0;
int y = 0;
for(x = 0; x<=3; x++)
{
for(y=0; y<=3; y++)
{
small_block[x][y] += sobel_h[x][y]*small_block[x][y];
}
}
return small_block[x][y];
}




