opencv简单视频与图像操作

来源:互联网 发布:jsp javabean MySQL 编辑:程序博客网 时间:2024/04/27 15:34
//学习OPENCV,第2章#include<cv.h>#include<iostream>#include<opencv2/core/core.hpp>#include<opencv2/highgui/highgui.hpp>#include <cxcore.h>#include<assert.h>//全局变量,用于视频波形滚条控制(帧之间的跳跃);int g_slider_position = 0; //设置滚条位置CvCapture* g_capture = NULL; //回调函数对象//定义回调函数,使其在滚动条被拖动时调用。滚条位置为posvoid onTrackbarSlide(int pos){//设置视频属性,对应获取视频属性为cvGetCaptureProperty//g_capture:对应视频结构体//CV_CAP_PROP_POS_FRAME:单位为帧数的位置(只对视频文件有效)//pos:视频位置valuecvSetCaptureProperty(g_capture,CV_CAP_PROP_POS_FRAMES,pos);}IplImage* docanny(IplImage* Image_in,double lowThresh,double highThresh,double aperture);IplImage* doPyrDown(IplImage* Image_in,int filter = IPL_GAUSSIAN_5x5);int main(int argc,char** argv){/**显示图像**/printf("1.简单图像显示\n");IplImage* img = cvLoadImage("D:\\AI_Proj\\OPENCV\\dog.jpg");//读取图像,自动分配内存cvNamedWindow("example",CV_WINDOW_AUTOSIZE);cvShowImage("example",img);cvWaitKey(0);cvReleaseImage(&img);cvDestroyWindow("example");/**简单AVI视频读取与显示**/printf("2.简单AVI视频读取与显示\n");cvNamedWindow("cv_vedio",CV_WINDOW_AUTOSIZE);//读入的AVI文件,CvCapture结构包括所有AVI文件信息,包括状态信息等。CvCapture* capture = cvCreateFileCapture("D:\\AI_Proj\\OPENCV\\shipin.avi");IplImage* frame;//循环读入AVI文件while(1){//将下一帧视频载入内存//cvLoadImage为图像分配内存,需要通过cvReleaseImage()进行内存释放//cvQueryFrame使用已经在CvCapture中分配好的内存,只需要释放CvCapture指针即可frame = cvQueryFrame(capture);if(!frame)break;cvShowImage("cv_vedio",frame);//实际应用中通过从CvCapture结构体中获取实际帧率更好(CV_CAP_PROP_FPS)//如果期间用户触发按键,c设置为对应按键的ASIC码char c = cvWaitKey(33);//wait for 33msif(c == 27) //对应ESC按键break;}cvWaitKey(0);cvReleaseCapture(&capture);cvDestroyWindow("cv_vedio");/**创建滚动条,通过设置参数确定滚动条所属窗口**///通过添加全局变量来表示滚动条位置,并添加一个回调函数更新变量以及设置视频读入位置。printf("3.视频滚动条\n");cvNamedWindow("cv_vedio_control",CV_WINDOW_AUTOSIZE);g_capture = cvCreateFileCapture("D:\\AI_Proj\\OPENCV\\shipin.avi");//cvGetCaptureProperty从cvCapture中查询数据//CV_CAP_PROP_FRAME_COUNT:将被下一步解压/获取的帧索引//以帧数来设置读入位置int frames = (int)cvGetCaptureProperty(g_capture,CV_CAP_PROP_FRAME_COUNT);if(frames != 0){//frame为0时不会创建,因为对于有些编码方式,总的帧数获取不到。这时看不到滚动条//创建滚动条cvCreateTrackbar("Position", //滚动条名称 "cv_vedio_control",//所属窗口 &g_slider_position,//pos位置以0为起点 frames,//将全局变量绑定到滚动条表示滚动条的最大值 onTrackbarSlide);//回调函数,当滚动条被拖动时被触发}IplImage* frame1;while(1){frame1 = cvQueryFrame(g_capture);//参数为CvCapture指针,将下一帧视频载入内存//cvLoadImage为图像分配内存,cvQueryFrame使用已经在CvCapture中分配好的内存//前者需要通过cvReleaseImage()进行内存释放,后者只需要释放CvCapture指针即可if(!frame1)break;cvShowImage("cv_vedio_control",frame1);char c = cvWaitKey(33);if(c == 27) break;}cvWaitKey(0);cvReleaseCapture(&g_capture);cvDestroyWindow("cv_vedio_control");/**平滑滤波**/printf("4.平滑滤波\n");IplImage* Image = cvLoadImage("D:\\AI_Proj\\OPENCV\\dog.jpg");cvNamedWindow("Image-in",CV_WINDOW_AUTOSIZE);cvNamedWindow("Image-out",CV_WINDOW_AUTOSIZE);cvShowImage("Image-in",Image);//创建图像,参数:图像大小,像素数据类型,通道数IplImage* Image_o = cvCreateImage(cvGetSize(Image),IPL_DEPTH_8U,3);cvSmooth(Image,Image_o,CV_GAUSSIAN,3,3);cvShowImage("Image-out",Image_o);cvWaitKey(0);cvReleaseImage(&Image_o);cvReleaseImage(&Image);cvDestroyWindow("Image-in");cvDestroyWindow("Image-out");/**图像变换**///图像变换前后大小、深度、通道数不同printf("5.简单图像变换\n");IplImage* Image_in = cvLoadImage("D:\\AI_Proj\\OPENCV\\stuff.jpg");//640x480//高度与宽度为源图像的一半IplImage* Image_out = doPyrDown(Image_in,IPL_GAUSSIAN_5x5);cvNamedWindow("Image_in",CV_WINDOW_AUTOSIZE);cvShowImage("Image_in",Image_in);cvNamedWindow("Image_out",CV_WINDOW_AUTOSIZE);cvShowImage("Image_out",Image_out);cvWaitKey(0);cvReleaseImage(&Image_in);cvReleaseImage(&Image_out);cvDestroyWindow("Image_in");cvDestroyWindow("Image_out");/**对图像进行2次缩放以及canny检测**/printf("6.对图像进行2次缩放以及canny检测\n");IplImage* Image_in1 = cvLoadImage("D:\\AI_Proj\\OPENCV\\stuff.jpg",0);//0-强制转为灰度图;1-彩色图;-1-源通道数IplImage* image1 = doPyrDown(Image_in1,IPL_GAUSSIAN_5x5);IplImage* image2 = doPyrDown(image1,IPL_GAUSSIAN_5x5);IplImage* image3 = docanny(image2,10,100,3);cvNamedWindow("Image_in");cvShowImage("Image_in",Image_in1);cvNamedWindow("image1");cvShowImage("image1",image1);cvNamedWindow("image2");cvShowImage("image2",image2);cvNamedWindow("image3");cvShowImage("image3",image3);cvWaitKey(0);cvReleaseImage(&Image_in1);cvDestroyWindow("Image_in");cvReleaseImage(&image1);cvDestroyWindow("image1");cvReleaseImage(&image2);cvDestroyWindow("image2");cvReleaseImage(&image3);cvDestroyWindow("image3");/**写入视频**///(1)读入视频文件、获取视频帧printf("7.写入视频\n");CvCapture* capture1 = cvCreateFileCapture("D:\\AI_Proj\\OPENCV\\shipin.avi");if(!capture1)return -1;IplImage* brg_frame = cvQueryFrame(capture1);//(2)获取视频流的各项属性double fps = cvGetCaptureProperty(capture1,CV_CAP_PROP_FPS);//获取帧率CvSize size = cvSize((int)cvGetCaptureProperty(capture1,CV_CAP_PROP_FRAME_WIDTH), (int)cvGetCaptureProperty(capture1,CV_CAP_PROP_FRAME_HEIGHT));//(3)创建视频文件写入器结构//CV_FOURCC为四个字符用来表示压缩帧的codec,motion-jpeg(MJPEG)CvVideoWriter* writer = cvCreateVideoWriter("D:\\AI_Proj\\OPENCV\\new.avi",CV_FOURCC('M','J','P','G'),fps,size);//(4)将图像帧转换为对数极坐标格式,并逐帧写入视频文件IplImage* logpolar_frame = cvCreateImage(size,IPL_DEPTH_8U,3);while(brg_frame != NULL){//Log-polar转换表示从笛卡尔坐标到极坐标。//模仿视网膜中央凹视力,对于目标跟踪等可用于快速尺度和旋转变换不变模板匹配。cvLogPolar(brg_frame,   logpolar_frame,   cvPoint2D32f(brg_frame->width/2,brg_frame->height/2),//创建一个二维坐标下的点(浮点)   40,   CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS);cvWriteFrame(writer,logpolar_frame);cvNamedWindow("mainwin",CV_WINDOW_AUTOSIZE);cvShowImage("mainwin", logpolar_frame);char c = cvWaitKey(33);if(c == 27)break;}printf("well done");cvReleaseVideoWriter(&writer);cvReleaseImage(&logpolar_frame);cvReleaseCapture(&capture1); return 0;}//doPyrDown,图像缩放与滤波(高斯金字塔)IplImage* doPyrDown(IplImage* Image_in,int filter){assert(Image_in->width%2==0 && Image_in->height%2==0);IplImage* Image_out = cvCreateImage(cvSize(Image_in->width/2,Image_in->height/2),Image_in->depth,Image_in->nChannels);//filter仅支持 CV_GAUSSIAN_5x5 //cvPyrDown使用Gaussian金字塔分解对输入图像向下采样。//先进行卷积,后通过拒绝偶数的行与列来下采样图像。cvPyrDown(Image_in,Image_out); //对图像进行缩放return(Image_out);}//docannyIplImage* docanny(IplImage* Image_in,double lowThresh,double highThresh,double aperture){if(Image_in->nChannels != 1) //通道必须为1{printf("it's not a 1-channel image-in\n");return 0;}IplImage* Image_out = cvCreateImage(cvGetSize(Image_in),IPL_DEPTH_8U,1);//输入图像必须为单通道灰度图。输出边缘图像也为单通道黑白图//小阈值控制边缘连接//大阈值控制强边缘的初始分割,才保留,否则删除//aperture为Sobel算子,默认为3即表示一个3*3的矩阵cvCanny(Image_in,Image_out,lowThresh,highThresh,aperture);return Image_out;}

效果图:

简单图像显示

平滑滤波

通道不变,简单缩放

对灰度图构建图像金字塔,并执行canny边缘检测


0 0