ROS利用仿真摄像头识别并抓取物体(一)

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

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

roslaunch prrobot_gazebo probot_anno_with_gripper_gazebo_world.launch

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

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

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

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信息发布出去。

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匡出桌子,函数返回桌子的坐标。

 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
  • 20
    点赞
  • 191
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
好的,我可以为您提供一些指导。要实现这个任务,您需要做以下步骤: 1. 安装ROS摄像头驱动程序。 2. 选择适合您的小车硬件,并将其连接到ROS系统。 3. 使用OpenCV库编写C++代码来捕获摄像头图像,并使用物体检测算法(如Haar级联分类器或深度学习模型)来识别目标物体。 4. 将目标物体的位置信息传递给小车控制器,使其移动并击倒目标物体。 下面是一个大致的代码框架,供您参考: ```c++ #include <ros/ros.h> #include <opencv2/opencv.hpp> int main(int argc, char** argv) { // ROS节点初始化 ros::init(argc, argv, "object_detection_node"); ros::NodeHandle nh; // 摄像头初始化 cv::VideoCapture cap(0); // 物体检测模型初始化 cv::CascadeClassifier object_cascade; object_cascade.load("path/to/object/cascade.xml"); while(ros::ok()) { // 读取摄像头图像 cv::Mat frame; cap >> frame; // 物体检测 std::vector<cv::Rect> objects; object_cascade.detectMultiScale(frame, objects); // 显示检测结果 for(int i=0; i<objects.size(); i++) { cv::rectangle(frame, objects[i], cv::Scalar(0,0,255), 2); } cv::imshow("Object Detection", frame); // 判断是否击倒目标物体 // 如果是,向小车控制器发送指令 // ... // 等待按键退出 if(cv::waitKey(1) == 'q') { break; } } // 释放资源 cap.release(); cv::destroyAllWindows(); return 0; } ``` 需要注意的是,这只是一个简单的框架,您需要根据您的具体情况进行修改和完善。另外,物体检测算法的选择也非常重要,您需要根据您的应用场景和硬件特性进行选择。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值