#include "cv.h"
#include "highgui.h"
#include
#include
#include
using namespace std;
int window=15;
float LimenValue(float *comhist,int num)//阈值
{
float mean = 0;
float sum = 0;
float T;
float max;
float min;
float mmax = 0;
float mmin = 0;
float summin = 0;
float summax = 0;
float mincount = 0;
float maxcount = 0;
float median;
float factor = 4;
int i = 0;
max = comhist [num];
min = comhist [num];
for( i = 0;i<window;i++)
{
sum +=comhist[num+i];
if(comhist[num+i]>max)
{
max = comhist[num+i];
}
if(comhist[num+i]<min)
{
min = comhist[num+i];
}
}
mean = sum / window;
median = (max +min) / 2;
//计算大小两集合均值
for (i = 0;i< window;i++)
{
if (comhist[num+i] <= median)
{
summin +=comhist[num+i];
mincount++;
}
else
{
summax +=comhist[num+i];
maxcount++;
}
}
mmin = summin / mincount;
mmax = summax / maxcount;
//计算是否有突变,返回阈值
if(fabs(mmax-mmin)>(factor*mean)) //如果 |mmax - mmin | > (Factor*mean)为真
T = (mmin+mmax * 2) / 3; //T = (mmin + mmax * 2) / 3作为阈值
else
T = max + 10;
return T;
}
float LimenValue2(float * comhist, int num1, int num2)
{
float avervalue = 0; //均值
float variance = 0; //方差
float sum = 0; //和
float squaresum = 0; //差值平方的和x
float limen;
int num = num2 - num1 + 1;
for(int i = num1; i<= num2; i++)
{
sum += comhist[i];
squaresum += comhist[i] * comhist[i];
}
avervalue = sum / num;
variance = squaresum / num - avervalue*avervalue;
limen = avervalue + 30*variance;
return limen;
}
int main(int argc, char** argv)
{
CvCapture * capture = NULL; //设置读取视频数据的指针
IplImage * Frame = NULL;
IplImage * preFrame = NULL; //前一帧
IplImage * frame1 = NULL;
IplImage * frame2 =NULL;
int HistogramBins = 256;
float HistogramRange1[2] = {0,255};
float * HistogramRange[1] = {&HistogramRange1[0]};
char * aviname = "F://视频//2.MP4"; //输入视频
char filename[3000]; //保存图片时用的变量
int totalFrmNum; //总帧数
int nFrmNum = 0;
float * pCompareHist; //存放所有相邻帧间直方图差值的指针
int * sceneframe; //镜头突变处,后一镜头第一帧表示//int * keyframe;
float fLimenValue; //阈值
float fLimenValue2;
int scenecount = 0;
cvNamedWindow("新闻视频",CV_WINDOW_AUTOSIZE);//读入视频
capture = cvCaptureFromAVI(aviname);
totalFrmNum =(int)cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_COUNT)-1;
if(!capture)
{
fprintf(stderr,"Could not initialize capturing...\n");
return -1;
}
while(Frame = cvQueryFrame( capture))
{
sprintf(filename,"allframe/%d.jpg",nFrmNum);
cvSaveImage(filename, Frame);
nFrmNum++;
cvShowImage("新闻视频",Frame);
cvWaitKey(5) ;
}
cvReleaseCapture(&capture);
cvDestroyWindow("新闻视频");
//创建直方图
CvHistogram*Histogram=cvCreateHist(1,&HistogramBins,CV_HIST_ARRAY,HistogramRange);
CvHistogram*Histogram2=cvCreateHist(1,&HistogramBins,CV_HIST_ARRAY,HistogramRange);
//计算相邻帧间直方图差值
pCompareHist = new float [totalFrmNum];
float CompareHist = 0;
pCompareHist[0] = 0;
capture = cvCaptureFromAVI(aviname);
nFrmNum = 0;
while (Frame = cvQueryFrame(capture))
{
if (nFrmNum==0)
{
frame1 = cvCreateImage(cvSize(Frame->width,Frame->height),IPL_DEPTH_8U,1);
frame2 = cvCreateImage(cvSize(Frame->width,Frame->height),IPL_DEPTH_8U,1);
}
else if(nFrmNum > 1)
{
cvCvtColor(Frame,frame1,CV_BGR2GRAY);
cvCvtColor(preFrame,frame2,CV_BGR2GRAY);
cvCalcHist(&frame1,Histogram,0,0);//计算当前帧的直方图
cvCalcHist(&frame2,Histogram2,0,0);//计算前一帧的直方图
//直方图归一化
cvNormalizeHist(Histogram,1);
cvNormalizeHist(Histogram2,1);
//计算当前帧与前一帧的直方图差
CompareHist = (float)cvCompareHist(Histogram,Histogram2,CV_COMP_CHISQR);
pCompareHist[nFrmNum-1] = CompareHist;
}
preFrame = cvCloneImage(Frame);
nFrmNum++;
}
//释放图像和矩阵
cvReleaseCapture(&capture);
cvReleaseImage(&Frame);
cvReleaseImage(&frame1);
cvReleaseImage(&frame2);
cvReleaseHist(&Histogram);
cvReleaseHist(&Histogram2);
printf("镜头突变处帧:\n");
sceneframe = new int[totalFrmNum];
//计算突变帧
for (int i = 0; i < (totalFrmNum - (totalFrmNum%window));)
{
fLimenValue = LimenValue(pCompareHist,1);
for (int j = 0; j < window; j++)
{
if (pCompareHist[i+j] > fLimenValue)
{
printf("%d,",i+j+1);
/*cvNamedWindow("突变帧",CV_WINDOW_AUTOSIZE);
cvShowImage("突变帧",sceneframe);
cvDestroyWindow("突变帧");
cvReleaseImage;*/
sceneframe[scenecount] = i+j+1;
scenecount++;
}
}
i +=window;
}
scenecount++;
//保存pCompareHist数组到CompareHist.txt文件中
//保存sceneframe数组到SceneFrame.txt文件中
fstream out1;
out1.open("CompareHist.txt",ios::out);
if (!out1)
{
cerr<<"CompareHist.txt can not open.\n";
abort();
}
for (int i = 0; i < totalFrmNum; i++)
{
out1<<pCompareHist[i];
out1<<"\n";
}
out1.close();
out1.open("ScenceFrame.txt",ios::out);
if (!out1)
{
cerr<<"ScenceFrame.txt can not open.\n";
abort();
}
for (int i = 0; i < scenecount-1; i++)
{
out1<<sceneframe[i];
out1<<"\n";
}
out1.close();
//保存突变帧
int count = 0;
nFrmNum = 0;
capture = cvCreateFileCapture(aviname);
while (Frame = cvQueryFrame( capture))
{
if (nFrmNum == sceneframe[count])
{
sprintf(filename,"sceneframe/%d.jpg",nFrmNum);
cvSaveImage(filename, Frame);
count++;
}
nFrmNum++;
}
cvReleaseCapture(&capture);