我是靠谱客的博主 威武蛋挞,这篇文章主要介绍ROS利用仿真摄像头识别并抓取物体(一),现在分享给大家,希望可以做个参考。

ROS利用仿真摄像头识别物体

在机械臂URDF文件中添加仿真摄像头、桌子和物体。运行launch文件启动gazebo。

复制代码
1
2
roslaunch prrobot_gazebo probot_anno_with_gripper_gazebo_world.launch

在这里插入图片描述运行结果如下图所示:
在这里插入图片描述接下来运行以下python程序对绿色物体进行识别

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#!/usr/bin/env python # -*- coding: utf-8 -*- import rospy import cv2 from cv_bridge import CvBridge, CvBridgeError from sensor_msgs.msg import Image import numpy as np from math import * from geometry_msgs.msg import Pose class Image_converter: def __init__(self): self.image_pub = rospy.Publisher('table_detect_test',Image,queue_size = 10) self.bridge = CvBridge() self.image_sub = rospy.Subscriber('/probot_anno/camera/image_raw',Image,self.callback) def callback(self,data): try: cv_image = self.bridge.imgmsg_to_cv2(data,"bgr8") except CvBridgeError as e: print e size = self.detect_table(cv_image) detect_image = self.detect_box(size[0], size[1], size[2], size[3], size[4]) try: self.image_pub.publish(self.bridge.cv2_to_imgmsg(detect_image, "bgr8")) except CvBridgeError as e: print e def detect_table(self,image): b, g, r = cv2.split(image) binary_image = cv2.medianBlur(r, 3) for i in range (binary_image.shape[0]): for j in range (binary_image.shape[1]): editValue = binary_image[i, j] editValue2 = g[i, j] if editValue >= 0 and editValue < 20 and editValue2 >= 0 and editValue2 < 20: binary_image[i, j] = 255 else: binary_image[i, j] = 0 img, cnts, hierarchy = cv2.findContours(binary_image, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) x, y, w, h = cv2.boundingRect(binary_image) cv2.rectangle(image, (x, y), (x+w, y+h), (0, 0, 255), 5) # loop over the contours for c in cnts: # compute the center of the contour M = cv2.moments(c) if int(M["m00"]) not in range(20000, 250000): continue cX = int(M["m10"] / M["m00"]) cY = int(M["m01"] / M["m00"]) cv2.circle(image, (cX, cY), 5, (0, 0, 255), -1) return image, x, y, w, h def detect_box(self,image, x, y, w, h): b, g, r = cv2.split(image) binary_image = cv2.medianBlur(g, 3) for i in range (binary_image.shape[0]): for j in range (binary_image.shape[1]): editValue = binary_image[i, j] if i < y or i > y+h or j < x or j > x+w: binary_image[i, j] = 0 else: if editValue > 120 and editValue <= 255: binary_image[i, j] = 255 else: binary_image[i, j] = 0 img, cnts, hierarchy = cv2.findContours(binary_image, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) cv2.drawContours(image, cnts, -1, (255, 0, 0), 4) for c in cnts: # compute the center of the contour M = cv2.moments(c) if int(M["m00"]) not in range(20000, 250000): continue cX = int(M["m10"] / M["m00"]) cY = int(M["m01"] / M["m00"]) cv2.circle(image, (cX, cY), 5, (255, 0, 0), -1) return image if __name__ == "__main__": rospy.init_node("vision_manager") rospy.loginfo("start") Image_converter() rospy.spin()

识别结果如下图所示:
在这里插入图片描述程序基本思路:
创建一个订阅者,用来订阅仿真摄像头发布的图像信息;
创建一个发布者,用于发布识别后的图像信息。

复制代码
1
2
3
4
self.image_pub = rospy.Publisher('table_detect_test',Image,queue_size = 10) self.bridge = CvBridge() self.image_sub = rospy.Subscriber('/probot_anno/camera/image_raw',Image,self.callback)

订阅器订阅到摄像头信息/probot_anno/camera/image_raw后,就会进入回调函数。在回调函数中,首先将image信息转成Opencv可以识别的cv_image,然后运行两个图像识别函数,最后将识别的opencv图像信息专程ROS识别的image信息发布出去。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
def callback(self,data): try: cv_image = self.bridge.imgmsg_to_cv2(data,"bgr8") except CvBridgeError as e: print e size = self.detect_table(cv_image) detect_image = self.detect_box(size[0], size[1], size[2], size[3], size[4]) try: self.image_pub.publish(self.bridge.cv2_to_imgmsg(detect_image, "bgr8")) except CvBridgeError as e: print e

物体识别过程主要分别两部,即两个函数,第一部识别图像中黑色的桌面。将图像的红色通道分离出来,通过红色通道的颜色差异进行图像二值化,然后通过cv2.findContours进行识别,并通过cv2.boundingRect匡出桌子,函数返回桌子的坐标。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
def detect_table(self,image): b, g, r = cv2.split(image) binary_image = cv2.medianBlur(r, 3) for i in range (binary_image.shape[0]): for j in range (binary_image.shape[1]): editValue = binary_image[i, j] editValue2 = g[i, j] if editValue >= 0 and editValue < 20 and editValue2 >= 0 and editValue2 < 20: binary_image[i, j] = 255 else: binary_image[i, j] = 0 img, cnts, hierarchy = cv2.findContours(binary_image, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) x, y, w, h = cv2.boundingRect(binary_image) cv2.rectangle(image, (x, y), (x+w, y+h), (0, 0, 255), 5) # loop over the contours for c in cnts: # compute the center of the contour M = cv2.moments(c) if int(M["m00"]) not in range(20000, 250000): continue cX = int(M["m10"] / M["m00"]) cY = int(M["m01"] / M["m00"]) cv2.circle(image, (cX, cY), 5, (0, 0, 255), -1) return image, x, y, w, h

第二部在桌子范围内对绿色物体进行识别,方法与上一步方法一模一样,只是多了一个桌面的范围限制。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
def detect_box(self,image, x, y, w, h): b, g, r = cv2.split(image) binary_image = cv2.medianBlur(g, 3) for i in range (binary_image.shape[0]): for j in range (binary_image.shape[1]): editValue = binary_image[i, j] if i < y or i > y+h or j < x or j > x+w: binary_image[i, j] = 0 else: if editValue > 120 and editValue <= 255: binary_image[i, j] = 255 else: binary_image[i, j] = 0 img, cnts, hierarchy = cv2.findContours(binary_image, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) cv2.drawContours(image, cnts, -1, (255, 0, 0), 4) for c in cnts: # compute the center of the contour M = cv2.moments(c) if int(M["m00"]) not in range(20000, 250000): continue cX = int(M["m10"] / M["m00"]) cY = int(M["m01"] / M["m00"]) cv2.circle(image, (cX, cY), 5, (255, 0, 0), -1) return image

最后

以上就是威武蛋挞最近收集整理的关于ROS利用仿真摄像头识别并抓取物体(一)的全部内容,更多相关ROS利用仿真摄像头识别并抓取物体(一)内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(62)

评论列表共有 0 条评论

立即
投稿
返回
顶部