最近公司接到一个案子,使用移动机械臂抓取圆盘上下料,目前我们的移动机器人定位精度在两厘米左右,因此需要视觉辅助定位来提高夹取的精度。
这个项目本身不是我做,出于对是视觉的兴趣,学习了一下如何使用 OpenCv 提取零件的坐标。
臂大概是这样的,平台是我司开发的 300kg 负载全向轮系列,臂为 ABB 的 IRB1200(话说 n 年前我也参与了这款臂的研发.....):
实际使用的时候,应该是按以下流程操作:
下面是学习过程 :
环境:
我自己做学习用所以拍照用的是手机拍照:iPhone5S 深空灰国行移动定制版
软件:python2.7,OpenCv2
OpenCv 的安装:
1.1 安装 Python2.7
1.2 安装 numpy: pip install numpy
1.3 下载安装 opencv2.4x
1.4 把 OpenCV 安装目录下的 "\\OpenCV\opencv\build\python\2.7" 的 cv2.pyd 复制到 Python 目录 ".\Program Files\Python27\Lib\site-packages" 下
具体思路如下:
- # coding:UTF-8
- import cv2
- import numpy as np
- class Findposition:
- def __init__(self,path):
- #获取图片
- self.img=cv2.imread(path)
- self.gray=cv2.cvtColor(self.img,cv2.COLOR_BGR2GRAY)
- self.hsv=cv2.cvtColor(self.img,cv2.COLOR_BGR2HSV)
- #提取黑色的区域
- def Get_black(self):
- #get black area
- low_black=np.array([0,0,0])
- high_black=np.array([100,100,100])
- mask=cv2.inRange(self.img,low_black,high_black)
- black=cv2.bitwise_and(self.hsv,self.hsv,mask=mask)
- return black
- #将黑色区域进行二值化处理
- def Get_contour(self):
- #change to gray
- black=self.Get_black()
- black_gray=cv2.cvtColor(black,cv2.COLOR_HSV2BGR)
- black_gray=cv2.cvtColor(black_gray,cv2.COLOR_BGR2GRAY)
- #binaryzation
- _, thresh=cv2.threshold(black_gray,10,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
- img_morph=cv2.morphologyEx(thresh,cv2.MORPH_OPEN,(3,3))
- cv2.erode(img_morph,(3,3),img_morph,iterations=2)
- cv2.dilate(img_morph,(3,3),img_morph,iterations=2)
- return img_morph
- #获取中心区域轮廓及坐标
- def Find_contour(self,img):
- img_cp=img.copy()
- cnts,_=cv2.findContours(img_cp,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
- cnt_second=sorted(cnts,key=cv2.contourArea,reverse=True)[1]
- box =cv2.minAreaRect(cnt_second)
- return np.int0(cv2.cv.BoxPoints(box))
- #绘制轮廓
- def Draw_contour(self,points):
- mask=np.zeros(self.gray.shape,np.uint8)
- cv2.drawContours(mask,[points],-1,255,2)
- return mask
- #获取中心位置
- def Get_center(self,points):
- p1x,p1y=points[0,0],points[0,1]
- p3x,p3y=points[2,0],points[2,1]
- center_x,center_y=(p1x+p3x)/2,(p1y+p3y)/2
- center=(center_x,center_y)
- return center
- #绘制中心点
- def Draw_center(self,center,mask):
- cv2.circle( mask,center,1,(255,255,255),2)
- return mask
- #主函数
- def main_process(self):
- morph=self.Get_contour()
- black=self.Get_black()
- points=self.Find_contour(morph)
- mask=self.Draw_contour(points)
- center=self.Get_center(points)
- draw_center=self.Draw_center(center,mask)
- center_x,center_y=self.Get_center(points)
- print(center_x,center_y)
- cv2.imshow('black',black)
- cv2.imshow('morph',morph)
- cv2.imshow('img',self.img)
- cv2.imshow('contour',draw_center)
- cv2.waitKey(0)
- if __name__== '__main__' :
- path='C:\Users\KaiyuanCao\Desktop\sample.jpg'
- d = Findposition(path)
- d.main_process()
输出图片这个其实没啥用,主要是看看效果,目标是得到中心点的位置。
实际运行效果如下:
圆盘的边沿太薄了,不太好提取轮廓,因此希望用中间的圆柱区域来定位
这个时候白色的背景和支撑盒已经被滤掉了
- #学习到此结束
- While True:
- end learning
- break
万事开头易,而后难,然后很难很难,最后难的不行了,凡事浅尝辄止。
百度搜索 "就爱阅读", 专业资料, 生活学习, 尽在就爱阅读网 92to.com, 您的在线图书馆!
来源: http://www.92to.com/bangong/2017/08-02/26189270.html