ji451119366 2016-05-18 15:50 采纳率: 0%
浏览 1498
已结题

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

#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条回答 默认 最新

  • threenewbee 2016-05-19 00:53
    关注

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

    评论

报告相同问题?

悬赏问题

  • ¥50 导入文件到网吧的电脑并且在重启之后不会被恢复
  • ¥15 (希望可以解决问题)ma和mb文件无法正常打开,打开后是空白,但是有正常内存占用,但可以在打开Maya应用程序后打开场景ma和mb格式。
  • ¥15 绘制多分类任务的roc曲线时只画出了一类的roc,其它的auc显示为nan
  • ¥20 ML307A在使用AT命令连接EMQX平台的MQTT时被拒绝
  • ¥20 腾讯企业邮箱邮件可以恢复么
  • ¥15 有人知道怎么将自己的迁移策略布到edgecloudsim上使用吗?
  • ¥15 错误 LNK2001 无法解析的外部符号
  • ¥50 安装pyaudiokits失败
  • ¥15 计组这些题应该咋做呀
  • ¥60 更换迈创SOL6M4AE卡的时候,驱动要重新装才能使用,怎么解决?