python机器人视觉编程——入门篇(下)

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 图像的读取与运算基础

2.1图像的读取

对于初、中级图像处理人员,可以使用opencv的python库进行图像的读取,包括:

2.1.1 从磁盘的图像(.jpg,.npg,.gif等等)读取

比如从D盘读取一张名叫test.jpg的图片到计算机的内存,并显示在窗口,可以在python编辑器里敲入如下代码:

import cv2
image=cv2.imread("D:\\test.JPG")#""内输入图像文件路径即可
cv2.imshow("test",image)

在这里插入图片描述

2.1.2 从摄像头里读取图像

如果想要从计算机自带的摄像头,或者USB摄像头读取采集的图像,可以这样进行读取和显示:

import cv2

cap=cv2.VideoCapture(0)   
while(True):
    sucess,frame=cap.read()#连续读取图像帧
    if sucess==True:#如果读取图像成功
        cv2.imshow("video",frame)#通过窗口显示更新图像
    key=cv2.waitKey(1)#通过函数获取按下监盘的值
    if key == ord("q"):#当按下q键时            
        cap.release()#当按下q键时,关闭摄像头
        cv2.destroyAllWindows()  #当按下q键时,关闭显示窗口               
        break#当按下q键时,退出while循环

在这里插入图片描述

2.2图像的运算

2.2.1 图像的数据结构

在物理结构上面,计算机展示的图像是由一个一个像素横竖排列组成的,且每个像素都是有颜色的。然而,本质上,对计算机来说,图像就是很多个按一定的组合顺序排列的数字组合。可以认为一副彩色的图像,是由三个二维的数组组合而成的数字集合(或者是三个数字矩阵组成)。如下图所示,左上角是一副人类看到的图像(放大后),该图像具有9个像素。这副图像,在计算机看来是三个二维数字组合:
![在这里插入图片描述](https://img-blog.csdnimg.cn/19b6e2168fb040209a95e12f4b31eea1.png
如上图所示,左上角的图像(RGB格式),计算机用三个二维的数字组合来存储,显示时,根据RGB的格式显示规则,即,每个像素显示,根据此像素在对于三个通道的对应位置的数值(可以认为是一个坐标,如(255,150,12))在RGB色域空间上查找到颜色后就显示出来(土黄色)。色域空间如下图:
在这里插入图片描述
我们可以用python读取一张小的图片,然后把他的数据打印出来:

import cv2
image=cv2.imread("D:\\test.JPG")
print("图像的数据结构",image.shape)
print("图像的像素数量",image.shape[0]*image.shape[0])
print("图像的详细数据",image)

打印输出如下:
在这里插入图片描述
上图所示,所读取的图像,结构是,有3个维度(或三个通道),每个维度中:竖着有30组数字,横着有28组数字,总共有840个数字。每个数字都是0-255之间的整数。在python里,我们可以通过*.shape*函数查看图像的结构。
*PS:opencv对rgb色域的图像存储,1-3通道先后顺序分别对应的是(B、G、R),而不是通常的RGB顺序。还需要注意的是,除了RGB格式存储外,还有其它如HSV、LAB等色域空间的存储,有些色域空间的通道值最大不是255,有可能是180. 由于深度有限,本篇只对BGR空间的图像进行探讨。

2.2.2 图像的像素与数据存储结构的对应规则

图像像素一般规定的坐标是以左上角为原点,分别向右向下增加坐标的数值,如下图:
在这里插入图片描述
像素坐标一般以u,v称呼,横着叫u轴,竖着叫v轴。比如上图红色像素的坐标是(1,1),左上角的像素的坐标是(0,0)。如果我们要知道图像某个像素的各通道数值是多少,我们可以利用python的“[u,v,x]”操作,操作如下:

import cv2
image=cv2.imread("D:\\test.JPG")
#获取图像左上角像素,的第一个通道(B通道)的值
print("图像左上角像素,的第一个通道(B通道)的值是:",image[0,0,0])
#获取图像中坐标为(u,v)=(9,10)的像素,的第二通道(G通道)的值  
print("获取图像中坐标为(u,v)=(9,10)的像素,的第二通道G通道)的值是:",image[10,9,1])   
#获取图像中坐标为(u,v)=(9,10)的像素,的3个通道(的值  
print("获取图像中坐标为(u,v)=(9,10)的像素,的3个通道(的值是:",image[10,9,:3])   

输出结果:
在这里插入图片描述

2.2.2 图像的像素信息获取、运算

知道了图像本质是3个维度的二维数据后,以及图像各个像素坐标与数据存储结构的对应关系,我们就可以很容易的对图像中的任意位置像素进行计算,包括:指定像素的提取、同种颜色像素的查找及个数的统计、或者是更改一下特定像素的三个RGB“坐标”数值,改变像素的颜色等等。简单演示如下:

(1)像素的统计运算

直方图的本质其实就是对图像象素进行同类项合并,并统计出0-255(或最大值)的颜色域内,各个像素的分布情况。

import cv2
import matplotlib.pyplot as plt#用于绘制统计图
image=cv2.imread("D:\\test.JPG")

B=[0 for i in range(256)]#创建一个具有256个长度的列表,分别用于存储0-255值得象素个数
G=[0 for i in range(256)]#创建一个具有256个长度的列表,分别用于存储0-255值得象素个数
R=[0 for i in range(256)]#创建一个具有256个长度的列表,分别用于存储0-255值得象素个数
#对图像得B通道的数值进行遍历,将通道内同类的数值个数,根据数值放入创建的列表value中
for u in range(image.shape[1]):
    for v in range(image.shape[0]):
        B[image[v,u,0]]=B[image[v,u,0]]+1
        G[image[v,u,1]]=G[image[v,u,1]]+1
        R[image[v,u,2]]=R[image[v,u,2]]+1
        
#画出直方图
x=[i for i in range(256)]#横坐标
fig=plt.figure()  
fig.canvas.set_window_title('直方图')   
plt.subplot(3,1,1)
plt.bar(x,B,color='b')
plt.subplot(3,1,2)
plt.bar(x,G,color='g')
plt.subplot(3,1,3)
plt.bar(x,R,color='r')
plt.show()

输入结果:
在这里插入图片描述

由上图可以看出,图像在各通道,数值>250的象素个数分布是比较多的,即亮的区域比较多。

(2)像素的过滤与查询

我们可以根据图像的颜色特点,设置查找条件,找出图像中感兴趣的部位,过滤掉其它不感兴趣的部位,下面例子是设置条件,找到图像中红色块,并把这个区域单独显示:

import cv2
import matplotlib.pyplot as plt#用于绘制统计图
image=cv2.imread("D:\\test.JPG")

black=image*0#这是一张全为0的黑色底图,图的大小和image是一样的

#设置查找颜色的条件 红色

B=[0,255]#蓝色通道的范围
G=[0,50]#绿色通道的范围
R=[130,255]#红色通道的范围

#下面我们将同时符合以上条件的象素给找出来,并放入底图black中
for u in range(image.shape[1]):
    for v in range(image.
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

机智新语

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值