2014-12-05 07:16:03 u010644209 阅读数 2684
举报

目录(?)[+]

机器视觉开源处理库汇总


cvchina搞到的机器视觉开源处理库汇总,转来了,很给力,还在不断更新。。。

通用库/General Library

无需多言。

Recognition And Vision Library. 线程安全。强大的IO机制。包含AAM。

很酷的一个图像处理包。整个库只有一个头文件。包含一个基于PDE的光流算法。

图像,视频IO/Image, Video IO

AR相关/Augmented Reality

基于Marker的AR库

ARToolKit的增强版。实现了更好的姿态估计算法。

实时的跟踪、SLAM、AR库。无需Marker,模板,内置传感器等。

基于特征点检测和识别的AR库。

局部不变特征/Local Invariant Feature

目前最好的Sift开源实现。同时包含了KD-tree,KD-Forest,BoW实现。

基于Naive Bayesian Bundle的特征点识别。高速,但占用内存高。

基于OpenCV的Sift实现。

目标检测/Object Detection

又一个AdaBoost实现。训练速度快。

基于Centrist和Linear SVM的快速行人检测。

(近似)最近邻/ANN

目前最完整的(近似)最近邻开源库。不但实现了一系列查找算法,还包含了一种自动选取最快算法的机制。

另外一个近似最近邻库。

SLAM & SFM

monoSLAM库。由Androw Davison开发。

图像分割/Segmentation

使用Simple Linear Iterative Clustering产生指定数目,近似均匀分布的Super Pixel。

目标跟踪/Tracking

基于Online Random Forest的目标跟踪算法。

Kanade-Lucas-Tracker

Online Boosting Trackers

直线检测/Line Detection

基于联通域连接的直线检测算法。

基于梯度的,局部直线段检测算子。

指纹/Finger Print

基于感知的多媒体文件Hash算法。(提取,对比图像、视频、音频的指纹)

视觉显著性/Visual Salience

Ming-Ming Cheng的视觉显著性算法。

/DWT

最快,最好的开源FFT。

轻量级的FFT实现。许可证是亮点。

音频处理/Audio processing

音频处理,音频合成。

音频文件IO。

音频重采样。

小波变换

快速小波变换(FWT)

BRIEF: Binary Robust Independent Elementary Feature 一个很好的局部特征描述子,里面有FAST corner + BRIEF实现特征点匹配的DEMO:http://cvlab.epfl.ch/software/brief/

http://code.google.com/p/javacv


Java打包的OpenCV, FFmpeg, libdc1394, PGR FlyCapture, OpenKinect, videoInput, and ARToolKitPlus库。可以放在Android上用~

 

libHIK,HIK SVM,计算HIK SVM跟Centrist的Lib。http://c2inet.sce.ntu.edu.sg/Jianxin/projects/libHIK/libHIK.htm

 

一组视觉显著性检测代码的链接:http://cg.cs.tsinghua.edu.cn/people/~cmm/saliency/



介绍n款计算机视觉库/人脸识别开源库/软件

计算机视觉库 OpenCV

OpenCV是Intel®开源计算机视觉库。它由一系列 C 函数和少量 C++ 类构成,实现了图像处理和计算机视觉方面的很多通用算法。 OpenCV 拥有包括 300 多个C函数的跨平台的中、高层 API。它不依赖于其它的外部库——尽管也可以使用某些外部库。 OpenCV 对非商业...

人脸识别 faceservice.cgi

faceservice.cgi 是一个用来进行人脸识别的 CGI 程序, 你可以通过上传图像,然后该程序即告诉你人脸的大概坐标位置。faceservice是采用 OpenCV 库进行开发的。

OpenCV的.NET版 OpenCVDotNet

OpenCVDotNet 是一个 .NET 对 OpenCV 包的封装。

人脸检测算法 jViolajones

jViolajones是人脸检测算法Viola-Jones的一个Java实现,并能够加载OpenCV XML文件。 示例代码:http://www.oschina.net/code/snippet_12_2033

Java视觉处理库 JavaCV

JavaCV 提供了在计算机视觉领域的封装库,包括:OpenCV、ARToolKitPlus、libdc1394 2.x 、PGR FlyCapture和FFmpeg。此外,该工具可以很容易地使用Java平台的功能。 JavaCV还带有硬件加速的全屏幕图像显示(CanvasFrame),易于在多个内核中执行并行代码(并...

运动检测程序 QMotion

QMotion 是一个采用 OpenCV 开发的运动检测程序,基于 QT。

视频监控系统 OpenVSS

OpenVSS - 开放平台的视频监控系统 - 是一个系统级别的视频监控软件视频分析框架(VAF)的视频分析与检索和播放服务,记录和索引技术。它被设计成插件式的支持多摄像头平台,多分析仪模块(OpenCV的集成),以及多核心架构。

手势识别 hand-gesture-detection

手势识别,用OpenCV实现

人脸检测识别 mcvai-tracking

提供人脸检测、识别与检测特定人脸的功能,示例代码 cvReleaseImage( &gray ); cvReleaseMemStorage(&storage); cvReleaseHaarClassifierCascade(&cascade);...

人脸检测与跟踪库 asmlibrary

Active Shape Model Library (ASMLibrary©) SDK, 用OpenCV开发,用于人脸检测与跟踪。

Lua视觉开发库 libecv

ECV 是 lua 的计算机视觉开发库(目前只提供linux支持)

OpenCV的.Net封装 OpenCVSharp

OpenCVSharp 是一个OpenCV的.Net wrapper,应用最新的OpenCV库开发,使用习惯比EmguCV更接近原始的OpenCV,有详细的使用样例供参考。

3D视觉库 fvision2010

基于OpenCV构建的图像处理和3D视觉库。 示例代码: ImageSequenceReaderFactory factory; ImageSequenceReader* reader = factory.pathRegex("c:/a/im_%03d.jpg", 0, 20); //ImageSequenceReader* reader = factory.avi("a.avi"); if (reader == NULL) { ...

基于QT的计算机视觉库 QVision

基于 QT 的面向对象的多平台计算机视觉库。可以方便的创建图形化应用程序,算法库主要从 OpenCV,GSL,CGAL,IPP,Octave 等高性能库借鉴而来。

图像特征提取 cvBlob

cvBlob 是计算机视觉应用中在二值图像里寻找连通域的库.能够执行连通域分析与特征提取.

实时图像/视频处理滤波开发包 GShow

GShow is a real-time image/video processing filter development kit. It successfully integrates DirectX11 with DirectShow framework. So it has the following features: GShow 是实时 图像/视频 处理滤波开发包,集成DiretX11。...

视频捕获 API VideoMan

VideoMan 提供一组视频捕获 API 。支持多种视频流同时输入(视频传输线、USB摄像头和视频文件等)。能利用 OpenGL 对输入进行处理,方便的与 OpenCV,CUDA 等集成开发计算机视觉系统。

开放模式识别项目 OpenPR

Pattern Recognition project(开放模式识别项目),致力于开发出一套包含图像处理、计算机视觉、自然语言处理、模式识别、机器学习和相关领域算法的函数库。

OpenCV的Python封装 pyopencv

OpenCV的Python封装,主要特性包括: 提供与OpenCV 2.x中最新的C++接口极为相似的Python接口,并且包括C++中不包括的C接口 提供对OpenCV 2.x中所有主要部件的绑定:CxCORE (almost complete), CxFLANN (complete), Cv (complete), CvAux (C++ part almost...

视觉快速开发平台 qcv

计算机视觉快速开发平台,提供测试框架,使开发者可以专注于算法研究。

图像捕获 libv4l2cam

对函数库v412的封装,从网络摄像头等硬件获得图像数据,支持YUYV裸数据输出和BGR24的OpenCV  IplImage输出

计算机视觉算法 OpenVIDIA

OpenVIDIA projects implement computer vision algorithms running on on graphics hardware such as single or multiple graphics processing units(GPUs) using OpenGL, Cg and CUDA-C. Some samples will soon support OpenCL and Direct Compute API'...

高斯模型点集配准算法 gmmreg

实现了基于混合高斯模型的点集配准算法,该算法描述在论文: A Robust Algorithm for Point Set Registration Using Mixture of Gaussians, Bing Jian and Baba C. Vemuri. ,实现了C++/Matlab/Python接口...

模式识别和视觉库 RAVL

Recognition And Vision Library (RAVL) 是一个通用 C++ 库,包含计算机视觉、模式识别等模块。

图像处理和计算机视觉常用算法库 LTI-Lib

LTI-Lib 是一个包含图像处理和计算机视觉常用算法和数据结构的面向对象库,提供 Windows 下的 VC 版本和 Linux 下的 gcc 版本,主要包含以下几方面内容: 1、线性代数 2、聚类分析 3、图像处理 4、可视化和绘图工具

OpenCV优化 opencv-dsp-acceleration

优化了OpenCV库在DSP上的速度。

C++计算机视觉库 Integrating Vision Toolkit

Integrating Vision Toolkit (IVT) 是一个强大而迅速的C++计算机视觉库,拥有易用的接口和面向对象的架构,并且含有自己的一套跨平台GUI组件,另外可以选择集成OpenCV

计算机视觉和机器人技术的工具包 EGT

The Epipolar Geometry Toolbox (EGT) is a toolbox designed for Matlab (by Mathworks Inc.). EGT provides a wide set of functions to approach computer vision and robotics problems with single and multiple views, and with different vision se...

OpenCV的扩展库 ImageNets

ImageNets 是对OpenCV 的扩展,提供对机器人视觉算法方面友好的支持,使用Nokia的QT编写界面。

libvideogfx

视频处理、计算机视觉和计算机图形学的快速开发库。

Matlab计算机视觉包 mVision

Matlab 的计算机视觉包,包含用于观察结果的 GUI 组件,貌似也停止开发了,拿来做学习用挺不错的。

Scilab的计算机视觉库 SIP

SIP 是 Scilab(一种免费的类Matlab编程环境)的图像处理和计算机视觉库。SIP 可以读写 JPEG/PNG/BMP 格式的图片。具备图像滤波、分割、边缘检测、形态学处理和形状分析等功能。

STAIR Vision Library

STAIR Vision Library (SVL) 最初是为支持斯坦福智能机器人设计的,提供对计算机视觉、机器学习和概率统计模


几种图像处理类库的比较

作者:王先荣

原文;http://www.cnblogs.com/xrwang/archive/2010/01/26/TheComparisonOfImageProcessingLibraries.html

前言

近期需要做一些图像处理方面的学习和研究,首要任务就是选择一套合适的图像处理类库。目前较知名且功能完善的图像处理类库有OpenCvEmguCvAForge.net等等。本文将从许可协议、下载、安装、文档资料、易用性、性能等方面对这些类库进行比较,然后给出选择建议,当然也包括我自己的选择。

 

许可协议

类库 许可协议 许可协议网址 大致介绍
OpenCv BSD www.opensource.org/licenses/bsd-license.html 在保留原来BSD协议声明的前提下,随便怎么用都行
EmguCv GPL v3 http://www.gnu.org/licenses/gpl-3.0.txt 你的产品必须也使用GPL协议,开源且免费
商业授权 http://www.emgu.com/wiki/files/CommercialLicense.txt 给钱之后可以用于闭源的商业产品
AForge.net LGPL v3 http://www.gnu.org/licenses/lgpl.html 如果不修改类库源代码,引用该类库的产品可以闭源和(或)收费

以上三种类库都可以用于开发商业产品,但是EmguCv需要付费;因为我只是用来学习和研究,所以这些许可协议对我无所谓。不过鉴于我们身在中国,如果脸皮厚点,去他丫的许可协议。

 

下载

可以很方便的下载到这些类库,下载地址分别为:

类库

下载地址

OpenCv

http://sourceforge.net/projects/opencvlibrary/files/

EmguCv

http://www.emgu.com/wiki/index.php/Download_And_Installation

AForge.net

http://www.aforgenet.com/framework/downloads.html

 

安装

这些类库的安装都比较简单,直接运行安装程序,并点“下一步”即可完成。但是OpenCv在安装完之后还需要一些额外的处理才能在VS2008里面使用,在http://www.opencv.org.cn有一篇名为《VC2008 Express下安装OpenCv 2.0》的文章专门介绍了如何安装OpenCv

类库

安装难易度

备注

OpenCv

比较容易

VC下使用需要重新编译

EmguCv

容易

 

AForge.net

容易

 

相信看这篇文章的人都不会被安装困扰。

 

文档资料 

类库

总体评价

书籍

网站

文档

示例

社区

备注

OpenCv

中等

中英文

中英文

中英文

较多

中文论坛

有中文资料但不完整

EmguCv

英文

英文

英文论坛

论坛人气很差

AForge.net

英文

英文

英文论坛

论坛人气很差

OpenCv有一些中文资料,另外两种的资料全是英文的;不过EmguCv建立在OpenCv的基础上,大部分OpenCv的资料可以用于EmguCv;而AForge.net是原生的.net类库,对GDI+有很多扩展,一些MSDN的资料可以借鉴。如果在查词典的基础上还看不懂英文文档,基本上可以放弃使用这些类库了。

 

易用性

易用性这玩意,主观意志和个人能力对它影响很大,下面是我的看法:

类库

易用性

备注

OpenCv

比较差

OpenCv大多数功能都以C风格函数形式提供,少部分功能以C++类提供。注意:2.0版将更多的功能封装成类了。

EmguCv

比较好

OpenCv的绝大部分功能都包装成了.net类、结构或者枚举。不过文档不全,还是得对照OpenCv的文档去看才行。

AForge.net

.net类库,用起来很方便。

最近几年一直用的是C# ,把CC++忘记得差不多了,况且本来C/C++我就不太熟,所以对OpenCv的看法恐怕有偏见。


视觉相关网站


这段时间因为项目的需要,我一直在折腾计算机视觉,尤其是双目立体视觉,代码、论文、工具箱等……占用了我几乎90%的工作时间,还在一点点地摸索,但进度实在不敢恭维,稍后我会把情况作个总结。

 

今天的主要任务就是和大家分享一些鄙人收藏的认为相当研究价值的网页:

 

Oxford大牛:Andrew Zisserman,http://www.robots.ox.ac.uk/~vgg/hzbook/code/,此人主要研究多幅图像的几何学,该网站提供了部分工具,相当实用,还有例子

 

西澳大利亚大学的Peter Kovesi:http://www.csse.uwa.edu.au/~pk/research/matlabfns/,提供了一些基本的matlab工具,主要内容涉及Computer Vision, Image Processing

 

CMU:http://www.cs.cmu.edu/afs/cs/project/cil/ftp/html/vision.html,该网站是我的最爱,尤其后面这个地址http://www.cs.cmu.edu/afs/cs/project/cil/ftp/html/v-groups.html,在这里提供了世界各地机构、大学在Computer Vision所涉及各领域的研究情况,包括Image Processing, Machine Vision,我后来也是通过它连接到了很多国外的网站

 

Cambridge:http://mi.eng.cam.ac.uk/milab.html,这是剑桥大学的机器智能实验室,里面有三个小组,Computer Vision & Robotics, Machine Intelligence, Speech,目前为止,Computer Vision & Robotics的一些研究成果对我日后的帮助可能会比较大,所以在此提及

 

大量计算机视觉方面的原版电子书:http://homepages.inf.ed.ac.uk/rbf/CVonline/books.htm,我今天先下了本Zisserman的书,呵呵,国外的原版书,虽然都是比较老的,但是对于基础的理解学习还是很有帮助的,至于目前的研究现状只能通过论文或者一些研究小组的网站

 

stanford:http://ai.stanford.edu/~asaxena/reconstruction3d/,这个网站是Andrew N.G老师和一个印度阿三的博士一起维护的,主要对于单张照片的三维重建,尤其他有个网页make3d.stanford.edu可以让你自己上传你的照片,通过网站来重建三维模型,这个网站对于刚开始接触Computer Vision的我来说,如获至宝,但有个致命问题就是make3d已经无法注册,我也多次给Andrew和印度阿三email,至今未回,郁闷,要是有这个网站的帐号,那还是相当爽的,不知道是不是由于他们的邮箱把我的email当成垃圾邮件过滤,哎,但这个stanford网站的贡献主要是代码,有很多computer vision的基础工具,貌似40M左右,全都是基于matlab的

 

caltech:http://www.vision.caltech.edu/bouguetj/calib_doc/,这是我们Computer Vision老师课件上的连接,主要是用于摄像机标定的工具集,当然也有涉及对标定图像三维重建的前期处理过程

 

JP Tarel:http://perso.lcpc.fr/tarel.jean-philippe/,这是他的个人主页,也是目前为止我发的email中,唯一一个给我回信的老外,因为我需要重建练习的正是他的图片集,我读过他的论文,但没有涉及代码的内容,再加上又是94年以前的论文,很多相关的引文,我都无法下载,在我的再三追问下,Tarel教授只告诉我,你可以按照我的那篇论文对足球进行重建,可是...你知道吗,你有很多图像处理的引文都下不了了,我只知道你通过那篇文章做了图像的预处理,根本不知道具体过程,当然我有幸找到过一篇90左右的论文,讲的是region-based segmentation,可是这文章里所有引文又是找不到的....悲剧的人生

 

开源软件网站:www.sourceforge.net

 

最后就是我们工大的Computer Vision大牛:sychen.com,我们Computer Vision课的老师,谦虚、低调,很有学者风范

 

总结:目前为止,我的个人感觉就是国外学者的论文包括刊登的资料大部分都是对原理进行的说明,并不是很在意具体的代码实现的讲解,而我却过分的关注于代码的实现,忽视Computer Vision的原理,国外学者对与自己相关领域的研究现状了解相当充分,对自己的工作进度更新也很勤快,很多好的网站我并没有完全列出来,在这里只是提了主要的几个,在这方面,我们国内的研究氛围有所不及,当然我选择的一些网站可能更多的是个人小组的研究介绍,不像一些专门从事领域研究的机构,会有那么多的权威资料,国外的网站有个很好的地方,就是有很多的免费资源,免费的matlab或者openCV工具集,免费的论文下载,课件下载等等,在这方面国内对于研究资源的共享,做得又有所差距,同样,国外的研究工具很多样,主要是matlab,一些发布的demo都使用C++写的,不过今天看到一个西班牙的研究机构(university of las palmas)用了个XMW的软件平台来实现图片的三维重建,data用的是人脸,而且国外的很多源代码基本上是在linux平台下完成的,对于我来说又是不方便,哎,可能要考虑装VM Ware了,不然双系统太累.....

 

目前,Computer Vision是全世界范围内自动化、计算机、数学领域的研究热点,综合性高,应用于医疗、军事、民用等等领域,其中有突出成绩的还是一下几所学校(个人见解):Cambridge(UK), Oxford(UK), CMU(US),Stanford(US),MIT(US),U.C.Berkeley(US),而UK的两所老牌高校,他们的实际应用领域丝毫不逊于stanford和CMU....

 

世界就是这样,当你不断的接触,不断的扩展你所能够及的边际就会发现自己越来越无知,还有很多很多不知道,发现还有很多自己都想不到但却已经实现的东西.....

 

革命远未成功,同志仍须努力,在CV的道路上前进.......

 

该文转自http://www.cnblogs.com/yangwei86/archive/2009/07/10/1520215.html

2017-01-12 22:03:00 yzhang6_10 阅读数 775

Python计算机视觉工具安装

由于刚刚接触Python没多久,对于python软件安装较生疏,但近想学习利用Python处理计算视觉,故着手安装各种包,遇到一些,经过查询相关资料,最终解决了,故总结了此篇博客。

  • PIL安装使用

    PIL(图像处理类库)提供了通用的图像处理功能,以及大量有用的基本图像操作,比如图像缩放、裁剪。、颜色转换等。它是免费的。下面是安装和使用PIL库的一些总结。

    1)安装PIL库,首先下载PIL-1.1.7.win32-py2.7.exe,然后点击安装即可。

    2)使用过程中,show()函数不能正常显示图片,修改方法如下:
    将 D:\setup\Python2.7.11\Lib\site-packages\PIL\ImageShow.py中的第99行代码(return “start /wait %s && del /f %s” % (file, file))修改为return “start /wait %s && PING 127.0.0.1 -n 5 > NUL && del /f %s” % (file, file) 即可。
    注意:一定要确定路径,该路径下不仅包括ImageShow.py还包括对应的ImageShow.pyc和ImageShow.pyo。

  • Numpy安装使用

    Numpy是非常有名的Python科学计算工具包,其中包含了大量有用的思想,如数组对象(用来表示向量、矩阵、图像等)以及线性代数函数。它可以帮助完成矩阵中重要的操作,如矩阵乘积、转置、解方程系统、向量乘积和归一化等,它为图像变形、图像分类、图像聚类等提供了基础。其安装过程如下:
    1)下载,可以下载.whl或.exe格式,然后对应进行安装即可。
    2)下载完成后,其使用需要依赖其他一些工具或包。安装提示的错误等,对应安装即可。

  • scipy安装使用

    Scipy是建立在Numpy基础上,用于数值运算的开源工具包。Scipy提供很多高效的操作,可以实现数值积分、优化、统计、信号处理,以及重要的一些图像处理等。其下载安装如下:
    1)下载,官网为http://scipy.org/install.html
    2)然后执行安装即可。也可下在网上找那种可以直接下载.exe的文件进行安装。

  • Matplotlib安装使用

    Matplotlib主要是Python中绘制高质量图表的工具。其下载安装如下:
    1)下载对应软件,然后执行安装即可。
    2)Matplotib的使用,需要dateutil和pyparsing,对应进行安装即可。

    pyLab绘图基本颜色、线性、标记命令如下:

    b:蓝色,g:绿色,r:红色,c:青色,m:品红,y:黄色,k:黑色,w:白色。
    -:实线,–:虚线,::点线
    .:点,o:圆圈,s:正方形,*:星形,+:加号,×:叉号

  • Python2与Python3处理

    由于在Windows 7下既安装了Python2和Python3相应版本,故在安装软件,一直出现安装不明确问题,为解决这一问题,使得将应的工具安装到自己想要安装的版本Python上,可以使用如下命令:
    py -2 -m pip install … (安装到Python2下)
    py -3 -m pip install … (安装到Python3下)

  • 参考文献: Python计算机视觉编程

2019-05-14 10:47:40 Zhang_Chen_ 阅读数 189

PIL:python图像处理类库

pip install Pillow
//用pip安装
from PIL import Image


pil_im = Image.open("test.png")
//读入一个名为test.png的图片
type(pil_im)
//显示pil_im的数据类型,<class 'PIL.PngImagePlugin.PngImageFile'>
pil_im.show()
//生成一个窗口显示test.png图片
pil_im = Image.open("test.png").convert("L")
//将test.png转化为灰度图
pil_im = Image.open("test.png").convert("1")
//将test.png转化为二值图
pil_im.save("test.jpg")
//保存图像
//pil_im是open读入的图片,将被保存为test.jpg
//这里可以保存为不同格式的图片,.jpg或.png都可以
//是新生成一张图片并保存,并不会覆盖原文件

创建缩略图

img = pil_im.thumbnail((128, 128))
//创建pil_im的缩略图
pil_im.show()
//显示生成的缩略图
img.show()
//报错,因为.thumbnail改变的是原图,返回给img的值为None

thumbnail和resize的区别

  1. 正如上面的代码,thumbnail改变的原图,返回值为None;而resize原图不变,返回的是改变大小后的图
  2. thumbnail只能缩小图片
  3. thumbnail缩小图片是按原图的长宽比例;而resize改变图片尺寸是严格按照赋值的

复制和粘贴图像区域

box = (100, 100, 400, 400)
//四元组表示剪裁区域
//1,2,3,4元素分别对应,剪裁区域左边框到原图左边框的距离;剪裁区域上边框到原图上边框的距离;剪裁区域右边框到原图左边框的距离;剪裁区域下边框到原图上边框的距离
region = pil_im.crop(box)
//按box取值切割原图pil_im,剪裁下来的图返回给region
region = region.transpose(Image.ROTATE_180)
//region旋转180度
pil_im.paste(region, box)
//将旋转后的region粘贴会原处,这一操作会改变原图

调整尺寸和旋转

out = pil_im.resize((128, 128))
//正如上面说的,resize原图不变,返回给out大小调整后的图片
out = pil_im.rotate(45)
//旋转操作,参数是旋转角度

Matplotlib

pip install matplotlib
//pip安装
from PIL import Image
import matplotlib.pylab as plt


im = plt.array(Image.open("test.png"))
//读取图片,并转为“numpy.ndarray”格式
//因为下面的画点操作,所以要转成“numpy.ndarray”格式
plt.imshow(im)
//plt.imshow()指定了接下来的操作是对im执行,并显示其格式,不显示图像

x = [100, 100, 400, 400]
y = [200, 500, 200, 500]

plt.plot(x, y, "r*")
plt.plot(x[:2], y[:2])
//连接前两个点,即(100,200)和(100,500)

plt.title('Plotting:"test.png"')
//加标题

plt.axis("off")
//plt.axis是对坐标轴进行操作,"off"是去掉坐标轴

plt.show()
//显示处理后的图像
//plt.show()过后,再想处理哪一张图片,需要用plt.imshow()重新指定
plt.axis()的参数 含义
‘on’ 打开坐标轴
‘off’ 关闭坐标轴
‘equal’ 通过改变轴取值的范围,使横轴和纵轴跨度相等。不改变图片尺寸,多出来的部分是空白
‘scaled’
‘tight’
‘auto’
’ normal’
‘image’
‘square’

图像轮廓和直方图

from PIL import Image
import matplotlib.pylab as plt


im = plt.array(Image.open("test.png").convert("L"))

plt.figure()
//新建一个图像,并指定下面的操作是在这个图像上
plt.gray()
//设置这个图像为单通道图像,即灰度图

plt.contour(im, origin="image")
//画轮廓

plt.axis("equal")
plt.axis("off")

plt.figure()
//再创建一个新图像,接下来的操作是在这个图像上

plt.hist(im.flatten(), 128)
//绘制直方图
//im.flatten()将转化为“numpy.ndarray”格式的原图像按行有限准则变成一维数组
//128指定了有128个直方条形图,每个条的高度,是一维数组中,落入这个条的像素值的和

plt.show()
//显示两张图像

交互式标注

from PIL import Image
import matplotlib.pylab as plt


im = plt.array(Image.open("test.png"))
plt.imshow(im)

x = plt.ginput(3)
//显示原图像,等待点击三次,将位置信息返回给列表x

结语

如果您有修改意见或问题,欢迎留言或者通过邮箱和我联系。
手打很辛苦,如果我的文章对您有帮助,转载请注明出处。

2019-08-24 23:32:22 qq_35069382 阅读数 19

记录PIL库的使用方法,因为书上用的是python2.6,而我的是python3.7,所以代码格式有所不同。首先展示PIL的基本操作,分别是打开图像、灰度处理、截取某一区域倒置、略缩图的操作以下附上代码。

from PIL import Image
import matplotlib.pyplot as plt


pil_im = Image.open('timg.jpg')    # 打开图像
pil_im01 = Image.open('timg.jpg').convert('L')    # 灰度处理
plt.imshow(pil_im01)
plt.show()
plt.imshow(pil_im)
plt.show()

box = (100, 100, 400, 400)    # 四元组的坐标依次是(左,上,右,下)
region = pil_im.crop(box)     # crop()方法可以从一幅图像中裁剪指定区域
region = region.transpose(Image.ROTATE_180)   # 将选中区域旋转180°
pil_im.paste(region, box)     # 使用paste()方法将该区域放回去
plt.imshow(pil_im)
plt.show()

pil_im.thumbnail((128, 128))  # 创建略缩图
plt.imshow(pil_im)
plt.show()

结果如下所示:

原图
灰度图

 

截取部分倒置后的图
略缩图

然后我们在图像中绘制添加点和线,

这里的pylab库值得注意一下,如果写 from pylab import * 那么不用定义plt也可以直接写plt.plot(),还有,在读取图像到数组时,如果写 from pylab import *,那么所有格式应该去掉pylab,比如是array()而不是pylab.array(),因为 PyLab 实际上包含 NumPy 的一些内容,如数组类型。下面的代码我直接使用的pylab:

from PIL import Image
import pylab
# 读取图像到数组中
# 如果写 from pylab import *,那么格式应该是array()而不是pylab.array()
img = pylab.array(Image.open('timg.jpg'))
# 绘制图像
pylab.imshow(img)
# 四个点
x = [100, 100, 400, 400]
y = [200, 500, 200, 500]
# 使用红色形状标记绘制点
pylab.plot(x, y, 'r*')
# 绘制链接前两个点的线
pylab.plot(x[:2], y[:2])
# 添加标题,显示绘制的图像
pylab.title('Plotting')
pylab.show()

结果如下:

图像轮廓和直方图

因为绘制轮廓需要对每个坐标 [x, y] 的 像素值施加同一个阈值,所以首先需要将图像灰度化,还需要注意的是在画直方图时,hist()方法只能接收一维数组作为输入所以需要用flatten()方法将任意数组按照行优先准则转换成一维数组。

from PIL import Image
from pylab import *
# 读取图像到数组中
img = array(Image.open('timg.jpg').convert('L'))
# 新建一个图像
figure()
# 不使用颜色信息
gray()
# 在原点的左上角显示轮廓图像
contour(img, origion='image')
axis('equal')     # 尺寸与原图相同
axis('off')       # 去掉坐标系
imshow(img)
show()

figure()
hist(img.flatten(),128)     # flatten()方法将任意数组按照行优先准则转换成一维数组,hist()方法只能接收一维数组作为输入
show()

结果如下:

 

 

 

 

2018-05-22 21:34:53 u013631121 阅读数 718

上一讲小木我讲解了图片的读取,保存。视频的读取、保存、以及如何调用摄像头。这节课我们要将这些东西给合而为一。怎么合而为一呢,美国的天才,也就是《OPENCV3 计算机视觉 PYTHON语言实现》这本书的作者,他做了一个程序叫做Cameo。这个程序集合了所有的方法。那么这个程序包括两个文件,分别是cameo.pymanager.py,接下来我展示一下:

# cameo.py

# cameo.py
import cv2

from1 managers import WindowManager, CaptureManager

 

class Cameo(object):

    

    def __init__(self):

        self._windowManager = WindowManager('Cameo',

                                            self.onKeypress)

        self._captureManager = CaptureManager(

            cv2.VideoCapture(0), self._windowManager, True)

    

    def run(self):

        """Run the main loop."""

        self._windowManager.createWindow()

        while self._windowManager.isWindowCreated:

            self._captureManager.enterFrame()

            frame = self._captureManager.frame

            

            if frame is not None:

                # TODO: Filter the frame (Chapter 3).

                pass

            

            self._captureManager.exitFrame()

            self._windowManager.processEvents()

    

    def onKeypress(self, keycode):

        """Handle a keypress.

        

        space  -> Take a screenshot.

        tab    -> Start/stop recording a screencast.

        escape -> Quit.

        

        """

        if keycode == 32: # space

            self._captureManager.writeImage('screenshot.png')

        elif keycode == 9: # tab

            if not self._captureManager.isWritingVideo:

                self._captureManager.startWritingVideo(

                    'screencast.avi')

            else:

                self._captureManager.stopWritingVideo()

        elif keycode == 27: # escape

            self._windowManager.destroyWindow()

 

if __name__=="__main__":

    Cameo().run()

#---------------------------------------

#manager.py

import cv2

import numpy

import time

 

 

class CaptureManager(object):

    

    def __init__(self, capture, previewWindowManager = None,

                 shouldMirrorPreview = False):

        

        self.previewWindowManager = previewWindowManager

        self.shouldMirrorPreview = shouldMirrorPreview

        

        self._capture = capture

        self._channel = 0

        self._enteredFrame = False

        self._frame = None

        self._imageFilename = None

        self._videoFilename = None

        self._videoEncoding = None

        self._videoWriter = None

        

        self._startTime = None

        self._framesElapsed = int(0)

        self._fpsEstimate = None

    

    @property

    def channel(self):

        return self._channel

    

    @channel.setter

    def channel(self, value):

        if self._channel != value:

            self._channel = value

            self._frame = None

    

    @property

    def frame(self):

        if self._enteredFrame and self._frame is None:

            # As of OpenCV 3.0, VideoCapture.retrieve() no longer supports

            # the channel argument.

            # _, self._frame = self._capture.retrieve(channel = self.channel)

            _, self._frame = self._capture.retrieve()

        return self._frame

    

    @property

    def isWritingImage(self):

        return self._imageFilename is not None

    

    @property

    def isWritingVideo(self):

        return self._videoFilename is not None

    

    def enterFrame(self):

        """Capture the next frame, if any."""

        

        # But first, check that any previous frame was exited.

        assert not self._enteredFrame, \

            'previous enterFrame() had no matching exitFrame()'

        

        if self._capture is not None:

            self._enteredFrame = self._capture.grab()

    

    def exitFrame(self):

        """Draw to the window. Write to files. Release the frame."""

        

        # Check whether any grabbed frame is retrievable.

        # The getter may retrieve and cache the frame.

        if self.frame is None:

            self._enteredFrame = False

            return

        

        # Update the FPS estimate and related variables.

        if self._framesElapsed == 0:

            self._startTime = time.time()

        else:

            timeElapsed = time.time() - self._startTime

            self._fpsEstimate =  self._framesElapsed / timeElapsed

        self._framesElapsed += 1

        

        # Draw to the window, if any.

        if self.previewWindowManager is not None:

            if self.shouldMirrorPreview:

                mirroredFrame = numpy.fliplr(self._frame).copy()

                self.previewWindowManager.show(mirroredFrame)

            else:

                self.previewWindowManager.show(self._frame)

        

        # Write to the image file, if any.

        if self.isWritingImage:

            cv2.imwrite(self._imageFilename, self._frame)

            self._imageFilename = None

        

        # Write to the video file, if any.

        self._writeVideoFrame()

        

        # Release the frame.

        self._frame = None

        self._enteredFrame = False

    

    def writeImage(self, filename):

        """Write the next exited frame to an image file."""

        self._imageFilename = filename

    

    def startWritingVideo(

            self, filename,

            encoding = cv2.VideoWriter_fourcc('M','J','P','G')):

        """Start writing exited frames to a video file."""

        self._videoFilename = filename

        self._videoEncoding = encoding

    

    def stopWritingVideo(self):

        """Stop writing exited frames to a video file."""

        self._videoFilename = None

        self._videoEncoding = None

        self._videoWriter = None

    

    def _writeVideoFrame(self):

        

        if not self.isWritingVideo:

            return

        

        if self._videoWriter is None:

            fps = self._capture.get(cv2.CAP_PROP_FPS)

            if fps <= 0.0:

                # The capture's FPS is unknown so use an estimate.

                if self._framesElapsed < 20:

                    # Wait until more frames elapse so that the

                    # estimate is more stable.

                    return

                else:

                    fps = self._fpsEstimate

            size = (int(self._capture.get(

                        cv2.CAP_PROP_FRAME_WIDTH)),

                    int(self._capture.get(

                        cv2.CAP_PROP_FRAME_HEIGHT)))

            self._videoWriter = cv2.VideoWriter(

                self._videoFilename, self._videoEncoding,

                fps, size)

        

        self._videoWriter.write(self._frame)

 

 

class WindowManager(object):

    

    def __init__(self, windowName, keypressCallback = None):

        self.keypressCallback = keypressCallback

        

        self._windowName = windowName

        self._isWindowCreated = False

    

    @property

    def isWindowCreated(self):

        return self._isWindowCreated

    

    def createWindow(self):

        cv2.namedWindow(self._windowName)

        self._isWindowCreated = True

    

    def show(self, frame):

        cv2.imshow(self._windowName, frame)

    

    def destroyWindow(self):

        cv2.destroyWindow(self._windowName)

        self._isWindowCreated = False

    

    def processEvents(self):

        keycode = cv2.waitKey(1)

        if self.keypressCallback is not None and keycode != -1:

            # Discard any non-ASCII info encoded by GTK.

            keycode &= 0xFF

            self.keypressCallback(keycode)

#---------------------------------------

我们这样乍眼一看,太特么的长了吧,看不懂呀。其实你们不是看不懂,而是太长了看着头痛罢了。如果大家对这个程序没兴趣的话,直接复制粘贴用就行了,根本没什么必要读懂。那么怎么用呢,我们把这两者py文件放到一块,然后执行cameo.py即可,执行后,打开笔记本的摄像头,并且在屏幕上显示。如果我们想退出,按ESC键、我们想抓取一帧摄像头的截图,那么我们按空格键即可,它会图片保存在同PY文件的目录下,名字叫screenshot.png。如果我们想录像,我们按一下TAB就会开始录像,再按一下TAB就会结束录像,并且把录像保存在同PY文件的目录下,名字叫screencast.avi

我给大家展示一下效果:

 

很棒吧,截图就按空格,录像就按TAB即可。

 

然而,我们既然有程序,而且是开源的,我们为啥不看?直接用倒是可以,但是了解一下程序木有坏处吧?恩恩,下面小木我就来讲解一下这个程序吧!

首先我们来到cameo.py这个文件中,我们看45-47行(若大家行数找不到或者对不上,直接复制代码到notepad,然后搜索一下相关字就行),也就是最后两行:

if __name__=="__main__":

    Cameo().run()

我们按一下运行,就会执行这条语句,执行之后,我们首先初始化Cameo这个类,然后执行run方法。

我们初始化这个方法是执行6-10行:

    def __init__(self):

        self._windowManager = WindowManager('Cameo',

                                            self.onKeypress)

        self._captureManager = CaptureManager(

            cv2.VideoCapture(0), self._windowManager, True)

我们初始化时候,第一步,创建一个WindowManager的实例,这个窗口名字叫Cameo,接受键盘按键(也就是录像或截图)的监控的函数叫做onKeypress,这个函数后面讲解。

第二步,我们创建一个CaptureManager的实例,这个实例中,第一个参数是获取摄像头设备,如果只有一个摄像头括号里面就为0,如果多个,就输入第几个摄像头的标号数字即可。第二个参数是把上面的WindowsManager实例_windowManager传给CaptureManager的实例_captureManager第三个参数是是否镜像,如果True就是镜像,因为我们照镜子,镜子里面的人是相反的,所以我们应该水平翻转一下,给它变正。

初始化完成之后,我们就要执行Run语句了,也就是cameo.py中的12-24行:

def run(self):

        """Run the main loop."""

        self._windowManager.createWindow()

        while self._windowManager.isWindowCreated:

            self._captureManager.enterFrame()

            frame = self._captureManager.frame

            

            if frame is not None:

                # TODO: Filter the frame (Chapter 3).

                pass

            

            self._captureManager.exitFrame()

        self._windowManager.processEvents()

下面我把run函数中的语句用()表示,便于区分是这个函数的内容还是其它函数的内容

(1)我们首先用WindowsManager的实例_windowManager创建一个窗口,用来在屏幕上面显示我们的摄像头内容。我们先判断一下是否窗口创建完毕。

createWindow()函数如下,也就是manager.py中的156-158行:

    def createWindow(self):

        cv2.namedWindow(self._windowName)

        self._isWindowCreated = True

我们把_windowName中传入的名称,也就是cameo写入,然后把_isWindowCreated属性改为True。

(2)如果创建完毕的话进入循环,如果没建立好窗口的话,直接就退出程序运行。我们按照创建完毕继续来说。创建完毕后我们进入循环,并且执行CaptureManager的实例_captureManager的enterFrame函数。

也就是manager.py中的54-62行:

  def enterFrame(self):

        """Capture the next frame, if any."""

        

        # But first, check that any previous frame was exited.

        assert not self._enteredFrame, \

            'previous enterFrame() had no matching exitFrame()'

        

        if self._capture is not None:

            self._enteredFrame = self._capture.grab()

这些语句的意思是如果_capture不为空的话,抓取摄像头中的一帧。_capture指的是我们当初CaptureManager类实例_captureManager打开的摄像头capture。

3)抓取之后我们执行循环中的frame = self._captureManager.frame把上面捕获的帧的图像传入到变量frame中。

4)执行CaptureManager中的exitFrame()函数,这个函数的用途是计算摄像头每秒钟的帧数,并且把摄像头捕获的帧放入窗口cameo中显示。

exitFrame()这个函数在manager.py的64-99行:

  def exitFrame(self):

        """Draw to the window. Write to files. Release the frame."""

        

        # Check whether any grabbed frame is retrievable.

        # The getter may retrieve and cache the frame.

        if self.frame is None:

            self._enteredFrame = False

            return

这个函数首先先判断一下,是否刚才在enterFrame中真的抓取到一帧了,如果抓取到继续,没抓取到,退出函数,执行循环中的下一句 self._windowManager.processEvents()。我们按照抓取到的算,那么就继续往下执行exitFrame。但是有一点要说的是判断语句中frame是一个函数:

  def frame(self):

        if self._enteredFrame and self._frame is None:

            # As of OpenCV 3.0, VideoCapture.retrieve() no longer supports

            # the channel argument.

            # _, self._frame = self._capture.retrieve(channel = self.channel)

            _, self._frame = self._capture.retrieve()

        return self._frame

在这个函数中,我们首先判断一下是否抓取图片成功,如果成功的话,把成功的图片的数据导入到_frame这个变量中,使用的方法是retrieve()。

我们把_frame添加东西后,它就不为none了,那么就继续往下执行exitFrame:

  # Update the FPS estimate and related variables.

        if self._framesElapsed == 0:

            self._startTime = time.time()

        else:

            timeElapsed = time.time() - self._startTime

            self._fpsEstimate =  self._framesElapsed / timeElapsed

        self._framesElapsed += 1

到这里了,我们做的是计算每秒钟的帧数,我们第一次的话,framesElapsed为0,那么我们就记录一下这个时候的时间。当我们第二次执行这一部分的时候,也就是抓取完成第二帧后,我们用这两帧的时间相减,然后除以一个2,第三次执行这部分时候,我们用第三次时间与第一次相减,然后除以一个3,以此类推,我们就估算出了FPS(每秒帧数),而且这个估算是实时更新的。这个时间我们记录到_fpsEstimate里面。我们假设我们是第一次执行这个语句,执行完毕后,我们进入下面:

   # Draw to the window, if any.

        if self.previewWindowManager is not None:

            if self.shouldMirrorPreview:

                mirroredFrame = numpy.fliplr(self._frame).copy()

                self.previewWindowManager.show(mirroredFrame)

            else:

                self.previewWindowManager.show(self._frame)

这一部分是把我们捕获的帧的图像显示到屏幕窗口上面,如果我们当初选择镜像一下的话,那么我们首先翻转一下图片,然后再显示到窗口上。我们每一次循环都更新一下窗口,这样我们就相当于一帧帧地放图片,速度会很快,快的话就达到了视频的效果。我们继续往下执行:     

 # Write to the image file, if any.

        if self.isWritingImage:

            cv2.imwrite(self._imageFilename, self._frame)

            self._imageFilename = None

这部分是判断是否按下了空格键,如果按下了,就把我们按下时候刚好_enterFrame捕获的那一帧数据保存到硬盘中。如果没有截图,就跳过。

        # Write to the video file, if any.

        self._writeVideoFrame()

这部分是判断是否按下了TAB,如果按下了,就把我们按下时候刚好_enterFrame捕获的那一帧数据保存到硬盘中,然后每一次循环的时候都把_enterFrame保存起来,直到我们又按了一下TAB键,我们就不再保存了。这样好多帧的图片会放到一个为avi格式的文件当中,说白了就是一个视频。

        # Release the frame.

        self._frame = None

        self._enteredFrame = False

最后我们把当前帧的图像给全部变为空,结束这个语句。

5)回到主函数的循环,执行self._windowManager.processEvents()。这个函数如下:

    def processEvents(self):

        keycode = cv2.waitKey(1)

        if self.keypressCallback is not None and keycode != -1:

            # Discard any non-ASCII info encoded by GTK.

            keycode &= 0xFF

            self.keypressCallback(keycode)

它的作用是监控键盘,看看它按下我们之前说的那些按键没有,如果按下的话,就执行相应的操作。

6)当我们执行完毕之后,我们返回循环的头部,然后继续执行循环,直到我们按下ESC键为止。

到此为止,我们的cameo类库就讲完了。我们还要额外补充几点:

1)如何监控键盘的:

监控键盘在循环语句的最后一句,当我们执行这句话的时候,我们要是键盘按下键或者没有按下键,都会产生一个数据,没按下是-1,按下了就是一个ASCII码,我们然后把这个码转换为GTK格式,然后传入keypressCallback中,也就是我们传入Windowsmanager类中的函数:

 

   def onKeypress(self, keycode):

        """Handle a keypress.

        

        space  -> Take a screenshot.

        tab    -> Start/stop recording a screencast.

        escape -> Quit.

        

        """

        if keycode == 32: # space

            self._captureManager.writeImage('screenshot.png')

        elif keycode == 9: # tab

            if not self._captureManager.isWritingVideo:

                self._captureManager.startWritingVideo(

                    'screencast.avi')

            else:

                self._captureManager.stopWritingVideo()

        elif keycode == 27: # escape

            self._windowManager.destroyWindow()

我们在这里判断一下是否键入了ESC、TAB、空格其中之一,然后执行相应的方法。

(3)这个函数中还有什么其它的方法:

    def show(self, frame):

        cv2.imshow(self._windowName, frame)

我们刚才讲的全是摄像头摄像,但是这里面类似上面的方法,也可以用于打开图片,可以打开视频,但是没啥用,因为我们直接用OPENCV自带的类实现要比它方便。

好了,这样我们的cameo的类库就讲完了,其实我们这里面忽略的很多方法没有讲,我想我根本没有必要讲解了吧,自己看看应该可以看懂,要是真心看不懂,欢迎大家发评论提问我,我会为大家一一解答。

我们OPENCV的基础部分全部都讲完了,之后我们要学习一些过滤的方法,比如腐蚀膨胀啥的,大家可以继续跟进我的讲座!

————————————————

如果对我的课程感兴趣的话,欢迎关注小木希望学园-微信公众号: 

mutianwei521

也可以扫描二维码哦!


没有更多推荐了,返回首页