OBJECTIVE Design, debug and test a C program that simulates an intelligent video
ID: 3777221 • Letter: O
Question
OBJECTIVE Design, debug and test a C program that simulates an intelligent video surveillance system that can automatically monitor an area and alarm security guards about suspicious activity in a restricted access area. BACKGROUND Video surveillance systems have become important components in the modern security infrastructure. More and more cameras are installed to provide efficient surveillance. Traditionally, video surveillance systems were considered only for observation and video recording, while video analysis relied on human attention and decision making. However according to many studies, the most vulnerable part of video surveillance systems is videoExplanation / Answer
fathima.c
#include <stdio.h>
#include <stdlib.h> /* Required for operation involving memory allocation */
#include <stdbool.h> /* Required for operation with bool functions */
#include "fathima.h"
int main(int argc , char *argv[])
{
BMPIMAGE bmpImage1 = {{0}} ; /* Initializes all the members of the nested structure to 0 */
BMPIMAGE bmpImage2 = {{0}} ; /* Initializes all the members of the nested structure to 0 */
FILE *BackgImage = NULL ; /* Initializes the file stream background image to NULL */
FILE *CurrentImage = NULL ; /* Initializes the file stream Current image to NULL */
FILE *SubImage = NULL ; /* Initializes the file stream sub image to NULL */
Pixel **pixelData1 ; /* Using a pointer to pointer of type Pixel to store pixel data of background image */
Pixel **pixelData2 ; /* Using a pointer to pointer of type Pixel to store pixel data of background image */
Pixel **pixelData3 ; /* Using a pointer to pointer of type Pixel to store pixel data of background image */
bool status; /* This is for checking the return values of function which if false results in termination */
int width1, height1; /* width1 and height1 is the width and height of Background image */
int width2,height2 ; /* width2 and height2 is the width and height of Current image */
int Error = 0,*errorIndicator; /* This pointer is used by changing its value to 1 if an error occurs. This results in termination */
unsigned int offset1,offset2; /* offset1 and offset2 is the offsets of background and current image respectively */
int read = 1 ; /* This is used to specify the the file stream opened should be in read mode. If the value is changed to 0 file stream is opened in write mode */
int difCounter; /* This is used to check the counter value which compares how big the intruding object is */
errorIndicator= &Error; /* Initializing the value of *errorIndicator to 0 (i.e no error) */
status = CorrectNoArguments(argc);
if (status == false) return -1; /* Correct number of arguments is not input. Terminate */
BackgImage = OpenFile(BackgImage,argv[1],read );
if (BackgImage == NULL) return -1 ; /* File stream open not successfull. Terminate */
bmpImage1 = ReadBmpImageHeaders(BackgImage,bmpImage1,argv[1],errorIndicator);
if (*errorIndicator == 1) /* Error in either fread or the file is not a bmp */
{
fclose(BackgImage); /* Close the file stream before terminating */
return -1;
}
/* ------- Obtain the width,height,offset of the Background image --------- */
width1 = bmpImage1.INFOHEADER.width ;
height1 = bmpImage1.INFOHEADER.height ;
offset1 = bmpImage1.FILEHEADER.imageDataOffset;
/* ------------ Allocate memory for the array pixelData1 ------------- */
pixelData1 = alloc2Drgb( height1, width1 );
if (pixelData1 == NULL)
{
fprintf(stderr, " Memory allocation failure in allocating for pixelData1");
fclose(BackgImage); /* Close the file stream before terminating */
return -1;
}
/* ------- Read the image's pixel information in the array pixelData1-------- */
status = ReadImageArray(BackgImage,pixelData1,width1,height1,offset1);
fclose(BackgImage); /* Close the file stream as all information from background image is extracted.*/
if (status == false) /* Error in fread */
{
free2Drgb(pixelData1); /* Free the allocated memory before terminating */
return -1 ;
}
CurrentImage = OpenFile(CurrentImage,argv[2], read);
if (CurrentImage == NULL) /* File stream open not successfull. */
{
free2Drgb(pixelData1); /* Free the allocated memory before terminating */
return -1 ;
}
/*------- Read FileHeader and InfoHeader in bmpImage2 -------*/
bmpImage2 = ReadBmpImageHeaders(CurrentImage,bmpImage2,argv[2],errorIndicator);
if (*errorIndicator == 1) /* Error in either fread or the file is not a bmp */
{
fclose(CurrentImage); /* Close the file stream */
free2Drgb(pixelData1); /* Free the allocated memory before terminating */
return -1;
}
width2 = bmpImage2.INFOHEADER.width ;
height2 = bmpImage2.INFOHEADER.height ;
offset2 = bmpImage2.FILEHEADER.imageDataOffset;
if ((width1 != width2) || (height1 != height2))
{
free2Drgb(pixelData1); /* Free the allocated memory for pixelData1 before terminating */
return -1;
}
/* ---------- Allocate memory for the array pixelData2 ------------- */
pixelData2 = alloc2Drgb( height2, width2 );
if (pixelData2 == NULL)
{
fprintf(stderr, " Memory allocation failure in allocating for pixelData2");
free2Drgb(pixelData1); /* Free the allocated memory before terminating */
fclose(CurrentImage); /* Close the file stream before terminating */
return -1;
}
/* -------- Read the image's pixel information in the array pixelData1 ------------ */
status = ReadImageArray(CurrentImage,pixelData2,width2,height2,offset2);
fclose(CurrentImage); /* Closes the CurrentImage file stream as it is of no more use */
if (status == false) /* Error in fread */
{
free2Drgb(pixelData1); /* Free the allocated memory for pixelData1 before terminating */
free2Drgb(pixelData2); /* Free the allocated memory for pixelData2 before terminating */
return -1 ;
}
pixelData3 = alloc2Drgb( height2, width2 );
if (pixelData3 == NULL)
{
fprintf(stderr, " Memory allocation failure in allocating for pixelData3");
free2Drgb(pixelData1); /* Free the allocated memory for pixelData1 before terminating */
free2Drgb(pixelData2); /* Free the allocated memory for pixelData2 before terminating */
return -1;
}
/* ----------------- Getting image array in pixelData3 and obtaining difCounter --------------- */
difCounter = GetImageArray(pixelData1,pixelData2,pixelData3,height2,width2) ;
free2Drgb(pixelData1); /* Free the allocated memory for pixelData1 as all information from it is extracted for use with subimage */
free2Drgb(pixelData2); /* Free the allocated memory for pixelData2 as all information from it is extracted for use with subimage */
/* -------- Open the Current image file in write mode ------------- */
SubImage = OpenFile(SubImage,argv[3], read=0 );
if (SubImage == NULL) /* File stream open not successfull. */
{
free2Drgb(pixelData3); /* Free the allocated memory before terminating */
return -1 ;
return -1 ;
}
/* -------- Write Subimage image headers into output File ------------ */
status = WriteBmpImageHeaders(SubImage,bmpImage2);
if (status == false) /* Error in fwrite */
{
fclose(SubImage);
free2Drgb(pixelData3);
return -1;
}
/* ---------- Write Subimage image array data into output File ------------ */
status = WriteImageArray(SubImage,pixelData3,height2,width2,offset2);
fclose(SubImage); /*Closes the Current Image file stream as it is of no more use*/
free2Drgb(pixelData3);
if (status == false) return -1 ;
/* ---------- Print Information relating to the alarm and counter reading ----------- */
PrintAlarmInfo(difCounter);
return(0);
}
bool CorrectNoArguments(int argc)
{
if (argc<ARGC_VALUE)
{
printf("Insufficient number of command parameters ");
printf("Program is terminated ");
return false ;
}
else if (argc>ARGC_VALUE)
{
printf("Too many command parameters ");
printf("Program is terminated ");
return false ;
}
else
return true;
}
FILE* OpenFile(FILE *file ,char fileName[],int mode)
{
if (mode == 1) file = fopen(fileName, "rb");
else file = fopen(fileName, "wb");
if (file == NULL) fprintf(stderr ,"Error in opening file %s " , fileName);
return file;
}
BMPIMAGE ReadBmpImageHeaders(FILE *Image,BMPIMAGE bmpImage, char fileName[],int *errorIndicator)
{
if(fread(&bmpImage, sizeof(bmpImage),1,Image) !=1)
{
*errorIndicator = 1 ;
printf("error is present in fread ");
if (!feof(Image)) printf("End of file reached " );
if (ferror(Image)) printf("Stream read error " ); /* check if the stream read error has occurred */
return bmpImage;
}
IsBmpFile(bmpImage.FILEHEADER,fileName,errorIndicator);
return (bmpImage);
}
void IsBmpFile(FileHeader fHeader, char fileName[], int *errorIndicator)
{
char filemarker1;
char filemarker2;
filemarker1 = fHeader.fileMarker1 ;
filemarker2 = fHeader.fileMarker2 ;
if (filemarker1 == 'B' && filemarker2 == 'M') return ;
else *errorIndicator = 1 ;
printf("Incorrect file format ");
printf("%s is not a bmp file ", fileName );
return;
}
bool ReadImageArray(FILE *Image , Pixel **pixelData, int width,int height,int offset)
{
int row;
if (fseek(Image,offset,SEEK_SET) != 0)
{
fprintf(stderr, " File Positioning Error ");
return false;
}
for(row=0; row< height; row++)
{
if (fread( pixelData[row], sizeof(Pixel), width, Image) == width)
{
printf("Error in fread while reading Array ");
if (!feof(Image)) printf("End of file not reached " );
/* check if the stream read error has occurred */
if( ferror(Image) ) printf("Stream read error " );
return false;
}
}
return true;
}
int GetImageArray(Pixel** pixelData1,Pixel** pixelData2, Pixel** pixelData3,int height, int width)
{
unsigned char backgLuminance , imageLuminance ;
int row, column ,difference,difCounter=0;
for(row=0 ; row<height ; row++)
{
for (column=0 ; column<width ; column++)
{
backgLuminance = (pixelData1[row][column].red + pixelData1[row][column].green + pixelData1[row][column].blue ) / 3 ;
imageLuminance = (pixelData2[row][column].red + pixelData2[row][column].green + pixelData2[row][column].blue ) / 3 ;
difference = backgLuminance - imageLuminance ;
if (difference<0) difference *=-1;
if (difference > THRESHOLD)
{
difference = 250 ;
difCounter++;
}
else difference = 0;
pixelData3[row][column].red = difference ;
pixelData3[row][column].green = difference ;
pixelData3[row][column].blue = difference ;
}
}
return difCounter;
}
bool WriteBmpImageHeaders(FILE *Image,BMPIMAGE bmpImage)
{
if(fwrite(&bmpImage, sizeof(BMPIMAGE),1,Image) != 1)
{
printf("error is present in fwrite while writing image headers. ");
return false;
}
return true;
}
bool WriteImageArray(FILE *outfile , Pixel **pixelData,int height, int width, unsigned int offset)
{
int row;
if(fseek(outfile,offset,SEEK_SET) != 0 )
{
fprintf(stderr, " File Positioning Error ");
return false;
}
for( row=0; row< height; row++)
{
if (fwrite( pixelData[row], sizeof(Pixel), width, outfile )!= width )
{
printf("Write error ");
return false;
}
}
return true ;
}
Pixel **alloc2Drgb( int height, int width )
{
int i;
unsigned int numElem;
Pixel *p, **pp;
numElem = height * width;
p = (Pixel*)calloc( numElem, 3 );
if( p == NULL ) return NULL;
pp = (Pixel**)calloc( height, sizeof(Pixel*) );
if( pp == NULL )
{
free(p);
return NULL;
}
for ( i=0; i<height; i++ )
pp[i] = p + i*width;
return pp;
}
void free2Drgb( Pixel **array )
{
if( array != NULL ) free( (Pixel*) *array );
free((Pixel**) array);
return;
}
void PrintAlarmInfo(int difCounter)
{
if (difCounter == 0) printf(" No intruding objects detected (counter = %d) ", difCounter );
else if (difCounter < S_AREA) printf(" ALarm:Small intruding object detected (counter = %d) ", difCounter );
else if ( difCounter >= S_AREA) printf(" ALarm:Large intruding object detected (counter = %d) ", difCounter );
return ;
}
fathima.h
#ifndef __BMP__IMG__
#define __BMP__IMG__
#define THRESHOLD 60 /* If difference between background luminance and image luminace exceeds this value then difference is stated as 250 (white colour) */
#define S_AREA 100 /* If the counter is more than this value then the Alarm is for a large object */
#define ARGC_VALUE 4 /* Number of arguments in the command line parameter */
typedef struct __attribute__((__packed__))
{
char fileMarker1; /* 'B' */
char fileMarker2; /* 'M' */
unsigned int bfSize;
unsigned short unused1;
unsigned short unused2;
unsigned int imageDataOffset; /*Offset to the start of imagedata */
}FileHeader;
typedef struct __attribute__((__packed__))
{
unsigned int biSize;
int width; /* Width of the image */
int height; /* Height of the image */
unsigned short planes;
unsigned short bitPix;
unsigned int biCompression;
unsigned int biSizeImage;
int biXPelsPerMeter;
int biYPelsPerMeter;
unsigned int biClrUsed;
unsigned int biClrImportant;
}InfoHeader;
typedef struct __attribute__((__packed__))
{
unsigned char blue ; /* Blue value */
unsigned char green ; /* Green value */
unsigned char red ; /* Red value */
}Pixel;
typedef struct __attribute__((__packed__))
{
FileHeader FILEHEADER ;
InfoHeader INFOHEADER ;
}BMPIMAGE;
bool CorrectNoArguments(int argc);
FILE* OpenFile(FILE *file ,char fileName[],int mode);
void PrintAlarmInfo(int difCounter);
BMPIMAGE ReadBmpImageHeaders(FILE *Image,BMPIMAGE bmpImage, char fileName[], int *errorIndicator);
void IsBmpFile(FileHeader fHeader, char fileName[],int *errorIndicator);
bool ReadImageArray(FILE *Image , Pixel **pixelData,int width, int height, int offset);
int GetImageArray(Pixel** pixelData1,Pixel** pixelData2, Pixel** pixelData3,int height, int width) ;
bool WriteBmpImageHeaders(FILE *Image,BMPIMAGE bmpImage);
bool WriteImageArray(FILE *outfile ,Pixel **pixelData,int height, int width, unsigned int offset2);
Pixel **alloc2Drgb( int height, int width );
void free2Drgb( Pixel **array );
#endif
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.