opencv简单视频与图像操作

//学习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; //回调函数对象

//定义回调函数,使其在滚动条被拖动时调用。滚条位置为pos
void onTrackbarSlide(int pos)
{
	//设置视频属性,对应获取视频属性为cvGetCaptureProperty
	//g_capture:对应视频结构体
	//CV_CAP_PROP_POS_FRAME:单位为帧数的位置(只对视频文件有效)
	//pos:视频位置value
	cvSetCaptureProperty(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 33ms
		
		if(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);
}

//docanny
IplImage* 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值