目录
- 1 全篇概要(主要阅读对象及内容提要)
- 2 python知识点之——环境及依赖的库安装简述
- 2.1 Python开发环境安装
- 2.2 Python 机器视觉模块安装
- 2.3 写第一个Python 图像打开程序
- 3 python知识点之——重要python编程基础概念简述
- 3.1 缩进
- 3.2 If语句
- 3.3 函数
- 3.4 类
- 3.5 循环
- 3.6 基础数据类型
- 3.7 基础数据结构
- 4 python知识点之——高级概念及应用
- 4.1 生成器(generator)
- 4.2 线程(thread)
- 4.3 队列(queue)
- 本节源码:
- 4.4 装饰器
- 本节源码:
1 全篇概要(主要阅读对象及内容提要)
如今,Python语言已经成为人工智能领域最热门的开发语言之一,她正在被越来越多的从事人工智能(包括机器人、机器视觉)的机构、和个人所使用,人们在使用python语言的灵活性、易用性及强大的应用模块的同时,也贡献她们的专业优秀模块,在科学各专业领域形成了科学计算的python模块资源,使得初学者便捷快速进行应用开发,降低重复劳动,避免重复制造“轮子”,快速实现程序的专业领域应用及设计规划落地,尤其,在机器人领域,作为机器人工程应用最重要的组成部分——机器视觉,python及其生态开发者为我们提供了诸如opencv-python、numpy、pillow等图像处理所需的模块库,任何人可以通过python自带的工具(pip)方便的安装相对应的版本,进行研究或工程应用。
本篇的阅读对象是致力于使用python或者通过python编程想敲门进入机器人视觉领域的零python基础者,假设具备有一定的其它编程语言的基础经验,掌握了诸如“函数”、“类”、“变量”、“数据类型”、“条件判断”、“循环”、“线程”等概念。
本篇的目标是抛砖引玉地介绍从事机器视觉python研究开发或工程应用所需的最基础知识点,简要介绍图像结构及基础运算、图像处理python基础库、图像识别基本流程、图像坐标变化等知识,帮助初学者入门python的机器视觉开发。
本篇讲述的内容如下:
(1) Python知识点一。主要讲述python的安装,及依赖环境的搭建,以及上手基础操作。
(2) Python知识点二。主要讲述python机器视觉编程的基础而重要的概念,并配以相应的程序进行说明,重要的概念有:”缩进”、”函数”、”类“、”循环“、基础数据类型等。
(3) Python知识点三。主要讲述python机器视觉编程所需的较为高级的概念,有助于提高性能及简化算法。如:”生成器“、“线程”、”队列“、”装饰器“等。
(4) 图像的读取与运算基础。主要讲述图像从摄像头获取后,图像的数据结构形式、图像的类型、及简单的运算。
(5) 图像处理基础库简介。主要介绍图像处理核心库opencv,以及人机界面PySimpleGUI,两者结合可以达到事半功倍的效果。
(6) 桌面物体识别基本流程。主要介绍了当摄像头获取一张桌面物体的图像后,如果通过以上的知识、工具对图像中的物体进行有效识别,并标记出来。
(7) 图像的坐标计算。主要介绍了如何将图像中的像素与摄像头外的现实空间坐标进行关联,从而实现图像中物体对应于现实世界的坐标定位,为机器人的抓取提供坐标。
当具备了以上基础知识后,读者可以通过翻阅本博客的另一个专题《实用工具集》,进行更深入的练习,改专题在每篇最后都提供了python源代码,方便快速复现。
本篇大部分凭笔者的经验及认识所写,难免会有不系统及遗误,还请读者批评指正。
2 python知识点之——环境及依赖的库安装简述
2.1 Python开发环境安装
对于初学者来说,建议安装Python集成了常用的python模块的发行版Anaconda,它自带集成了常用的模块外,还配置了spyder、jupyter Notebook两个轻量的开发环境,可以便捷使用。以windows操作系统为例,可以到Anaconda官网下载适合windows/mac/linux对应的安装的版本。网上很容易搜索到:
2.2 Python 机器视觉模块安装
安装完后,即可以进行本篇所需的其它机器视觉模块的安装,以windows操作系统为例,可以有在线安装和离线安装两种模式,在线安装一个opencv-python模块的步骤如下:
步骤一:首先打开开始菜单下的Anaconda Powershell Prompt,进入shell模式。
步骤二:在打开的命令行终端,输入安装指令,如pip install opencv-contrib-python==3.4.2.17,这里的版本号(==3.4.2.17)也可以不输入,那么对默认安装最新版本,建议安装opencv3.X,保持与本篇环境同步。
PS:由于Anaconda的默认安装源是国外网站,有时候由于网络原因会安装失败,这样可以将pip的安装装源更换为国内的站点,然后再输入pip安装指令安装对应的模块,更换的办法如下:
命令行终端输入:
pip config set global.index-url https://pypi.tuna.tsinghua.edu/simple
可以通过输入pip config list,查看是否已添加国内源。
当需要安装同个模块的其它版本时,可以先使用pip uninstall 模块名称指令进行卸载后再通过pip install 模块名称==模块版本号重新安装。
离线安装,步骤如下:
步骤一:进入opencv安装模块清华源:
https://pypi.tuna.tsinghua.edu/simple/opencv-contrib-python/
选择指定操作系统及对应版本,进行下载。
步骤二:
命令行进入下载模块的文件夹路径,使用pip install 安装模块名,进行安装:
如果在开发过程中需要安装新模块,模块的安装也可以参考以上安装步骤,不再赘述。
安装模块后,可以通过两种方式查看是否安装成功:
(1) 命令行端输入pip list | findstr “opencv”
(2) 命令进入python,并输入import cv2后不报错即为安装成功。
2.3 写第一个Python 图像打开程序
完成以上环境及模块安装后,就可以打开spyder编程工具进行python的编程了:
打开spyder编辑器
新建一个.py文档,并保存在一个文件夹(如charp 1),输入如下代码,可以打开文件夹里的图片了:
import cv2
image=cv2.imread(“image1.png”)
cv2.imshow(“title”,image)
显示图片窗口如下:
3 python知识点之——重要python编程基础概念简述
Python是一种脚本语言,其语法相对其它语言来说约束相对较少,不需要事先声明变量类型,也没有“{}”,python解释器是通过”:”、”tab”、“def”等特殊符合来解释程序的。最基础的语法如下:
3.1 缩进
Python里缩进是必须严格执行的语法规则和编码规范,每行代码都必须遵守缩进的原则,保持与上下行代码缩进相对一致,如果忽略缩进规则,或者在同一代码段与上下行的缩进没保持一致,则程序可能无法运行或者运行出错。
缩进可以使用多个空格或者一个Tab指标符。在spyder编辑器里,会自动识别”:”,回车后自动会加入一个Tab缩进:
3.2 If语句
Python的if语句格式比较简洁,通过if 条件:进行声明,与或非使用字母 and or not 进行条件判断,以下是if使用举例:
3.3 函数
Python是通过”def”+空格+函数名 来声明函数的,函数可以有参数,也可以不带参数,函数既可以有返回值,也可以没有返回值,返回值用return + 返回值表示,简单形式如下:
Python的函数,有一个很有意思且将来很有用的功能是,它的函数参数可以设置默认值,通过”function(参数=默认值)”表示,这样调用函数时,如果参数不变,就可以不输入这个参数,如果想要改变参数的默认值,调用时就加上想要的参数值,调用时最好写成下图最后一种形式:
Python的函数可以带上多个默认参数,这样可以方便地编写带非常多默认参数的图像处理函数,且调用函数时根据需要带上少量参数即可。当然python函数的参数还支持可变参数、关键字参数等,在本篇不再说明。
3.4 类
Python的类通过关键词“class +类名”定义,可使用def init(self,参数1…)定义类的构造函数。通过“=类名(参数…)”进行实例化一个类。举例如下:
当一个类定义好后,可以单独保存为一个文件,当在工程用到该类时,可以通过”from 文件名 import 类名”进行引入,如下:
3.5 循环
Python最常用到的循环是for循环和while循环,一个for循环。while循环一般用于循环次数不确定的运算,或者用于一个线程的主循环中,每次循环要对循环条件进行判断。for循环用于较为确定次数的循环,较多用于如列表或字典等类型的遍历等,要想中间退出循环,使用可使用break语句。
(1) while循环的例子
以下示例使用了一个while循环,用于不断读取摄像头的(帧)图像,并当按下键盘q的时候,执行break退出while循环,这样就实现了一个视频的采集程序。
(2) for循环的例子
for循环使用for+变量+in+列表进行声明,以下for循环实现了0到9的加和。
3.6 基础数据类型
Python在使用各类型变量时,不需要进行类型声明,会自动识别变量类型。通过type()函数可以提供变量类型的查看。变量基本类型主要有int(整数型)、float(浮点型)、str(字符串)和bool(布尔型)四种,可以看出,这四种类型本身是一个class对象,可见python的基础是对象构成的。
3.7 基础数据结构
Python提供非常易用的数据结构,主要有:list(列表)、dist(字典)、tuple(元组)、str(字符串)等。
(1) list列表
列表的创建可以通过“[]”、或“list()”进行创建,通过.append(元素)进行在末尾追加元素,支持任意类型。通过.pop(索引号),删除索引号对应的元素,如不指定索引号,则删除列表的最后一个元素。列表常用的操作如下:
(2) dist字典
dist字典是python又一好用的数据结构,其形式是类似一个个键值对的表,但是这个表跟顺序无关,可以存储任何类型的元素或数据结构,字典封装了很多有用的方法,可以用于复杂计算的结构化存储。
字典可以通过dict(key=value)或者{key:value}创建,用字典名.update({key:value})或者字典名[key]=value进行插入或者更新,用pop(key)进行删除。下面列出了一些字典操作的示例:
(3) tuple元组
tuple元组可以认为是只有两个元素的列表,不同的是一旦创建这个tuple元组,就不能进行元素的增加、删除、和修改操作,元组可以用于一些结构类似的坐标、像素位置等。
创建使用(元素1,元素2)或者tuple([元素1,元素2]),通过元组名[index]进行取值查询。
(4) str字符串
python字符串可以用于文本处理,其功能非常强大,字符类串封装了非常多的方法,可以认为字符串是字符的列表,可以进行索引和切片操作,但是不能进行增加字符和删除和修改。以下为一些字符串操作示例:
4 python知识点之——高级概念及应用
4.1 生成器(generator)
生成器是一种利用python的协程机制实现的特殊函数,其特点是内部具有类似中断的机制,当接收到外部信号后才继续执行。利用这个特点,可以容易实现流程化计算:
4.2 线程(thread)
线程是操作系统能够进行运算的最小单位,线程在进程中运行,创建多个线程,可以进行多任务的平行运行,提高程序的性能。
Python的threading模块提供了简单易用的方法,使使用者能够非常便捷地创建多线程函数。示例如下:
4.3 队列(queue)
当python涉及到同一个图像源多任务图像处理时,由于各图像处理的时间不同,图像的”生产”和”消费”就会产生“供大于求”或者“供小于求”的情况,容易造成整个系统的堵塞或者异常。使用python的队列功能块,在图像处理的上下游设置队列作为中间缓冲块,能够较好解决此类问题:
本节源码:
# -*- coding: utf-8 -*-
"""
Created on Sat May 21 18:42:46 2022
@author: JAMES FEI
"""
from collections import deque
import cv2
import time,threading
MAXLEN=5#队列缓存的长度
FBUFFER=deque(maxlen=MAXLEN)#创建视频图像队列
def video_server(period=0.03):
"""
视频采集服务
"""
print("start video server...")
cap=cv2.VideoCapture(0)
while(True):
time.sleep(period)#设定视频采集周期,每period秒采集一次
sucess,frame=cap.read()#从摄像头读取新图像帧
if sucess:
FBUFFER.append(frame)#压入队列
key=cv2.waitKey(1)#通过函数获取按下监盘的值
if key == ord("q"):#当按下q键时
cap.release()#当按下q键时,关闭摄像头
print("server closed...")
break#当按下q键时,退出while循环
def image_processor(num,period=1):
"""
视频处理器
"""
print("image processor %d start.. "%num)
while(True):
time.sleep(period)#设定视频采集周期,每period秒采集一次
if FBUFFER:
image=FBUFFER.popleft()#读取缓存图像
print("NO. %d processing....."%num)
if __name__ == '__main__':
server=threading.Thread(target=video_server,args=(0.03,))#创建视频服务器线程
p1=threading.Thread(target=image_processor,args=(1,1))#创建视频处理器1线程
p2=threading.Thread(target=image_processor,args=(2,1))#创建视频处理器2线程
p3=threading.Thread(target=image_processor,args=(3,1))#创建视频处理器3线程
p4=threading.Thread(target=image_processor,args=(4,1))#创建视频处理器4线程
server.start()#启动服务线程
p1.start()#启动处理线程
p2.start()#启动处理线程
p3.start()#启动处理线程
p4.start()#启动处理线程
4.4 装饰器
Python通过在程序前一行使用@+装饰器名应用装饰器,所谓装饰器是一个函数它用来对另一个函数(被装饰的对象)在不改动代码的前提下进行函数功能上或性能上的补充优化。
本节源码:
# -*- coding: utf-8 -*-
"""
Created on Sat May 21 18:42:46 2022
@author: JAMES FEI
"""
import time
from numba import jit
def calTime(func):#自定义一个计算函数耗时的装饰器函数
def wrapper(*args,**kwds):
Tstart=time.time()#开始时间
func(*args,**kwds)#执行被修饰函数
Tend=time.time()#结束时间
print("函数执行耗时%0.3f秒"%(Tend-Tstart))
return wrapper
@calTime #使用@calTime自定义装饰器
def job1():#定义一个耗时for循环
def dofor(): #定义一个耗时计算函数
model=0
for x in range(10240):
for y in range(10000):
model=(3*x+3*y)/(x+1)+model
dofor()
@calTime #使用@calTime自定义装饰器
def job2():#定义一个耗时for循环,并使用@jit装饰器加速
@jit
def dofor(): #定义一个耗时计算函数
model=0
for x in range(10240):
for y in range(10000):
model=(3*x+3*y)/(x+1)+model
dofor()
if __name__ == '__main__':
job1()#执行一个耗时计算,未优化
job2()#执行一个耗时计算,性能优化
(—上篇完—)
更多推荐
python机器人视觉编程——入门篇(上)
发布评论