opencv 获取摄像头拍摄图中物料位置并获取物料坐标

摄像头拍摄散放多个物料 物料是同一种物料, opencv 获取图片中最中心三个物料中心坐标。

看看这个代码行不行:

# 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()


播放的摄像头视频,可以看做由一帧帧图片动态组成的,参考这篇文章,实现你的需求
用python和opencv实现物体框选并保存坐标信息及面积信息(附代码)_小小小小能的博客-CSDN博客_python框选图片

可以使用形态学变换、最后获取轮廓,计算轮廓的中心点坐标,有需要的话可以练习详聊

环境:
我自己做学习用所以拍照用的是手机拍照: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
万事开头易,而后难,然后很难很难,最后难的不行了,凡事浅尝辄止

来一张物料图片

找出所有物料中心位置,算出距离图像中心偏移值,加到容器中。排序找出距离中心最小三个值就行了。

物料在相机视野中相对相机中心偏移位置计算 ptLock.x= ptcvLock.x - nWidth / 2; ptLock.y= ptcvLock.y - nHeight / 2; (ptcvLock 是图像处理算出的物料中心在图片中的像素坐标, nWidth,nHeight分别是相机图片的宽高)。