《学习OpenCV》第4章 细说HighGUI

合集下载

OpenCV入门教程

OpenCV入门教程

O p e n C V入门教程-CAL-FENGHAI.-(YICAI)-Company One1OpenCV 入门教程作者:于仕琪年 8 月版权所有于仕琪本作品采用知识共享署名-相同方式共享国际许可协议进行许可。

1前言OpenCV 是一个广受欢迎的开源计算机视觉库,它提供了很多函数,实现了很多计算机视觉算法,算法从最基本的滤波到高级的物体检测皆有涵盖。

很多初学者希望快速掌握OpenCV 的使用方法,但往往会遇到各种各样的困难。

其实仔细分析,造成这些困难的原因有两类:第一类是C/C++编程基础不过关;第二类是不了解算法原理。

解决这些困难无非提升编程能力,以及提升理论基础知识。

提升编程能力需要多练习编程,提升理论知识需要系统学习《数字图像处理》、《计算机视觉》和《模式识别》等课程,所有这些都不能一蹴而就,需要耐下心来认真修炼。

同时我们也需要认识到 OpenCV 只是一个算法库,能为我们搭建计算机视觉应用提供“砖头”。

我们并不需要完全精通了算法原理之后才去使用 OpenCV,只要了解了“砖头”的功能,就可以动手了。

在实践中学习才是最高效的学习方式。

本小册子希望为初学者提供引导,使初学者快速了解 OpenCV 的基本数据结构以及用法。

此外,如您发现有错误之处,欢迎来信指正。

于仕琪深圳大学插播广告:欢迎有能力、有激情以及对计算机视觉有兴趣的同学报考我的研究生。

欲了解详情可以访问深圳大学招生网或者给我发 email。

目录第 1 章预备知识 (5)编程的流程 (5)什么叫编辑 (6)什么叫编译 (6)什么叫连接 (7)什么叫运行 (7)Visual C++是什么 (8)头文件 (9)库文件 (10)OpenCV 是什么 (11)什么是命令行参数 (12)常见编译错误 (13)找不到头文件 (13)拼写错误 (14)常见链接错误 (15)运行时错误 (17)第 2 章OpenCV 介绍 (19)OpenCV 的来源 (19)OpenCV 的协议 (19)第 3 章图像的基本操作 (21)图像的表示 (21)Mat 类 (23)创建 Mat 对象 (24)构造函数方法 (24)create()函数创建对象 (25)Matlab 风格的创建对象方法 (26)矩阵的基本元素表达 (26)像素值的读写 (27)at()函数 (28)使用迭代器 (29)通过数据指针 (30)选取图像局部区域 (32)单行或单列选择 (32)用 Range 选择多行或多列 (33)感兴趣区域 (33)取对角线元素 (34)Mat 表达式 (34)Mat_类 (36)Mat 类的内存管理 (38)输出 (40)Mat 与 IplImage 和 CvMat 的转换 (42)Mat 转为 IplImage 和 CvMat 格式 (42)IplImage 和 CvMat 格式转为 Mat (42)第 4 章数据获取与存储 (44)读写图像文件 (44)读图像文件 (44)写图像文件 (45)读写视频 (47)读视频 (47)写视频 (49)第1章预备知识OpenCV 是一个功能强大的计算机视觉库,要用好它,除了要具有相关的计算机视觉理论知识外,还需要具有一定的编程能力。

《学习OPENCV》4第四章 细说HighGUI

《学习OPENCV》4第四章 细说HighGUI
CvCapture* cvCreateFileCapture(const char* filename);
CvCapture* cvCreateCameraCapture(int index);
注:要注意检查函数返回值。
cvCreateCameraCapture()参数设置为-1时,OpenCV会打开一个窗口让用户选择需要摄像机。
value : 它是一个整数指针,当滑动条被拖动时,OpenCV会自动将当前位置所代表的值传递给指针指向的整数。
count : 滑动条所能表示的最大值。
on_change: 指向回调函数的指针,当滑动条被拖动时,回调 函数会自动 被调用。
读取、设置滑动条的值。
int cvGetTrackbarPos(const char* trackbar_name,const char* window_name);
2.cvDestroyWindow()
释放窗口
3.opencv所使用的窗口名称与各个窗口系统所使用的窗口句柄之间进行转换。
void* cvGetWindowHandle(const char* name);
const char* cvGetWindowName(void* window_handle);
int fourcc,
double fps,
CvSize frame_size,
int is_color = 1
);
int cvWriterFrame(CvVideoWriter* writer,const IplImage* image);
void cvReleaseWriter(CvVideoWirter** writer);

opencv 4计算机视觉应用程序编程手册

opencv 4计算机视觉应用程序编程手册

opencv 4计算机视觉应用程序编程手册OpenCV 4计算机视觉应用程序编程手册一、OpenCV 4简介与安装OpenCV(Open Source Computer Vision Library)是一款开源的计算机视觉库,广泛应用于图像处理、视频分析、特征提取、目标检测等领域。

OpenCV 4在性能和功能上均有显著提升,支持Python、C++等多种编程语言。

本手册将带领读者了解OpenCV 4的基本概念,并在各种平台上安装使用。

二、计算机视觉基础概念与原理计算机视觉是一门研究如何让计算机从图像或视频中获取有意义信息的科学。

其主要任务包括图像处理、特征提取、目标检测、目标跟踪等。

在本章节中,我们将学习计算机视觉的基本概念和原理,为后续的实际项目打下基础。

三、图像处理与分析图像处理是计算机视觉的核心任务之一,主要包括图像读取、显示、存储、滤波、边缘检测等操作。

在本章节中,我们将学习OpenCV 4中常用的图像处理函数,并了解其应用场景。

四、特征提取与匹配特征提取是计算机视觉中关键的一环,旨在从图像中提取具有代表性的特征点。

常见的特征提取算法有SIFT、SURF、ORB等。

特征匹配则是寻找两幅图像中对应的特征点,常用的方法有暴力匹配、FLANN等。

在本章节中,我们将学习这些算法的原理及使用方法。

五、目标检测与跟踪目标检测是在图像或视频中查找特定目标的过程,常用的算法有R-CNN、Fast R-CNN、Faster R-CNN、SSD、YOLO等。

目标跟踪则是跟踪目标在连续帧中的位置,常用的方法有TLD、KCF等。

在本章节中,我们将学习这些目标检测与跟踪算法的原理及实现。

六、3D建模与增强现实3D建模是将二维图像转换为三维模型的一种技术,常用的工具有Open3D、Maya等。

增强现实则是将虚拟物体叠加到真实场景中,常用的框架有ARCore、ARKit等。

在本章节中,我们将学习3D建模与增强现实的基本原理及应用。

opencv自学笔记

opencv自学笔记

OPENCV一、Opencv 基本架构分析多模块组合起来的一个软件开发工具包(SDK)1、【calib3d】2、【cntrib】3、【core】:核心功能模块。

4、【imgproc】:图像处理模块。

5、【features2d】6、【flann】7、【gpu】8、【highgui】:高层GUI图形用户界面,包含媒体的输入输出、视频捕捉、图像视频的编码和解码、图形交互界面的接口内容等。

9、【legacy】…二、HighGui图形用户界面初步1、opencv的命名空间:opencv的C++类和函数都是定义在命名空间cv之内的,访问方法:(1)、在代码开头的适当位置加上using namespace cv (2)、在使用opencv的每个内和函数时,都加入cv::命名空间。

2、图像的载入:imread()函数Mat imread(const string& filename, int flags=1);(1)、const string&类型的filename,填我们需要载入的图片路径名称。

(2)、int类型的flags,为载入标志,它指一个加载图像的颜色类型。

3、图像的显示:imshow()函数Void imshow(const string& winname, InputArray mat);(1)、const string&类型的winname,填需要显示的窗口标识名称。

(2)、InputArray类型的mat,填需要显示的图像。

4、创建窗口:namedWindow()函数void namedWindow(const string& winname, int flags=WINDOW_AUTOSIZE);(1)、const string&类型的name,填写被作用窗口的标识符的窗口名称。

(2)、int类型的flags,窗口的标识,可填写WINDOW_AUTOSIZE、WINDOW_NORMAL或WINDOW_OPENGL5、输出到文件:imwrite()函数bool imwrite(const string& finename, InputArray img , const vector<int>& params=vector<int>() );(1)、const string&类型的finename,填需要写入的文件名。

Opencv学习之路——自己编写的HOG算法

Opencv学习之路——自己编写的HOG算法

Opencv学习之路——⾃⼰编写的HOG算法#include<opencv2\core\core.hpp>#include<opencv2\highgui\highgui.hpp>#include<opencv2\opencv.hpp>#include<iostream>#include<fstream>using namespace std;using namespace cv;#define Max 100class Cell{private:int pixel_x; //cell的像素的起始位置⾏坐标;int pixel_y; //cell的像素的起始位置纵坐标;Mat img; //待处理的图像,通常该该图像是经过Gamma校正的灰度图;double pixel[10][10]; //我们⼀般默认cell为8*8的像素⼤⼩,但是为了储存周边店的像素,需要多加两个像素储存点的位置;double gradient_M[9][9]; //保存梯度的幅值;double gradient_Angle[9][9]; //保存像素梯度的⽅向;double gradient_h[9][9];double gradient_v[9][9];public:double bin[9]; //将梯度⽅向分成九个⽅向,在根据具体像素梯度的⽅向⼤⼩,进⾏投票;Cell(Mat src){ //构造函数;img=src;}void Set_Cell(int x,int y);void Get_Pixel(); //为了计算机使⽤⽅便,我们把⼀个cell当中的像素先读下来,⽤pixel[][]数组储存;void Gradient_Pixel(); //计算机图像像素的梯度幅值和梯度⾓度;void Bin_Selection_Normalization(); //根据每个像素的幅值进⾏维度的区分和归⼀化,并且返回bin[]数组;};void Cell::Set_Cell(int x,int y){pixel_x=x;pixel_y=y;}void Cell::Get_Pixel(){for(int i=pixel_x-1,m=0;i<pixel_x+9;i++,m++){uchar *data=img.ptr<uchar>(i);for(int j=pixel_y-1,n=0;j<pixel_y+9;j++,n++){pixel[m][n]=data[j];}}// for(int i=0;i<9;i++){// for(int j=0;j<9;j++){// cout<<i<<j<<" "<<pixel[i][j]<<"\n";// }// }}void Cell::Gradient_Pixel(){for(int i=1;i<9;i++){for(int j=1;j<9;j++){gradient_h[i][j]=pixel[i+1][j]-pixel[i-1][j];gradient_v[i][j]=pixel[i][j+1]-pixel[i][j-1];gradient_M[i][j]=sqrt(gradient_h[i][j]*gradient_h[i][j]+gradient_v[i][j]*gradient_v[i][j]);gradient_Angle[i][j]=atan2(gradient_h[i][j],gradient_v[i][j])*180;}}// for(int i=0;i<9;i++){// for(int j=0;j<9;j++){// cout<<i<<j<<" "<<gradient_h[i][j]<<" "<<gradient_v[i][j]<<" "<<gradient_M[i][j]<<" "<<gradient_Angle[i][j]<<"\n";// }// }}void Cell::Bin_Selection_Normalization(){for(int i=0;i<9;i++){bin[i]=0;}for(int i=1;i<9;i++){for(int j=1;j<9;j++){if((gradient_Angle[i][j]>=0&&gradient_Angle[i][j]<20)||(gradient_Angle[i][j]>=180&&gradient_Angle[i][j]<200)){bin[0]=bin[0]+gradient_M[i][j];if((gradient_Angle[i][j]>=20&&gradient_Angle[i][j]<40)||(gradient_Angle[i][j]>=200&&gradient_Angle[i][j]<220)){bin[1]=bin[1]+gradient_M[i][j];}if((gradient_Angle[i][j]>=40&&gradient_Angle[i][j]<60)||(gradient_Angle[i][j]>=220&&gradient_Angle[i][j]<240)){bin[2]=bin[2]+gradient_M[i][j];}if((gradient_Angle[i][j]>=60&&gradient_Angle[i][j]<80)||(gradient_Angle[i][j]>=240&&gradient_Angle[i][j]<260)){bin[3]=bin[3]+gradient_M[i][j];}if((gradient_Angle[i][j]>=80&&gradient_Angle[i][j]<100)||(gradient_Angle[i][j]>=260&&gradient_Angle[i][j]<280)){bin[4]=bin[4]+gradient_M[i][j];}if((gradient_Angle[i][j]>=100&&gradient_Angle[i][j]<120)||(gradient_Angle[i][j]>=280&&gradient_Angle[i][j]<300)){ bin[5]=bin[5]+gradient_M[i][j];}if((gradient_Angle[i][j]>=120&&gradient_Angle[i][j]<140)||(gradient_Angle[i][j]>=300&&gradient_Angle[i][j]<320)){ bin[6]=bin[6]+gradient_M[i][j];}if((gradient_Angle[i][j]>=140&&gradient_Angle[i][j]<160)||(gradient_Angle[i][j]>=320&&gradient_Angle[i][j]<340)){ bin[7]=bin[7]+gradient_M[i][j];}if((gradient_Angle[i][j]>=160&&gradient_Angle[i][j]<=180)||(gradient_Angle[i][j]>=340&&gradient_Angle[i][j]<=360)){ bin[8]=bin[8]+gradient_M[i][j];}}}//////////////////////////////////////归⼀化;double sum_bin=0;for(int i=0;i<9;i++){sum_bin=sum_bin+bin[i];}for(int i=0;i<9;i++){bin[i]=bin[i]/sum_bin;if(bin[i]>0.2){bin[i]=0.2;}}sum_bin=0;for(int i=0;i<9;i++){sum_bin=sum_bin+bin[i];}for(int i=0;i<9;i++){bin[i]=bin[i]/sum_bin;}}//Block类部分****************class Block{int block_pixel_x; //block的起始像素点横坐标位置;int block_pixel_y; //block的起始像素点纵坐标位置;Mat src; //图像必须是灰度图;double bins[38]; //该类主要是对block进⾏相关处理,我们默认block为四个cell,即2*2;所以bins为36维;int k;public:Block(Mat img){src=img;k=0;}void Set_Block(int x,int y);void Cut_Block(); //本⼈认为这是整个算法当中⽐较重要的⼀部分,即图像切割划分部分;void Block_into_HistImage();void output_bins();};void Block::Set_Block(int x,int y){block_pixel_x=x;block_pixel_y=y;}void Block::Cut_Block(){k=0;Cell cell(src);for(int i=block_pixel_x, m=0;m<2;i=i+8,m++){for(int j=block_pixel_y, n=0;n<2;j=j+8,n++){cell.Set_Cell(i,j);cell.Get_Pixel();cell.Gradient_Pixel();cell.Bin_Selection_Normalization();for(int i=0;i<9;i++){bins[k++]=cell.bin[i];}}}void Block::Block_into_HistImage(){ //该部分算法是将bins⽣成直⽅图;int hight=256;int width=80;IplImage *hist_image=cvCreateImage(Size(80,256),8,3);for(int i=0;i<36;i++){cvRectangle(hist_image,CvPoint(i*2,hight-1),CvPoint((i+1)*2-1,hight-bins[i]*100),CV_RGB(255,255,255)); }cvNamedWindow("1",1);cvShowImage("1",hist_image);cvWaitKey(0);}void Block::output_bins(){//ofstream out ("1.txt");for(int i=0;i<36;i++){cout<<bins[i]<<"\n";}cout<<"*******************************************\n";}int main(){Mat img=imread("G:/2.png",1); //载⼊图⽚;if(img.empty()){return -1;}Mat gray1;Mat gray;cvtColor(img,gray1,COLOR_RGB2GRAY);resize(gray1,gray,Size(130,66),0,0,1);namedWindow("gray",1);imshow("gray",gray);// cvWaitKey(0);Block block(gray);for(int i=1,m=0;m<7;m++,i=i+8){for(int j=1,n=0;n<15;n++,j=j+8){block.Set_Block(i,j);block.Cut_Block();//block.Block_into_HistImage();block.output_bins();}}}。

基于OpenCV图像处理系统的开发与实现

基于OpenCV图像处理系统的开发与实现

基于OpenCV图像处理系统的开发与实现刘培军;马明栋;王得玉【摘要】In the research of digital image processing technology, when a small number of images are processed, various image processing algorithms are generally used for programming according to different requirements, and there are a lot of repetitive work. However, when the amount of digital image data is large and the real-time requirement of processed images is high, all images are processed, codes and algorithms are written manually, which is quite difficult and inefficient. In order to effectively solve the above problems, based on OpenCV computer vision library and under the integrated development environment of Qt Creator, we develop and implement an image processing system of object-oriented programming with better interface and convenient for users. The practice of digital image processing shows that the system can process images efficiently and quickly.%在数字图像处理技术的研究过程中,基于平时对少量图像进行处理时,一般都是针对不同需求运用各种图像处理算法进行编程,存在着许多重复性工作.而当数字图像数据量非常大且对处理的图像实时性要求非常高时,对所有图像进行处理,代码以及算法的实现都通过人工进行编写,存在着相当大的难度且效率十分低下.为有效解决上述问题,以OpenCV计算机视觉库为基础,在Qt Creator 集成开发环境下,采用面向对象编程,开发并实现了一款界面良好,方便用户使用的图像处理系统.通过对大量数字图像处理的实践表明,该系统能够有效快速地对图像进行处理.【期刊名称】《计算机技术与发展》【年(卷),期】2019(029)003【总页数】5页(P127-131)【关键词】图像处理算法;OpenCV;Qt Creator;面向对象;图像处理系统【作者】刘培军;马明栋;王得玉【作者单位】南京邮电大学通信与信息工程学院, 江苏南京 210003;南京邮电大学地理与生物信息学院, 江苏南京 210023;南京邮电大学地理与生物信息学院, 江苏南京 210023【正文语种】中文【中图分类】TP3020 引言在计算机技术如此成熟的今天,图像处理理论与技术已经得到了较为全面的发展并在持续不断的优化创新中,尤其在人工智能、航空航天、工业部件检测、交通、医学等领域得到了广泛应用[1-2]。

opencv4应用开发-入门,进阶与工程化实践

opencv4应用开发-入门,进阶与工程化实践引言随着计算机视觉技术的飞速发展,OpenCV已成为计算机视觉领域的核心库。

OpenCV4在图像处理、目标检测、机器学习等领域的应用日益广泛。

本文将带领大家从入门到进阶,再到工程化实践,深入探索OpenCV4的魅力。

第一部分:入门篇1.1 OpenCV4简介首先,我们来了解一下OpenCV4。

OpenCV是一个开源的计算机视觉库,包含了大量的图像处理和计算机视觉的算法。

OpenCV4在保持原有功能的基础上,进一步优化了算法性能,并增加了许多新的功能模块。

1.2 环境配置在开始OpenCV的学习之前,我们需要配置好开发环境。

这包括安装OpenCV 库、选择合适的编程语言(如Python、C++等)以及相应的开发工具(如PyCharm、Visual Studio等)。

1.3 基本操作在掌握了环境配置后,我们可以开始学习OpenCV的基本操作,如图像的读取、显示、保存等。

通过这些基础操作,我们可以对图像进行简单的处理,如灰度转换、噪声去除等。

第二部分:进阶篇2.1 图像处理算法在掌握了基本操作后,我们可以进一步学习OpenCV提供的各种图像处理算法,如滤波、边缘检测、形态学处理等。

这些算法可以帮助我们更好地理解和处理图像。

2.2 目标检测与跟踪目标检测和跟踪是计算机视觉的重要应用之一。

OpenCV提供了多种目标检测和跟踪的方法,如Haar级联、HOG+SVM、深度学习模型等。

通过这些方法,我们可以实现人脸检测、行人检测等功能。

2.3 机器学习与计算机视觉近年来,机器学习在计算机视觉领域的应用越来越广泛。

OpenCV4结合了多种机器学习算法,如支持向量机、随机森林等,使得我们可以在计算机视觉任务中更好地利用机器学习的能力。

第三部分:工程化实践篇3.1 项目管理与团队协作在大型项目中,良好的项目管理至关重要。

我们需要根据项目的需求,制定合适的开发计划,并进行有效的团队协作。

OpenCV源码架构讲解

OpenCV源码架构讲解1. Core(核心):此模块包含了OpenCV的核心功能,如矩阵操作、数据类型、数组和向量运算等。

该模块提供了基础的数据结构和函数,为其他模块的实现提供支持。

2. Imgproc(图像处理):此模块提供了各种图像处理函数,如滤波、边缘检测、图像变换等。

它包含了大量的图像处理算法,并提供了丰富的工具函数,方便用户进行图像处理操作。

3. Highgui(图形用户界面):该模块提供了图形用户界面相关的函数,如图像显示、鼠标事件处理、键盘事件处理等。

它可以帮助用户在图像处理过程中进行交互操作,方便调试和分析。

4. Video(视频处理):此模块提供了与视频处理相关的函数,如视频捕捉、视频压缩、视频写入等。

它支持从摄像机、文件或其他源中读取视频流,并提供了一系列的视频处理算法。

5. Objdetect(对象检测):该模块提供了对象检测相关的函数,如人脸检测、行人检测等。

它提供了训练好的模型和相应的算法,可以用于识别和跟踪不同种类的对象。

此外,OpenCV还包含了一些辅助模块,如ml(机器学习)、calib3d (相机标定和三维重建)、features2d(特征检测和描述子)、videoio (视频IO)、flann(最近邻)等。

OpenCV的源码采用模块化的结构,使得用户可以灵活地选择所需的模块,以适应不同的应用场景。

每个模块都有自己的命名空间和头文件,以避免命名冲突。

同时,源码还提供了丰富的示例和文档,方便用户使用和理解。

在OpenCV的源码中,各个模块之间存在着一定的依赖关系,需要进行编译和链接才能生成可执行文件。

此外,OpenCV还提供了对Python、Java等语言的接口,使得用户可以在不同的平台上使用OpenCV。

总之,OpenCV的源码架构是基于C++实现的,模块化设计使得用户可以方便地选择所需的功能模块。

各个模块之间存在着一定的依赖关系,通过编译和链接可以生成可执行文件。

opencve 源码解读

OpenCV是一个开源的计算机视觉和机器学习软件库,它包含了多个用于图像处理和计算机视觉的算法和函数。

下面是对OpenCV源码的一些解读:架构和组成OpenCV的源码主要由C++编写,同时也支持Python和Java等语言。

它主要由以下几个模块组成:Core:提供基本的图像处理和计算机视觉功能,如图像读取、保存、转换、滤波等。

Imgproc:提供一些高级的图像处理函数,如图像分割、特征提取、形态学操作等。

Video:提供视频处理和分析的函数,如视频捕获、编码、解码等。

HighGUI:提供用户界面功能,如窗口创建、鼠标和键盘事件处理等。

Contrib:提供一些额外的算法和功能,如SIFT、SURF等。

算法实现OpenCV包含了许多经典的计算机视觉算法和深度学习模型,如SIFT、SURF、HOG、YOLO等。

这些算法和模型的实现方式各不相同,但都经过了精心的优化和效率提升。

在OpenCV中,一些算法的实现采用了C++的模板函数和内联函数等技术,以提高计算效率。

跨平台支持OpenCV支持多个操作系统和硬件平台,包括Windows、Linux、MacOS、Android和iOS等。

为了实现跨平台支持,OpenCV的源码中包含了许多与平台相关的代码,如OpenGL的渲染、摄像头的访问等。

此外,OpenCV还提供了Python和Java等语言的接口,方便不同语言的开发者使用。

性能优化OpenCV的源码中包含了许多性能优化的技巧,如使用并行计算、缓存优化、内存管理等。

这些技巧可以提高OpenCV的运行速度和处理能力,使其能够处理大规模的数据和高性能的计算任务。

总之,OpenCV是一个功能强大、性能优良、跨平台支持的计算机视觉库,它的源码包含了丰富的算法和功能,同时也具有很好的可读性和可维护性。

通过对OpenCV源码的解读,可以更好地了解其功能和实现方式,为开发者和用户提供更好的支持和帮助。

OpenCV的四大模块

理函数和高级的计算机视觉算法
OpenCV的 四 大 模 块
前言 我们都知道 OpenCV 是一个开源的计算机视觉库,那么里面到底有哪些东西?本文将为你解答这个问题。 模块一:CV 这个模块是 OpenCV 的核心,它包含了基本的图像处理函数和高级的计算机视觉算法。 模块二:HighGUI 这个模块包含了图像和视频的基本 GUI 输入输出函数。 模块三:MILL 这个模块是计算机学习库,包含一些基于统计的分类和聚类工具。 模块四:CXCORE 这个模块包含了基本数据结构和一些最基本的函数。上面四个模块都要调用此模块。
下图可形象表述OpenCV的四大模块
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

方便起见,我们使用文件名来表示窗口名称。这样处理 很好,因为OpenCV默认将窗口名称显示在窗口的顶部, 这使得我们可以知道正在看的是哪一幅图像(见图41)。这是很容易的一件事。
在进入下一部分前,有一些其他窗口相关的函数需要了 解,具体如下:
void cvMoveWindow(const char* name, int x, int y); void cvDestroyAllWinodws(void); void cvStartWindowThread(void);
如果想读入数据与原始图像通道数以及位数保持一致, 也可以使用CV_LOAD_IMAGE_UNCHAGNED。需要注意 的是,当cvLoadImage()读入失败,并不会产生一个运 行时错误,而是返回一个空指针。 与cvLoadImage()对应的函数是cvSaveImage(),实现了保 存图像功能,cvSaveImage()有两个参数:
Hale Waihona Puke 题操心。 话虽如此,还是有些人担心HighGUI内部的处理,那没 关系。HighGUI提供了以下函数:
void* cvGetWindowHandle(const char* name); const char* cvGetWindowName(void* window_handle);
这些函数允许我们在OpenCV所使用的窗口名称与各个窗 口系统所使用的窗口句柄之间进行转换。 HighGUI提供了cvResizeWindow()用来调整窗口的大小:
int cvSaveImage( const char* filename, const CvArr* image );
第一个参数表示文件名,其中后缀部分用来指定图像存 储的编码格式。回忆前一章讲到的,CvArr是一种C语 言风格的,功能与面向对象语言中基类类似的结构。 当你看到CvArr*时,你可以用IplImage*参数传入。对
鼠标事件 现在我们已经可以显示一张图像给用户,我们现在希望 给用户添加一些交互功能。由于我们在窗口环境下工 作,而且我们已经知道如何使用cvWaitKey()来捕捉单 次用户触发事件,我们下一步需要做的是如何捕捉以 及响应鼠标事件。
与键盘事件响应不同,鼠标事件响应采用回调函数的方 式来处理。即,为了可以响应鼠标点击事件,首先必 须创建一个回调函数,使鼠标点击事件发生时OpenCV 可以调用这个函数。创建这个函数以后,需要在 OpenCV中注册这个函数,以便特定窗口被触发鼠标事 件以后,OpenCV可以正确调用这个函数。 让我们从这个回调函数开始,回调函数callback可以是满
void cvShowImage( const char* name, const CvArr* image );
第一个参数用来指定用来显示图像的窗口,第二个参数 指向需要显示的图像。
现在让我们用前面提到的一些函数完成一个简单的程序。这 个程序通过命令行读入文件名,创建窗口并且将图像显示 的窗口中。它包括注释和内存清理部分在内,它共有25行!
情况下,图像是以每个通道8位,3个通道的形式被读入; 可以通过设置CV_LOAD_IMAGE_ANYDEPTH来读入非8 位的图像。默认情况下的通道为3,因为参数iscolor的 默认值是CV_LOAD_IMAGE_COLOR,这意味着不管原 始图像的通道数为多少,都将被转换为3个通道读入。 相对于CV_LOAD_IMAGE_COLOR,iscolor也可以被设置 成CV_LOAD_IMAGE_GRAYSCALE和 CV_LOAD_IMAGE_ANYCOLOR。类似于 CV_LOAD_IMAGE_COLOR将读入图像强制转换为3个通 道,CV_LOAD_IMAGE_GRAYSCLAE将读入图像强制转换 为单通道。CV_LOAD_IMAGE_ANYCOLOR则以保持原始 图像通道数的方式读入。这样,为了读入16位的彩色 图像,我们需要设置iscolor为 CV_LOAD_IMAGE_COLOR|CV_LOAD_IMAGE_ANYDEPTH。
IplImage* cvLoadImage( const char* filename, int iscolor = CV_LOAD_IMAGE_COLOR );
当打开一幅图像时,cvLoadImage()并不分析文件扩展名, 而是通过分析图像文件的前几个字节来确定图像的编 码格式。第二个参数iscolor有几个值可以选择。默认
创建窗口
首先,我们要做的是利用HighGUI将一幅图像显示到 屏幕上。我们使用cvNameWindow()来实现这个功 能。这个函数接受两个参数,第一个参数用来表 示新窗口的名称,这个名称显示在窗口的顶部, 同时用作HighGUI中其他函数调用窗口的句柄。第 二个参数是一个标志,用来表示是否需要使窗口 大小自动适应读入的图像大小。下面是这个函数 的定义:
WaitKey 在前面的创建窗口例子的循环语句中,有一个新的函数 我们前面没有看到过:cvWaitKey()。这个函数在一个 给定的时间内(单位ms)等待用户按键触发。如果在 给定时间内用户按下了一个键,函数返回用户按下的 键,否则,返回0。具体使用如下:
while(1){ if(cvWaitKey(100)==27) break; }
于大部分文件格式,cvSaveImage()只能存储8位单通道或 者8位3个通道格式的图像。新的文件格式像PNG, TIFF或者JPEG2000允许存储16位甚至浮点类型格式, 同样也部分支持4通道格式(BGRA)的图像。当存储 成功时,返回1,否则返回0。
显示图像
准备工作做完了,现在让我们来做一些我们一直想做的 事情,从磁盘中载入一张图像,并在窗口中显示出来, 让我们来享受这一过程吧!为了完成这个功能,我们 还需要了解一个简单的函数cvShowImage():
int cvNamedWindow( const char* name, int flags = CV_WINDOW_AUTOSIZE );
需要留意的是参数flags,到目前为止,唯一有效的设置 是0或者保持默认设置CV_WINDOW_AUTOSIZE。如果 使用CV_WINDOW_AUTOSIZE,HighGUI会根据图像的 大小调整窗口大小。这样,窗口大小会随着图像的载 入而根据图像大小调整,用户没办法手动调整窗口大 小。当然,如果不想窗口大小自动调整,也可以将参 数值设置为0,这样的话,用户就可以随意调整窗口 的大小了。 当窗口被创建以后,我们通常是想加入一些东西到里面。 不要着急,在做这些事情之前,我们先看看当不需要 这些窗口时,如何释放它们。为了释放窗口,我们需 要使用cvDestroryWindow(),这个函数接收一个字符 串参数,这个字符串是窗口创建时所指定的名字。 在OpenCV中,窗口根据名称来引用(操作系统独立的) 而不是一些“不友好”的句柄。句柄与窗口名称之间 的转换都由HighGUI在后台处理,我们不用为这些问
第4章 细说HighGUI
本章各小节目录
• • • • • • • 一个可移植的图形工具包 创建窗口 载入图像 显示图像 视频的处理 ConvertImage函数 练习
一个可移植的图形工具包
OpenCV将与操作系统、文件系统和摄像机之类的硬 件进行交互的一些函数纳入HighGUI(high-level graphical user interface)库中。有了HighGUI,我们 可以方便地打开窗口、显示图像、读出或者写入 图像相关的文件(包含图像与视频)、处理简单 的鼠标、光标和键盘事件。我们也可以使用 HighGUI创建其他一些很有用的空间,比如滑动条, 并把它们加入窗口。如果对自己所使用的系统的 图形用户界面非常熟悉,也许会认为HighGUI提供 的很多功能是没有必要的,但即使如此,HighGUI 的跨平台性对你也会有很大帮助。
这个程序中,我们告诉OpenCV等待用户触发事件100ms, 如果在100ms内没有用户触发,则继续循环;如果有 用户触发且按键ASCII码为27(Esc键),则退出循环。 这使得用户可以从容地仔细查看图像,直到按Esc键
退出。 提到cvWaitKey(),需要介绍的是cvWaitKey()可以接收0作 为参数。在这种情况下,cvWaitKey()会无限期地等待, 直到用户触发一个按键。在前面的程序中,可以用 cvWaitKey(0)来代替我们的实现。这两者实现的区别 在于显示一个视频的时候会体现出来,因为在视频播 放过程中,我们希望播放下一帧,即使用户没有触发 事件。
cvMoveWindow()将窗口移动到其左上角为x, y的位置。 cvDestroyAllWindows()是一个很有用的清理函数,用来 关闭所有窗口并释放窗口相关的内存空间。 在Linux或者Mac操作系统中,cvStartWindowThread()用 来创建一个线程用来自动更新窗口以及处理其他窗口 触发事件。返回值为0表示没有创建出线程,如果目 前使用的OpenCV版本并不支持这个功能则返回0。注 意,如果没有创建一个独立的窗口线程,OpenCV只会 在明显式指定的时间里面处理用户交互(这需要程序 调用cvWaitKey,在后面的章节会具体描述)。
int main(int argc, char** argv) { //Create a named window with the name of the file. cvNamedWindow("aaa", 1); //"aaa" argv[1] //Load the image from the given file name. IplImage* img = cvLoadImage("E:\\Pictures\\man.jpg"); // //Show the image in the named window cvShowImage("aaa", img); //Idle until the user hits the "Esc" key while(1){ if(cvWaitKey(100)==27)break; } //Clean up and don't be piggies cvDestroyWindow("aaa"); cvReleaseImage(&img); exit(0); }
相关文档
最新文档