镜头边缘检测ppt

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

03实验
连续帧相减代码实现
直方图相减代码实现
//imhist( i );直接显示图像i的灰度直方图;
直方图相减代码实现
直方图相减少关键帧
时空切片代码实现
int main(int argc, char** argv) { //void cutColSlide(CvMat*, CvMat*, int, int); void cutRowSlide(CvMat*, CvMat*, int, int); int i; int nFrmNum = 0; int totalFrmNum; char* videofile = "G:/Makoto.mkv"; //声明IplImage指针 IplImage* pFrame = NULL; //IplImage* pSlImg_col; IplImage* pSlImg_row; CvMat* pFrameMat = NULL; CvMat* pFrMat_r = NULL; CvMat* pFrMat_g = NULL; CvMat* pFrMat_b = NULL; //CvMat* pSlMat_col; CvMat* pSlMat_row; //CvMat* pSlMat_col_r[COL_NUM+1]; CvMat* pSlMat_row_r[ROW_NUM + 1]; //CvMat* pSlMat_col_g[COL_NUM+1]; CvMat* pSlMat_row_g[ROW_NUM + 1]; //CvMat* pSlMat_col_b[COL_NUM+1]; CvMat* pSlMat_row_b[ROW_NUM + 1]; CvCapture* pCapture = NULL; char filename[50]; //垂直切片 //水平切片
连续帧相减法中,我们同样使用这个指标来评价两张图片的近
似度,一旦区别大到一定地步则认为该两帧是镜头边界。������
������
连续帧相减
ቤተ መጻሕፍቲ ባይዱ
算法原理:计算相邻两帧像素变化的数目。当超过设定的阈值时,即找到镜
头的边界 缺点:对摄像机运动敏感,如放缩、平移,往往较小的物体运动会造成很大 的帧间差,从而容易导致误检测 解决办法:通过滤波器的使用来降低。在比较一帧的每个像素前,用它的邻
时空切片代码实现
//保存切片图像 for (i = 0; i <= ROW_NUM; i++) { cvMerge(pSlMat_row_r[i], pSlMat_row_g[i], pSlMat_row_b[i], NULL, pSlMat_row); cvConvert(pSlMat_row, pSlImg_row); sprintf(filename, "G://1.bmp", i); cvSaveImage(filename, pSlImg_row); } //释放图像和矩阵 cvReleaseImage(&pSlImg_row); cvReleaseMat(&pSlMat_row); for (i = 0; i <= ROW_NUM; i++) { cvReleaseMat(&pSlMat_row_r[i]); cvReleaseMat(&pSlMat_row_g[i]); cvReleaseMat(&pSlMat_row_b[i]); } return 0; }
时空切片代码实现
//不是第一帧,正常处理 else { cvConvert(pFrame, pFrameMat); cvSmooth(pFrameMat, pFrameMat); cvSplit(pFrameMat, pFrMat_r, pFrMat_g, pFrMat_b, NULL); //切片 for (i = 0; i <= ROW_NUM; i++) { cutRowSlide(pFrMat_r, pSlMat_row_r[i], i*(int(pFrame->height / ROW_NUM)), nFrmNum); cutRowSlide(pFrMat_g, pSlMat_row_g[i], i*(int(pFrame->height / ROW_NUM)), nFrmNum);
基本概念
镜头边界检测的基础是两个连续镜头的内容有较大的不同性,因此可以用定量的方法来确定
帧序列之间的差别;如果这种差别超出了给定的阈值,就可以提取出镜头的边界(关键帧)
关键帧
短片截图的关键帧
02三种方法
连续帧相减
一帧本质就是一张图片,因此衡量两帧之间变化本质就是衡量
两张图片的区别。在KNN算法中衡量两张图片之间相似度就是图片 对应像素相减之和,将其累加,值最小的即最接近的两张图片。
时空切片代码实现
//初始化并分配图像空间和矩阵空间 pFrMat_r = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1); pFrMat_g = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1); pFrMat_b = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1); pFrameMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC3); //转化成单通道图像再处理 cvConvert(pFrame, pFrameMat); cvSmooth(pFrameMat, pFrameMat); cvSplit(pFrameMat, pFrMat_r, pFrMat_g, pFrMat_b, NULL); //切片 for (i = 0; i <= ROW_NUM; i++) { cutRowSlide(pFrMat_r, pSlMat_row_r[i], i*(int(pFrame->height / ROW_NUM)), nFrmNum); cutRowSlide(pFrMat_g, pSlMat_row_g[i], i*(int(pFrame->height / ROW_NUM)), nFrmNum); cutRowSlide(pFrMat_b, pSlMat_row_b[i], i*(int(pFrame->height / ROW_NUM)), nFrmNum); }
镜头边界检测
Contents
01
概念介绍
02
三种方法
03
实验
04
小结
05
01概念介绍
基本概念
镜头边界检测
当镜头发生转变时,会产生一些明 显的变化,镜头边界检测依据这些 变化来判断镜头是否发生转变。
镜头
视频由一个个镜头所组成, 镜头是时间上连续的若干幅 帧图像组成的片段。
镜头发生转变时的边 界帧,也称关键帧。
代码
时空切片
������ 切片颜色和纹理纹理中包含有对应视频的大量信息 ,包括镜头切变点 、摄像 机的运动方式等
因为单个镜头内部的视频帧在时间、空间和图像结构上是连续的 ,在时空切片 上的表现就是颜色和纹理空间上的连续性 。
镜头发生切换时 ,视频数据会跟着发生一系列的变化 ,表现在颜色差异突然增 大 、运动的不连续等 , 时空切片上的颜色和纹理也会表现出明显的不连续现 象。
近区域的平均值来代替,这也过滤了输入图像的一些噪声。
������
图片演示
相邻连续帧
图片演示
直方图相减
算法原理:统计相邻两帧中所有像素在不同灰度(颜色)上
的分布差异,当差异的累加值超过阈值T时,即检测到镜头边界 优点:对对象运动不敏感,因为直方图忽略了帧内的空间变 化 缺点:可能两个图像有类似的直方图但却是完全不同的内容。
cutRowSlide(pFrMat_b, pSlMat_row_b[i], i*(int(pFrame->height / ROW_NUM)),
nFrmNum); } } } //printf("Reading Done!\n"); printf("Number of frames : %d.\n", totalFrmNum); // cvReleaseImage(&pFrame); cvReleaseMat(&pFrameMat); cvReleaseMat(&pFrMat_r); cvReleaseMat(&pFrMat_g); cvReleaseMat(&pFrMat_b); cvReleaseCapture(&pCapture); printf("Save\n");
然而,这种事件的概率是足够低
代码
图片演示
相邻两个帧图像
帧图像灰度图
灰度图直方图
时空切片
������切片就是从连续的视频图像序列的同一个位置提取出的一行 (列 )像素组 合而成的一幅二维图像 。 如果将视频看作是一个 ( x, y, t)三维图像序列 , 其中 ( x, y)为图像维 , t为时间维 ,则视频的时空切片可以看作是由时间维 与图像维构成的一幅二维图像 。
时空切片代码实现
void cutRowSlide(CvMat* pFrameMat, CvMat* pSlMat_row, int row_ind, int nFrmNum) //完成行切片的工作 // pFrameMat - 要进行切片的帧数据 // pSlMat_row - 目标切片数据 // col_ind - 当前帧在视频流中的下标 { CvMat* temp_row; //临时存放提取出的行数据 temp_row = cvCreateMat(1, pFrameMat->width, CV_32FC1); //初始化 if (row_ind == pFrameMat->height) row_ind--; cvGetRow(pFrameMat, temp_row, row_ind); //从当前帧中提取 出第row_ind列 for (int i = 0; i<pFrameMat->width; i++) //将提取出的行添 加到切片 cvSet2D(pSlMat_row, nFrmNum - 1, i, cvScalar(((float*)(temp_row->data.ptr))[i])); //图像切片行坐标 // nFrmNum cvReleaseMat(&temp_row); }
//总帧数
//视频帧 //水平切片图像 //视频帧数据矩阵 //前景数据
//垂直切片数据矩阵 //水平切片数据矩阵 //垂直切片数据矩阵 //水平切片数据矩阵 //垂直切片数据矩阵 //水平切片数据矩阵 //读取视频数据的指针
时空切片代码实现
//打开视频文件 if (!(pCapture = cvCaptureFromFile(videofile))) { fprintf(stderr, "Can not open video file %s\n", videofile); return -2; } //printf("Start to reading Video!And you have to be patient!\n"); //逐帧读取视频 while (pFrame = cvQueryFrame(pCapture)) { nFrmNum++; //如果是第一帧,需要申请内存,并初始化 if (nFrmNum == 1) { totalFrmNum = (int)cvGetCaptureProperty(pCapture, CV_CAP_PROP_FRAME_COUNT); //获取视频文件总帧数 //创建切片初始矩阵 pSlImg_row = cvCreateImage(cvSize(pFrame->width, totalFrmNum), IPL_DEPTH_8U, 3); pSlMat_row = cvCreateMat(totalFrmNum, pFrame->width, CV_32FC3); for (i = 0; i <= ROW_NUM; i++) { pSlMat_row_r[i] = cvCreateMat(totalFrmNum, pFrame->width, CV_32FC1); pSlMat_row_g[i] = cvCreateMat(totalFrmNum, pFrame->width, CV_32FC1); pSlMat_row_b[i] = cvCreateMat(totalFrmNum, pFrame->width, CV_32FC1); }
相关文档
最新文档