第二章

使用numpy.array访问图像数据

改变一个特定像素的值:

  • numpy.array提供的item()

    • item(x,y,id)
    • id为索引,B G R
  • itemset()
    • itemset((x,y,id),val)
    • (x,y,索引,要设定的值)

操作通道:将指定通道所有值置0

import cv2
import numpy as np
img = cv2.imread('1.png')
img[:,:,1] = 0

视频文件的读/写

  • OpenCV提供了VideoCapture类和VideoWriter类支持各种格式的视频文件(都支持AVI格式),到达视频文件末尾前,可通过read()获取新的帧,每一帧是一幅基于BGR格式的图像
import cv2
videoCapture = cv2.VideoCapture('2_1.avi')
fps = videoCapture.get(cv2.CAP_PROP_FPS)#帧速率
size = (int(videoCapture.get(cv2.CAP_PROP_FRAME_WIDTH)),int(videoCapture.get(cv2.CAP_PROP_FRAME_HEIGHT)))
videoWriter = cv2.VideoWriter('2_1_copy.avi',cv2.VideoWriter_fourcc('I','4','2','0'),fps,size)sucess , frame = videoCapture.read()
while sucess:videoWriter.write(frame)sucess , frame = videoCapture.read()

其中编解码器的可用性常用选项:

  • cv2.VideoWriter_fource('I','4','2','0'):该选项是一个未压缩的YUV颜色编码,4:2:0色度子采样。这种编码有很好地兼容性,但会产生较大文件,文件扩展名.avi (例子视频145K,产生了12.4M文件)
  • cv2.VideoWriter_fource(‘P’,‘I’,‘M’,‘1’): 生成.avi
  • cv2.VideoWriter_fource(‘X’,‘V’,‘I’,‘D’):MPEG-4编码类型,生成.avi(若希望视频大小为平均值,推荐使用)
  • cv2.VideoWriter_fource(‘F’,‘L’,‘V’,‘1’):该选项是一个Flash视频,扩展名.flv

捕获摄像头的帧

import cv2cameraCapture = cv2.VideoCapture(0)
#为了针对摄像头创建合适的VideoWriter类,
#要么对帧速率作出假设,
#要么使用计时器测量
fps = 30
size = (int(cameraCapture.get(cv2.CAP_PROP_FRAME_WIDTH)),int(cameraCapture.get(cv2.CAP_PROP_FRAME_HEIGHT)))videoWriter = cv2.VideoWriter('2_1_catch_camera.avi',cv2.VideoWriter_fourcc('I','4','2','0'),fps,size)success , frame = cameraCapture.read()
numFramesRemaining = 10 * fps - 1while success and numFramesRemaining > 0 :videoWriter.write(frame)
#需要同步一组摄像头,read()方法不适用,可用grab(),retrive()替代success , frame = cameraCapture.read()numFramesRemaining -= 1cameraCapture.release()

imshow在窗口显示图像

import cv2
import  numpy as np
img = cv2.imread('2_1.jpg')
cv2.imshow('2_1.jpg',img)
cv2.waitKey()#保证显示视频时窗口上帧可以一直更新
cv2.destroyAllWindows()

在窗口显示摄像头帧

  • 任意窗口下都可以通过waitKey()获取键盘输入;
  • 通过setMouseCallback()获取鼠标输入。
#实时显示摄像头帧#OpenCV不提供任何处理窗口事件的方法,单击窗口关闭时,并不能关闭应用程序
import cv2
clicked = False
#鼠标响应函数
"""
flags: 代表鼠标的拖拽事件,以及键盘鼠标联合事件
param:函数指针 标识了所响应的事件函数,相当于自定义了一个OnMouseAction()函数的ID。
"""
def onMouse( event , x , y , flags , param ):global clickedif event == cv2.EVENT_LBUTTONUP:clicked = TruecameraCapture = cv2.VideoCapture(0)
cv2.namedWindow('MyWindow')#鼠标回调函数,param为可选参数
"""
C++中原型:
void setMouseCallback(const string& winname,     //图像视窗名称
MouseCallback onMouse,     //鼠标响应函数,监视到鼠标操作后调用并处理相应动作
void* userdata = 0        //鼠标响应处理函数的ID,识别号,默认0
);
"""
cv2.setMouseCallback('MyWindow',onMouse)print('Showing camera feed. Click window or press any key to stop.')sucess , frame = cameraCapture.read()#waitKey()参数为等待键盘触发的时间,单位ms,返回值-1(表示没有被按下)
#某些系统waitKey()返回值可能比ASCII更大,可通过读取返回值最后一个字节
#保证只提取ASCII码:
# keycode = cv2.waitKey(1)
# if keycode != -1 :
#     keycode &= 0xFFwhile sucess and cv2.waitKey(1) == -1 and not clicked:cv2.imshow('MyWindow',frame)sucess , frame = cameraCapture.read()cv2.destroyWindow('MyWindow')
cameraCapture.release()

Cameo-面向对象设计

  • 使用多个I/O流
  • 创建CaptureManager类和WindowManager类作为高级的I/O流接口

使用managers.CaptureManager提取视频流

使用windowManager抽象窗口和键盘

监听键盘和鼠标事件:进行截图,截屏

运行时,摄像头帧被镜像,存储图片也被镜像(默认设置镜像为True)
managers.py

#managers.CaptureManager提取视频流
import cv2
import numpy
import timeclass CaptureManager(object):def __init__(self,capture,previewWindowManager = None,shouldMirrorPreview = False):self.previewWindowManager = previewWindowManagerself.shouldMirrorPreview = shouldMirrorPreviewself._capture = captureself._channel = 0self._enteredFrame = Falseself._frame = Noneself._mirroredframe = Noneself._imageFilename = Noneself._videoFilename = Noneself._videoEncoding = Noneself._videoWriter = Noneself._startTime = Noneself._framesElapsed = numpy.long(0)self._fpsEstimate = None@propertydef channel(self):return self._channel@channel.setterdef channel(self,value):if self._channel != value:self._channel = valueself._frame = None@propertydef frame(self):if self._enteredFrame and self._frame is None:_ , self._frame = self._capture.retrieve() #retrieve()是解码并返回一个帧,grab是指向下一个帧(不需要当前帧时可跳过),read是grab和retrieve的结合return self._frame@propertydef isWritingImage(self):return self._imageFilename is not None@propertydef isWritingVideo(self):return  self._videoFilename is not Nonedef enterFrame(self): #Capture the next frame#check previous frame was existed.# 检查上一帧是否退出assert not self._enteredFrame , \'previous enterFrame() had no matching exitFrame()'if self._capture is not None :self._enteredFrame = self._capture.grab() #用grab()指向下一帧def exitFrame(self):#draw to the window ,write to files , release the frame.if self.frame is None:self._enteredFrame = Falsereturnif self._framesElapsed == 0 :self._startTime = time.time()else:timeElapsed = time.time() - self._startTimeself._fpsEstimate = self._framesElapsed / timeElapsedself._framesElapsed += 1#draw to the windowif self.previewWindowManager is not None:if self.shouldMirrorPreview:self._mirroredframe = numpy.fliplr(self._frame).copy()self.previewWindowManager.show(self._mirroredframe)else:self.previewWindowManager.show(self._frame)if self.isWritingImage:if self.shouldMirrorPreview:cv2.imwrite(self._imageFilename,self._mirroredframe)else :cv2.imwrite(self._imageFilename, self._frame)self._imageFilename = Noneself._writeVideoFrame()self._frame = Noneself._enteredFrame = Falsedef writeImage(self , filename):self._imageFilename = filenamedef startWritingVideo(self,filename,encoding=cv2.VideoWriter_fourcc('I','4','2','0')):self._videoFilename = filenameself._videoEncoding = encodingdef stopWritingVideo(self):self._videoFilename = Noneself._videoEncoding = Noneself._videoWriter = Nonedef _writeVideoFrame(self): #非公有if not self.isWritingVideo:returnif self._videoWriter is None:fps = self._capture.get(cv2.CAP_PROP_FPS)if fps == 0.0:if self._framesElapsed < 20 :returnelse:fps = self._fpsEstimatesize = (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,mousepressCallback = None):self.keypressCallback = keypressCallbackself.mousepressCallback = mousepressCallback #鼠标self._windowName = windowNameself._isWindowCreated = False@propertydef isWindowCreated(self):return self._isWindowCreateddef createWindow(self):cv2.namedWindow(self._windowName)self._isWindowCreated = Truecv2.setMouseCallback(self._windowName,self.mousepressCallback) #鼠标事件def show(self , frame):cv2.imshow(self._windowName,frame)def destoryWindow(self):cv2.destroyWindow(self._windowName)self._isWindowCreated = Falsedef processEvent(self):keycode = cv2.waitKey(1)if self.keypressCallback is not None and keycode != -1:keycode &= 0xFFself.keypressCallback(keycode)#python内置的@property装饰器就是负责把一个方法变成属性调用的

cameo.py

import cv2
from managers import WindowManager , CaptureManagerclass Cameo(object):def __init__(self):self._windowManager = WindowManager('cameo',self.onKeypress,self.onMouse)self._captureManager = CaptureManager(cv2.VideoCapture(0),self._windowManager,True)def run(self):self._windowManager.createWindow() #创建窗口while self._windowManager.isWindowCreated:self._captureManager.enterFrame()     #检查上一帧是否退出,并指向下一帧frame = self._captureManager.frame    #获取当前帧self._captureManager.exitFrame()      #draw to the window ,write to files , release the frame.self._windowManager.processEvent()    #处理键盘事件def onKeypress(self , keycode): #键盘响应"""Handle a keypress.space  -> Take a screenshottab    -> Start/Stop recording a screencastescape -> Quit"""if keycode == 32: #spaceself._captureManager.writeImage('screenshot.png')elif keycode == 9:#tabif not self._captureManager.isWritingVideo:self._captureManager.startWritingVideo('screencast.avi')else:self._captureManager.stopWritingVideo()elif keycode == 27:#escapeself._windowManager.destoryWindow()def onMouse(self , event, x, y, flags, param): #鼠标响应函数if event == cv2.EVENT_LBUTTONUP:self._windowManager.destoryWindow()
if __name__=="__main__":Cameo().run()

OpenCV3计算机视觉:Python实现 读书笔记-第二章相关推荐

  1. 《计算传播学导论》读书笔记——第二章文本分析简介

    <计算传播学导论>读书笔记--第二章文本分析简介 第一节 文本分析研究现状 常用文本挖掘技术 第二节 文本分析与传播学研究 (一)为什么文本挖掘技术逐渐受到传播学者的关注 (二)不同文本分 ...

  2. In-memory Computing with SAP HANA读书笔记 - 第二章:SAP HANA overview

    本文为In-memory Computing with SAP HANA on Lenovo X6 Systems第二章SAP HANA overview的读书笔记. 本章最重要的部分是SAP HAN ...

  3. C++ Primer Plus读书笔记第二章

    自学了一段时间的C++打算还是要系统的整理一下一些知识点,让学习思路更清晰,不然老是学一点忘一点,这个读书笔记用来记录这段时间对C++ Primer Plus一书中知识点的记录,尽量会写的详细一点.直 ...

  4. 《软件测试经验与教训》读书笔记---第二章

    <软件测试经验与教训>读书笔记--目录 第一章 测试员的角色 第二章 按测试员的方式思考 第三章 测试手段 第四章 程序错误分析 第五章 测试自动化 第六章 测试文档 第七章 与程序员交互 ...

  5. 计算机网络(第五版 作者:AndrewS.Tanenbaum David J.Wetherall 清华大学出版社)读书笔记----第二章的学习

    计算机网络第二章--物理层读书笔记 1.物理层是网络的技术设置,物理层的材质和带宽决定了最大的传输速率. 2.传输介质的分类:引导性(有线介质)和非引导性(无线介质). (1)有线介质:磁介质.双绞线 ...

  6. PHP核心技术与最佳实践 读书笔记 第二章 面向对象的设计原则

    2019独角兽企业重金招聘Python工程师标准>>> 第二章 面向对象的设计原则 2.1 面向对象设计的五大原则 单一职责原则 接口隔离原则 开放-封闭原则 替换原则 依赖倒置原则 ...

  7. 《辛雷学习方法》读书笔记——第二章 心态

    第二章 心态   (1)保持良好心态:学习时保持良好心态,你才能比较容易入门.深入掌握知识.灵活运用知识.学习时始终保持着轻松愉悦振奋的心情,你就容易产生学习心得,更容易灵活运用. (2)爱情对心态影 ...

  8. 4月19日读书笔记——第二章序列构成的数组(1)

    流畅的python 第二章 序列构成的数组 在这之前,我想要先知道什么是序列.维基百科的答案是 数学上,序列是被排成一列的对象(或事件):这样,每个元素不是在其他元素之前,就是在其他元素之后. 例如: ...

  9. 《暗时间》读书笔记--第二章 进度条,第三章 有效记忆和学习

    第二章 进度条 要点: 进度条的例子 过早的退出 专注和持之以恒 饿死在甘草间的驴子 我的总结: 开篇作者讲了一个进度条的例子,我们的生活中充满着各种各样的进度条,工作的之前我们要做工作计划,要指定T ...

  10. 【编程珠玑】读书笔记 第二章 算法

    2013-07-11 22:00:28 第二章 算法 本章围绕三个问题进行算法讨论,包括元素的查找.字符串的旋转.以及变位词的查找. 下面给出了实现代码.以及测试结果. 问题一 查找不存在的元素 思路 ...

最新文章

  1. Go语言开发常见陷阱,你遇到过几个?
  2. js 正则之检测素数
  3. java 函数参数 返回值_java中如何用函数返回值作为post提交的参数?
  4. PPT 下载 | 神策数据孙超赟:多场景解读运营的价值、生存状态与解决方案
  5. python钻石数据分析_数据分析该用什么工具?
  6. pitstop插件使用说明_【学员分享】程序员效率神器,最常用VIM插件安装大全
  7. linux权限bcd码是6,Linux权限管理(1)基本权限
  8. 参数等效模型可以用于_华北电力大学 陈宁、齐磊 等:适用于柔性直流电网操作过电压分析的混合式高压直流断路器端口等效模型...
  9. 查看本机的用户 net user
  10. 微信小程序反编译解包教程
  11. 音乐播放类应用后台播放耗电评测报告 1
  12. RocketMQ(消息中间件)
  13. 如何防止局域网病毒春风吹又生--之二
  14. android动态mac地址,Android 版本兼容 — Android 6.0 和 7.0后获取Mac地址
  15. python tkinter.Text 高级用法 -- 设计功能齐全的文本编辑器
  16. 如何开发手游联运平台?
  17. 550+集Java学习全套视频课程,新手入门收藏
  18. 准确率99.9%的离线IP地址定位库
  19. 读书:每天做一个情绪稳定的成年人!
  20. 写给大家看的机器学习书【Part3】直观易懂的感知机学习算法PLA

热门文章

  1. Nexus下载安装+登录修改密码(Maven私服)
  2. 资深人士关于PIFA天线的理解与讨论
  3. 通达信主力强势上涨预警副图指标公式(源码)
  4. Ubuntu下mysql可视化_ubuntu上mysql有可视化界面吗 ubuntu mysql 图形界面
  5. vc++/c++ 汉字取拼音首字母
  6. python爬虫淘宝评论图片_淘宝上的图片是怎么被爬取的
  7. java+构造函数+native_java中native的用法
  8. cmos和ttl_TTL与CMOS电路怎么区分
  9. 音视频实时交互/语音通话/即时通话/连麦,EasyRTC即时通讯系统全方位服务
  10. 威纶通触摸屏直接与台达变频器进行MODBUS RTU通信的具体方法(图文)