#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <conio.h>
#include <string.h>
#include <ctype.h>
#define mod1 1
/*mod1,mod2分别为门限计算公式的两个常数参数*/
#define mod2 2
#define NULL 0
#define H 2
#define W 1
#define size H*W*3/2
#define LEN sizeof(struct staff)
struct staff
{
int Num_frame;
int SADn;
struct staff *next;
} ;
float M,N,Threshold;
/*M,N分别为求得们先所需要的两个数据*/
int k,SAD;
/*K为帧的数目*/
FILE *fp=NULL;
struct staff *countSAD();
void countM();
void countN(struct staff *head);
void countThreshold();
void compare(struct staff *head);
void main()
{
int
a=1;
/*通过a=0判断该程序的结束*/
char c,filename[20];
struct staff *head = NULL;
printf("读取文件中的数据:\n");
kaishi:
printf("输入文件的名称:\n");
gets(filename);
if((fp=fopen(filename,"r+t"))==NULL)
{
printf("不能够读取该文件中的数据!!\n");
exit(0);
}
printf("文件读取成功!!\n");
printf("\n");
do
{
printf("******************************************************************************\n");
printf("*
****************************
*\n");
printf("*
**欢迎进入图象变化检测系统**
*\n");
printf("*
****************************
*\n");
printf("******************************************************************************\n");
printf("*============================================================================*\n");
printf("*==========================1,首先计算出SAD的数值。===========================*\n");
printf("*==========================2,紧接着计算M的数值。
===========================*\n");
printf("*==========================3,紧接着计算N的数值。
===========================*\n");
printf("*==========================4,紧接着门限的数值。
===========================*\n");
printf("*==========================5,显示最终的结果。
===========================*\n");
printf("*==========================6,再次读取文件。
===========================*\n");
printf("*==========================7,退出该系统。
===========================*\n");
printf("*============================================================================*\n");
printf("*请作出您的选择:(请输入数字选择)
*\n");
printf("*备注:选择1在每次读取文件后只能使用一次!!!
*\n");
printf("*============================================================================*\n");
printf("******************************************************************************\n");
printf ("\n");
c=getche ();
printf ("\n");
printf ("\n");
switch (c)
{
case '1':
head = countSAD ();
break;
case '2':
countM ();
break;
case '3':
countN (head);
break;
case '4':
countThreshold ();
break;
case '5':
compare (head);
break;
case '6':
goto kaishi;
break;
case '7':
a = 0;
break;
default :
printf("选择错,请输入1~7进行选择!!\n");
break;
}
}
while(a != 0);
fclose(fp);
}
struct staff *countSAD ( )
/*计算SAD的数值*/
{
char a[size];
int c,i,j,sum = 0,sum1 = 0;
/*通过sum求得SAD的总和,sum1求得每一帧的SADn的数值*/
FILE *fp1 = NULL;
struct staff *head,*s,*r;
/*r始终指向单链表的最后节点*/
fp1=fp;
k=0;
head=(struct staff *)malloc(LEN);
r=head;
do
{
s = (struct staff *)malloc(LEN);
j = fread(a,sizeof(char),size,fp1);
printf("这次读入了%2d个数据!!\n",j);
printf("缓存中的数据为%s!!\n",a);
for(i=0;i<size-1;i++)
{
printf("%c%4d\n",a[i],a[i]);
if(a[i] == '\0')
break;
c = abs(a[i+1]-a[i]);
sum = sum + c;
sum1 = sum1 + c;
}
if(a[i+1] == '\0')
break;
k++;
s->Num_frame = k;
printf("第%d帧SAD的数值为%d。\n",k,sum1);
s->SADn = sum1;
printf("%d\n",s->SADn);
sum1 = 0;
r->next = s;
r = s;
}
while(j);
r->next = NULL;
SAD = sum;
printf("总共有%d帧,所有这些SAD的和为%d。\n",k,SAD);
fclose(fp1);
return head;
}
void countN(struct staff *head)
{
struct staff *p;
float x,y = 0;
p=head->next;
if(p == NULL)
printf("未读取文件!!");
else
{
while(p->next != NULL)
{
x = p->SADn-M;
printf("%f\n",x);
y = y+x*x;
printf("%f\n",y);
p = p->next;
}
}
N=(float)sqrt(y/(k-2));
printf("N的数值为%f。\n",N);
}
void countM()
{
M = (float)SAD/(k-1);
printf("M的数值为%f。\n",M);
}
void countThreshold()
{
Threshold = mod1*M + mod2*N;
printf("门限的数值为%f。\n",Threshold);
}
void compare(struct staff *head)
{
struct staff *p2;
p2 = head->next;
while(p2 != NULL)
{
if(p2->SADn > Threshold)
printf("能够检测出图像变化,第%d帧与前面有变化!!\n",p2->Num_frame);
else
printf("不能够检测出图像变化!!\n");
p2 = p2->next;
}
}