Code:
#include <math.h>#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);
int applyHorizontalFilter(unsigned char smallBlock[n][n], int sobelH[n][n]);
int applyVerticalFilter(unsigned char smallBlock[n][n], int sobelV[n][n]);
void imageAnalysis(image_ptr imagePtr, int row, int col, int width, int height, int rows, int cols, float *mean, float *sd);
int threshold_image(unsigned char **image, int rows, int cols, float threshold, unsigned char **imageout);
unsigned char **allocate_image(int rows, int cols);
//argc - argument count
//argv - stores the arguments as a string
int main(int argc, char **argv){
//variable declaration
int rows, cols, type;
int i=0, j=0, x=0, y=0, valueH = 0, valueV = 0;
int tp;
float mean = 0;
float sd = 0;
unsigned char **image=NULL, **imageout=NULL;
float threshold = 1;
unsigned char smallBlock[n][n];//sub block for image
image_ptr imagePtr, imagePtr2, imagePtr3, imagePtr4, imagePtr5, imagePtr6, imagePtr7;//image pointer types
//sobel filters
int sobelH[3][3] = {-1, -2, -1, 0, 0, 0, 1, 2, 1}; //horizontal
int sobelV[3][3] = {-1, 0, 1, -2, 0, 2, -1, 0, 1}; //vertical
//checks the inputs
if (argc != 8){
printf("Wrong inputs: use %s infile out1 out2 out3 \n", argv[0]);
return 0;
}
else{
imagePtr = read_pnm(argv[1], &rows, &cols, &type);//pointer to access the whole image
printf("\nYour image was read successfully!\n");
printf("Image information: rows = %d, cols = %d, type = %d\n", rows, cols, type);
printf("\n");
//spaces for output images
unsigned char image2[rows][cols];
unsigned char image3[rows][cols];
unsigned char image4[rows][cols];
unsigned char image5[rows][cols];
unsigned char image6[rows][cols];
unsigned char image7[rows][cols];
//applies the horizontol edge filter
for(i=0; i<rows; i++){//height of the image
for(j=0; j<cols; j++){//width of the image
for(y=0; y<n; y++){//width of the sub-block
for(x=0; x<n; x++){//height of the sub-block
smallBlock[x][y]=imagePtr[(i+x)*cols+(j+y)];
}
}
valueH = applyHorizontalFilter(smallBlock, sobelH);
image2[i][j] = valueH;
}
}
//applies the vertical edge filter
for(i=0; i<rows; i++){//height of the image
for(j=0; j<cols; j++){//width of the image
for(y=0; y<n; y++){//width of the sub-block
for(x=0; x<n; x++){//height of the sub-block
smallBlock[x][y]=imagePtr[(i+x)*cols+(j+y)];
}
}
valueV = applyVerticalFilter(smallBlock, sobelV);
image3[i][j] = valueV;
}
}
//applies both vertical and horizontal filters to the image
for(i=0; i<rows; i++){//height of the image
for(j=0; j<cols; j++){//width of the image
for(y=0; y<n; y++){//width of the sub-block
for(x=0; x<n; x++){//height of the sub-block
smallBlock[x][y]=imagePtr[(i+x)*cols+(j+y)];
}
}
valueV = applyVerticalFilter(smallBlock, sobelV);
valueH = applyHorizontalFilter(smallBlock, sobelH);
image4[i][j] = valueV + valueH;
}
}
tp = 5;
imagePtr2 = (image_ptr)image2;
imageAnalysis(imagePtr2, 0, 0, rows, cols, rows, cols, &mean, &sd);
threshold = mean + sd;
printf("The overall mean of the image with horizontal filter is: %6.2f\n", mean);
printf("The overall standard deviation of the image with horizontal filter is: %6.2f\n", sd);
printf("\n");
imagePtr3 = (image_ptr)image3;
imageAnalysis(imagePtr3, 0, 0, rows, cols, rows, cols, &mean, &sd);
printf("The overall mean of the image with vertical filter is: %6.2f\n", mean);
printf("The overall standard deviation of the image with vertical filter is: %6.2f\n", sd);
printf("\n");
imagePtr4 = (image_ptr)image4;
imageAnalysis(imagePtr4, 0, 0, rows, cols, rows, cols, &mean, &sd);
printf("The overall mean of the image with both the horizontal and vertical filter is: %6.2f\n", mean);
printf("The overall standard deviation of the image with both the horizontal and vertical filter is: %6.2f\n", sd);
printf("\n");
//binary images
imagePtr5 = threshold_image(**image2, rows, cols, 1, image5);
imagePtr6 = threshold_image(**image3, rows, cols, 1, image6);
imagePtr7 = threshold_image(**image2, rows, cols, 1, image7 );
// imageAnalysis(imagePtr5, 0, 0, rows, cols, rows, cols, &mean, &sd);
//printf("The overall mean of the image with a binary horizontal filter is: %6.2f\n", mean);
// printf("The overall standard deviation of the image with a binary horizontal filter is: %6.2f\n", sd);
// printf("\n");
// imagePtr6 = (image_ptr)image6;
//imageAnalysis(imagePtr6, 0, 0, rows, cols, rows, cols, &mean, &sd);
//printf("The overall mean of the image with a binary vertical filter is: %6.2f\n", mean);
//printf("The overall standard deviation of the image with a binary vertical filter is: %6.2f\n", sd);
// printf("\n");
// imagePtr7 = (image_ptr)image7;
//imageAnalysis(imagePtr7, 0, 0, rows, cols, rows, cols, &mean, &sd);
//printf("The overall mean of the image with a binary horizontal and vertical filter is: %6.2f\n", mean);
// printf("The overall standard deviation of the image with a binary horizontal and vertical filter is: %6.2f\n", sd);
// printf("\n");
write_pnm(imagePtr2, argv[2], rows, cols, tp);//creates the image with just a horizontal filter
write_pnm(imagePtr3, argv[3], rows, cols, tp);//creates the image with just a vertical filter
write_pnm(imagePtr4, argv[4], rows, cols, tp);//creates the image with both the horizontal and vertical filters
//unfinished binaey image outputs
write_pnm(imagePtr5, argv[5], rows, cols, tp);//creates the image with a binary horizontal filter
write_pnm(imagePtr6, argv[6], rows, cols, tp);//creates the image with a binary vertical filter
write_pnm(imagePtr7, argv[7], rows, cols, tp);//creates the image with a binary horizontal and vertical filter
}
return 0;
}
//methods
int applyHorizontalFilter(unsigned char smallBlock[n][n], int sobelH[3][3]){
int x = 0;
int y = 0;
int pixelValueH = 0;
// unsigned char filtered_block[3][3];
for(x = 0; x<3; x++){
for(y=0; y<3; y++){
pixelValueH += sobelH[x][y]*smallBlock[x][y];
}
}
return abs(pixelValueH);
}
int applyVerticalFilter(unsigned char smallBlock[n][n], int sobelV[3][3]){
int x = 0;
int y = 0;
int pixelValueV = 0;
// unsigned char filtered_block[3][3];
for(x = 0; x<3; x++){
for(y=0; y<3; y++){
pixelValueV += sobelV[x][y]*smallBlock[x][y];
}
}
return abs(pixelValueV);
}
//analyzes images to get their mean and standard deviation
void imageAnalysis(image_ptr imagePtr, int row, int col, int width, int height, int rows, int cols, float *mean, float *sd){
float sum = 0;
//calculate the sum
for(int i=0; i<height; i++){
for(int j=0; j<width; j++){
sum += imagePtr[(row + i)*rows + col + j];
}
}
*mean=sum/(width*height);
sum = 0;
//calculates the standard deviation
for(int i=0; i<height; i++){
for(int j=0; j<width; j++){
sum += pow(imagePtr[(row + i)*rows + col + j]-*mean, 2);
}
}
sum = 1.0/(width*height-1.0)*sum;
*sd = sqrt(sum);
}
int threshold_image(unsigned char **image, int rows, int cols, float threshold,unsigned char **imageout){
unsigned char **imagetmp=NULL;
int r, c;
// Allocate memory for the thresholded image.
if((imagetmp = allocate_image(rows, cols)) == NULL) return(0);
*imageout = *imagetmp;
for(r=0;r<rows;r++){
for(c=0;c<cols;c++){
if(image[r][c] < threshold) imagetmp[r][c] = 0;
else imagetmp[r][c] = 255;
}
}
return(1);
}
unsigned char **allocate_image(int rows, int cols)
{
unsigned char **image=NULL;
int r, br;
//Allocate an array of pointers of type (unsigned char *). The array is
allocated to have a length of the number of rows.
if((image = (unsigned char **) calloc(rows, sizeof(unsigned char *)))==NULL){
fprintf(stderr, "Error allocating the array of pointers in allocate_image().\n");
}
return((unsigned char **)NULL);
}