2016-05-18 15:50

# opencv视频边界检测，哪个大神知道这是什么算法啊啊啊，好急

5

#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);
• 点赞
• 写回答
• 关注问题
• 收藏
• 复制链接分享
• 邀请回答

#### 1条回答

• 这个就是通过灰度直方图判断两个图片（相邻的帧）的差异，差异大说明切换了。

点赞 评论 复制链接分享