您的位置:首页 > 运维架构

【OpenCV】2nd-播放视频、平滑处理、尺寸变换

2016-11-14 15:37 295 查看

一、一些概念

OpenCV 2.4.8 or OpenCV 2.4.9组件结构全解析

二、图像的载入,显示和输出

图像的载入,显示和输出

//-----------------------------------【程序说明】----------------------------------------------
//  程序名称::【OpenCV入门教程之三】图像的载入,显示与输出 一站式完全解析 博文配套源码
// VS2010版   OpenCV版本:2.4.8
//      2014年3月5日 Create by 浅墨
//  描述: 图像的载入,显示与输出 一站式剖析   配套源码
//  图片素材出处:dota2原画圣堂刺客 dota2 logo  动漫人物
//------------------------------------------------------------------------------------------------

#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>

using namespace cv;

int main( )
{
//-----------------------------------【一、图像的载入和显示】--------------------------------------
//     描述:以下三行代码用于完成图像的载入和显示
//--------------------------------------------------------------------------------------------------

Mat girl=imread("girl.jpg"); //载入图像到Mat
namedWindow("【1】动漫图"); //创建一个名为 "【1】动漫图"的窗口
imshow("【1】动漫图",girl);//显示名为 "【1】动漫图"的窗口

//-----------------------------------【二、初级图像混合】--------------------------------------
//     描述:二、初级图像混合
//-----------------------------------------------------------------------------------------------
//载入图片
Mat image= imread("dota.jpg",199);
Mat logo= imread("dota_logo.jpg");

//载入后先显示
namedWindow("【2】原画图");
imshow("【2】原画图",image);

namedWindow("【3】logo图");
imshow("【3】logo图",logo);

//定义一个Mat类型,用于存放,图像的ROI
Mat imageROI;
//方法一
imageROI=image(Rect(800,350,logo.cols,logo.rows));
//方法二
//imageROI=image(Range(350,350+logo.rows),Range(800,800+logo.cols));

//将logo加到原图上
addWeighted(imageROI,0.5,logo,0.3,0.,imageROI);

//显示结果
namedWindow("【4】原画+logo图");
imshow("【4】原画+logo图",image);

//-----------------------------------【三、图像的输出】--------------------------------------
//     描述:将一个Mat图像输出到图像文件
//-----------------------------------------------------------------------------------------------
//输出一张jpg图片到工程目录下
imwrite("我喜欢打dota2 by浅墨.jpg",image);

waitKey();

return 0;
}


Mat类型是用来存放图像的数据结构

图像的载入和显示——imread函数、namedWindow函数、imshow函数

输出图像到文件——imwrite函数

三、播放视频

播放视频(p21)

#include"highgui.h"

int main(int argc, char** argv) {
cvNamedWindow("Example2", CV_WINDOW_AUTOSIZE);
//CvCapture* capture = cvCaptureFromAVI( argv[1] ); // either one will work
CvCapture* capture = cvCreateFileCapture(argv[1]);
IplImage* frame;
while (1) {
frame = cvQueryFrame(capture);
if (!frame) break;
cvShowImage("Example2", frame);
char c = cvWaitKey(33);
if (c == 27) break;
}
cvReleaseCapture(&capture);
cvDestroyWindow("Example2");
}


视频播放控制(p24)

这种方法是通过添加一个全局变量来表示滚动条位置并添加一个回调函数更新变量以及重新设置视频读入位置。

通过一个调用来创建滚动条和确定回调函数。(未写出该代码)

#include <stdio.h>
#include <iostream>
#include <fstream>
#include "cv.h"
#include "highgui.h"
/*
OK, you caught us.  Video playback under linux is still just bad.  Part of this is due to FFMPEG, part of this
is due to lack of standards in video files.  But the position slider here will often not work. We tried to at least
find number of frames using the "getAVIFrames" hack below.  Terrible.  But, this file shows something of how to
put a slider up and play with it.  Sorry.
*/

using namespace std;

int        g_slider_position = 0;
CvCapture* g_capture = NULL;

void onTrackbarSlide(int pos) {
cvSetCaptureProperty(
g_capture,
CV_CAP_PROP_POS_FRAMES,
pos
);
}
//Hack because sometimes the number of frames in a video is not accessible.
//Probably delete this on Widows
int getAVIFrames(char * fname) {
char tempSize[4];
// Trying to open the video file
ifstream  videoFile(fname, ios::in | ios::binary);
// Checking the availablity of the file
if (!videoFile) {
cout << "Couldn’t open the input file " << fname << endl;
exit(1);
}
// get the number of frames
videoFile.seekg(0x30, ios::beg);
videoFile.read(tempSize, 4);
int frames = (unsigned char)tempSize[0] + 0x100 * (unsigned char)tempSize[1] + 0x10000 * (unsigned char)tempSize[2] + 0x1000000 * (unsigned char)tempSize[3];
videoFile.close();
return frames;
}

int main(int argc, char** argv)
{
cvNamedWindow("Example2_3", CV_WINDOW_AUTOSIZE);
g_capture = cvCreateFileCapture(argv[1]);

d835
IplImage *foo = cvQueryFrame(g_capture);

int frames = (int)cvGetCaptureProperty(
g_capture,
CV_CAP_PROP_FRAME_COUNT
);

int tmpw = (int)cvGetCaptureProperty(
g_capture,
CV_CAP_PROP_FRAME_WIDTH
);

int tmph = (int)cvGetCaptureProperty(
g_capture,  // AVI文件地址
CV_CAP_PROP_FRAME_HEIGHT
);

printf("opencv frames %d w %d h %d\n", frames, tmpw, tmph);

frames = getAVIFrames(argv[1]); //This is a hack because on linux, getting number of frames often doesn't work

printf("hacked frames %d w %d h %d\n", frames, tmpw, tmph);

cvCreateTrackbar(
"Position",  //滚动条名称
"Example2_3",  //所属窗口
&g_slider_position,
frames,
onTrackbarSlide   //回调函数
);
IplImage* frame;
frames = 0;
while (1) {
frame = cvQueryFrame(g_capture);
if (!frame) break;
// int frames = cvGetCaptureProperty( g_capture, CV_CAP_PROP_POS_FRAMES);//This should work, sometimes it does not on linux
frames++; //My cheat
printf("\nFrame number=%d\n", frames);
cvSetTrackbarPos("Position", "Example2_3", frames);
cvShowImage("Example2_3", frame);
char c = (char)cvWaitKey(10);
if (c == 27) break;
}
cvReleaseCapture(&g_capture);
cvDestroyWindow("Example2_3");
return(0);
}


实现滚动条随着视频播放移动(回调函数)

以下是对照网上程序自己改的滚动条可移动:

#include <stdio.h>
#include <iostream>
#include <fstream>
#include "cv.h"
#include "highgui.h"

using namespace std;

int g_slider_position = 0;
int n = 0;
CvCapture* g_capture = NULL;

void onTrackbarSlide(int pos) {
cvSetCaptureProperty(
g_capture,
CV_CAP_PROP_POS_FRAMES,
pos
);
n = pos;     //增加变量n
return;
}

//Hack because sometimes the number of frames in a video is not accessible.
//Probably delete this on Widows
int getAVIFrames(char * fname)    //不知有何用
{
char tempSize[4];
// Trying to open the video file
ifstream  videoFile(fname, ios::in | ios::binary);
// Checking the availablity of the file
if (!videoFile) {
cout << "Couldn’t open the input file " << fname << endl;
exit(1);
}
// get the number of frames
videoFile.seekg(0x30, ios::beg);
videoFile.read(tempSize, 4);
int frames = (unsigned char)tempSize[0] + 0x100 * (unsigned char)tempSize[1] + 0x10000 * (unsigned char)tempSize[2] + 0x1000000 * (unsigned char)tempSize[3];
videoFile.close();
return frames;
}

int main(int argc, char** argv)
{
cvNamedWindow("Example2_3", CV_WINDOW_AUTOSIZE);
g_capture = cvCreateFileCapture(argv[1]);
IplImage *foo = cvQueryFrame(g_capture);

int frames = (int)cvGetCaptureProperty(
g_capture,
CV_CAP_PROP_FRAME_COUNT
);

int tmpw = (int)cvGetCaptureProperty(
g_capture,
CV_CAP_PROP_FRAME_WIDTH
);

int tmph = (int)cvGetCaptureProperty(
g_capture,
CV_CAP_PROP_FRAME_HEIGHT
);

printf("opencv frames %d w %d h %d\n", frames, tmpw, tmph);

/*frames = getAVIFrames(argv[1]); //This is a hack because on linux, getting number of frames often doesn't work

printf("hacked frames %d w %d h %d\n", frames, tmpw, tmph);*/           //这段屏蔽掉即可拖动任务条

if (frames != 0)
{
cvCreateTrackbar(
"Position",
"Example2_3",
&g_slider_position,
frames,
onTrackbarSlide
);
}
IplImage* frame=NULL;
frames = 0;
while (1) {
frame = cvQueryFrame(g_capture);
if (!frame) break;
//      int frames = cvGetCaptureProperty( g_capture, CV_CAP_PROP_POS_FRAMES);//This should work, sometimes it does not on linux
frames++; //My cheat
printf("\nFrame number=%d\n", frames);
cvSetTrackbarPos("Position", "Example2_3",n++);  //改动
cvShowImage("Example2_3", frame);
char c = (char)cvWaitKey(18);
if (c == 27) break;
}
cvReleaseCapture(&g_capture);
cvDestroyWindow("Example2_3");
return(0);
}


三、载入图像并做平滑处理(p26)

#include "cv.h"
#include "highgui.h"

void example2_4(IplImage* image)
{
// Create some windows to show the input
// and output images in.
cvNamedWindow("Example2_4-in", CV_WINDOW_AUTOSIZE);
cvNamedWindow("Example2_4-out", CV_WINDOW_AUTOSIZE);

// Create a window to show our input image
cvShowImage("Example2_4-in", image);

// Create an image to hold the smoothed output
IplImage* out = cvCreateImage(
cvGetSize(image),   //大小
IPL_DEPTH_8U,     //数据类型
3     //通道总数
);

// Do the smoothing
cvSmooth(image, out, CV_GAUSSIAN, 5, 5);  //使用每个像素周围5*5区域进行高斯平滑处理

// Show the smoothed image in the output window
cvShowImage("Example2_4-out", out);

// Be tidy
cvReleaseImage(&out);

// Wait for the user to hit a key, then clean up the windows
cvWaitKey(0);
cvDestroyWindow("Example2_4-in");
cvDestroyWindow("Example2_4-out");

}

int main(int argc, char** argv)
{
IplImage* img = cvLoadImage(argv[1]);
//cvNamedWindow("Example1", CV_WINDOW_AUTOSIZE);
//cvShowImage("Example1", img);
example2_4(img);
//cvWaitKey(0);
cvReleaseImage(&img);
cvDestroyWindow("Example1");
}


四、使用cvPyrDown()创建一幅宽度高度为输入图像一般尺寸的图像(p28)

该程序中分配新的图像空间时是从旧的图像中读取所需的信息。

#include "cv.h"
#include "highgui.h"

IplImage* doPyrDown(
IplImage* in,
int  filter = CV_GAUSSIAN_5x5)
{

// Best to make sure input image is divisible by two.
assert(in->width % 2 == 0 && in->height % 2 == 0);

IplImage* out = cvCreateImage(
cvSize(in->width / 2, in->height / 2),
in->depth,
in->nChannels
);
cvPyrDown(in, out);
return(out);
};

int main(int argc, char** argv)
{
IplImage* img = cvLoadImage(argv[1]);
IplImage* img2 = cvCreateImage(cvSize(img->width / 2, img->height / 2), img->depth, img->nChannels);
cvNamedWindow("Example1", CV_WINDOW_AUTOSIZE);
cvNamedWindow("Example2", CV_WINDOW_AUTOSIZE);
cvShowImage("Example1", img);
img2 = doPyrDown(img);
cvShowImage("Example2", img2);
cvWaitKey(0);
cvReleaseImage(&img);
cvReleaseImage(&img2);
cvDestroyWindow("Example1");
cvDestroyWindow("Example2");
}


【问题】:显示 未定义标识符 “IPL_GAUSSIAN_5x5”

【原因】:卷积滤波器的类型,目前仅支持“CV_GAUSSIAN_5x5”
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  opencv
相关文章推荐