吴忠躺衫网络科技有限公司

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

ROS部署PaddlePaddle的CV模型

新機器視覺 ? 來源:新機器視覺 ? 2023-10-20 17:02 ? 次閱讀

本篇博客應該是全網第一篇將ROS和PaddlePaddle做結合,并且手把手教基于python3部署的文章,目的是為了把ROS和Paddle Inference打通,方便大家基于飛槳做ROS+CV方面的任務!本文只是Demo,大家跑通該Demo后即可將自己的模型替換,實現你自己的創意~

快速體驗

paddle_inference_ros_demo

paddle_inference_ros_demo功能包是基于paddle_inference_ros開發的,幫助開發者快速體驗paddle_inference在ROS環境下的推理部署效果的功能包。可以直接進入該項目鏈接進行查看和快速體驗。

項目地址:

https://gitee.com/irvingao/paddle_inference_ros_demo

1.環境準備

(1)硬件平臺

Jetson nano(Jetson系列開發板配置和以下都相同)

Jetson系列基礎環境配置:

https://blog.csdn.net/qq_45779334/article/details/108611797

(2)軟件環境

  • Ubuntu18.04

  • python3.6.9

  • ROS Melodic

  • PaddlePaddle-gpu 2.1.1

PaddlePaddle:跑通Paddle inference Demo:

https://blog.csdn.net/qq_45779334/article/details/118611953

待Paddle inference GPU預測正常之后再將其遷移進ROS中。

2.編譯python3的cv_bridge

在ROS中想使用原生python3的Paddle Inference,最重要的就是需要重新編譯基于python3的cv_bridge,只有我們在編譯完成python3后,才能基于python3實現Paddle Inference目標檢測、分類、分割等相關節點。

所以編譯基于python3的cv_bridge便是最基礎和最重要的一步,該博客詳細介紹了完整的編譯過程,按步驟進行操作即可成功。

ROS——基于Ubuntu18.04和ROS Melodic編譯python3的cv_bridge:

https://blog.csdn.net/qq_45779334/article/details/119641789

3.創建python3Paddle inference ROS節點

這里將以機器人開發中最常用的目標檢測為例,進行部署演示,大家可以自行修改代碼,完成分類、分割等任務的ROS節點。

(1)初始化paddle_ros_ws工作空間

mkdir -p paddle_ros_ws/src && cd paddle_ros_ws/src
catkin_init_workspace

(2)創建功能包

catkin_create_pkg py3_camera rospy rosmsg roscpp
catkin_create_pkg py3_infer rospy rosmsg roscpp

(3)編寫python圖像發布和paddle inference預測節點

①攝像頭發布節點

cd py3_camera && mkdir scripts
cd scripts && touch camera.py
chmod +x camera.py
cd ../..

camera.py

#!/usr/bin/env python3
# coding:utf-8


import cv2
import numpy as np
import rospy
from std_msgs.msg import Header
from sensor_msgs.msg import Image
from cv_bridge import CvBridge , CvBridgeError
import time


if __name__=="__main__":
  import sys 
  print(sys.version) # 查看python版本
  capture = cv2.VideoCapture(0) # 定義攝像頭
  rospy.init_node('camera_node', anonymous=True) #定義節點
  image_pub=rospy.Publisher('/image_view/image_raw', Image, queue_size = 1) #定義話題


  while not rospy.is_shutdown():  # Ctrl C正常退出,如果異常退出會報錯device busy!
    start = time.time()
    ret, frame = capture.read()
    if ret: # 如果有畫面再執行
      # frame = cv2.flip(frame,0)  #垂直鏡像操作
      frame = cv2.flip(frame,1)  #水平鏡像操作  
  
      ros_frame = Image()
      header = Header(stamp = rospy.Time.now())
      header.frame_id = "Camera"
      ros_frame.header=header
      ros_frame.width = 640
      ros_frame.height = 480
      ros_frame.encoding = "bgr8"
      ros_frame.step = 1920
      ros_frame.data = np.array(frame).tostring() #圖片格式轉換
      image_pub.publish(ros_frame) #發布消息
      end = time.time() 
      print("cost time:", end-start ) # 看一下每一幀的執行時間,從而確定合適的rate
      rate = rospy.Rate(25) # 10hz 


  capture.release()
  cv2.destroyAllWindows() 
  print("quit successfully!")

②paddle inference目標檢測節點

cd py3_infer && mkdir scripts
cd scripts && touch pp_infer.py
chmod +x pp_infer.py

pp_infer.py

#!/usr/bin/env python3
# coding:utf-8


import cv2
import numpy as np


import rospy
from sensor_msgs.msg import Image
from cv_bridge import CvBridge, CvBridgeError


from paddle.inference import Config
from paddle.inference import PrecisionType
from paddle.inference import create_predictor
import yaml
import time


# ————————————————圖像預處理函數———————————————— #


def resize(img, target_size):
  """resize to target size"""
  if not isinstance(img, np.ndarray):
    raise TypeError('image type is not numpy.')
  im_shape = img.shape
  im_size_min = np.min(im_shape[0:2])
  im_size_max = np.max(im_shape[0:2])
  im_scale_x = float(target_size) / float(im_shape[1])
  im_scale_y = float(target_size) / float(im_shape[0])
  img = cv2.resize(img, None, None, fx=im_scale_x, fy=im_scale_y)
  return img


def normalize(img, mean, std):
  img = img / 255.0
  mean = np.array(mean)[np.newaxis, np.newaxis, :]
  std = np.array(std)[np.newaxis, np.newaxis, :]
  img -= mean
  img /= std
  return img


def preprocess(img, img_size):
  mean = [0.485, 0.456, 0.406]
  std = [0.229, 0.224, 0.225]
  img = resize(img, img_size)
  resize_img = img
  img = img[:, :, ::-1].astype('float32') # bgr -> rgb
  img = normalize(img, mean, std)
  img = img.transpose((2, 0, 1)) # hwc -> chw
  return img[np.newaxis, :], resize_img


# ——————————————————————模型配置、預測相關函數—————————————————————————— #
def predict_config(model_file, params_file):
  '''
  函數功能:初始化預測模型predictor
  函數輸入:模型結構文件,模型參數文件
  函數輸出:預測器predictor
  '''
  # 根據預測部署的實際情況,設置Config
  config = Config()
  # 讀取模型文件
  config.set_prog_file(model_file)
  config.set_params_file(params_file)
  # Config默認是使用CPU預測,若要使用GPU預測,需要手動開啟,設置運行的GPU卡號和分配的初始顯存。
  config.enable_use_gpu(400, 0)
  # 可以設置開啟IR優化、開啟內存優化。
  config.switch_ir_optim()
  config.enable_memory_optim()
  # config.enable_tensorrt_engine(workspace_size=1 << 30, precision_mode=PrecisionType.Float32,max_batch_size=1, min_subgraph_size=5, use_static=False, use_calib_mode=False)
  predictor = create_predictor(config)
  return predictor


def predict(predictor, img):
  
  '''
  函數功能:初始化預測模型predictor
  函數輸入:模型結構文件,模型參數文件
  函數輸出:預測器predictor
  '''
  input_names = predictor.get_input_names()
  for i, name in enumerate(input_names):
    input_tensor = predictor.get_input_handle(name)
    input_tensor.reshape(img[i].shape)
    input_tensor.copy_from_cpu(img[i].copy())
  # 執行Predictor
  predictor.run()
  # 獲取輸出
  results = []
  # 獲取輸出
  output_names = predictor.get_output_names()
  for i, name in enumerate(output_names):
    output_tensor = predictor.get_output_handle(name)
    output_data = output_tensor.copy_to_cpu()
    results.append(output_data)
  return results


# ——————————————————————后處理函數—————————————————————————— #
def draw_bbox_image(frame, result, label_list, threshold=0.5):
  
  for res in result:
    cat_id, score, bbox = res[0], res[1], res[2:]
    if score < threshold:
     continue
    xmin, ymin, xmax, ymax = bbox
    cv2.rectangle(frame, (int(xmin), int(ymin)), (int(xmax), int(ymax)), (255,0,255), 2)
    label_id = label_list[int(cat_id)]
    print('label is {}, bbox is {}'.format(label_id, bbox))
    try:
      # #cv2.putText(圖像, 文字, (x, y), 字體, 大小, (b, g, r), 寬度)
      cv2.putText(frame, label_id, (int(xmin), int(ymin-2)), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255,0,0), 2)
      cv2.putText(frame, str(round(score,2)), (int(xmin-35), int(ymin-2)), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,255,0), 2)
    except KeyError:
      pass


def callback(data):
  global bridge, predictor, im_size, im_shape, scale_factor, label_list
  cv_img = bridge.imgmsg_to_cv2(data, "bgr8")
  img_data, cv_img = preprocess(cv_img, im_size)    
  # 預測
  result = predict(predictor, [im_shape, img_data, scale_factor])
  draw_bbox_image(cv_img, result[0], label_list, threshold=0.1)
  cv2.imshow("cv_img", cv_img)


  cv2.waitKey(1)


if __name__ == '__main__':
  import sys 
  print(sys.version) # 查看python版本
  
  # 初始化節點
  rospy.init_node('ppinfer_node', anonymous=True)
  bridge = CvBridge()


  # 模型文件路徑(最好寫絕對路徑)
  model_dir = '/home/nano/workspace/paddle_ros_ws/src/py3_infer/scripts/yolov3_r50vd_dcn_270e_coco/'
  # 從infer_cfg.yml中讀出label
  infer_cfg = open(model_dir + 'infer_cfg.yml')
  data = infer_cfg.read()
  yaml_reader = yaml.load(data)
  label_list = yaml_reader['label_list']
  print(label_list)


  # 配置模型參數
  model_file = model_dir + "model.pdmodel"
  params_file = model_dir + "model.pdiparams"
  
  # 圖像尺寸相關參數初始化
  try:
    img = bridge.imgmsg_to_cv2(data, "bgr8")
  except AttributeError:
    img = np.zeros((224,224,3), np.uint8)
  im_size = 224
  scale_factor = np.array([im_size * 1. / img.shape[0], im_size * 1. / img.shape[1]]).reshape((1, 2)).astype(np.float32)
  im_shape = np.array([im_size, im_size]).reshape((1, 2)).astype(np.float32)


  # 初始化預測模型
  predictor = predict_config(model_file, params_file)


  rospy.Subscriber('/image_view/image_raw', Image, callback)


  rospy.spin()

準備模型文件

wget https://paddle-inference-dist.bj.bcebos.com/Paddle-Inference-Demo/yolov3_r50vd_dcn_270e_coco.tgz &&tar xzf yolov3_r50vd_dcn_270e_coco.tgz

87e3b4a0-6f26-11ee-939d-92fbcf53809c.png

4.在ROS中運行Paddle Inference節點

(1)編譯

cd ../../..
catkin_make -DPYTHON_EXECUTABLE=/usr/bin/python3

87ef56ca-6f26-11ee-939d-92fbcf53809c.png

(2)將工作空間添加進環境變量

sudo vim ~/.bashrc
source /home/nano/workspace/paddle_ros_ws/devel/setup.bash

(3)運行節點

roscore
rosrun py3_camera camera.py
rosrun py3_infer pp_infer.py

87fffdae-6f26-11ee-939d-92fbcf53809c.png

rosrun rqt_iamge_view rqt_iamge_view

(4)運行成功示意圖

8816dcfe-6f26-11ee-939d-92fbcf53809c.png


聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • CV
    CV
    +關注

    關注

    0

    文章

    53

    瀏覽量

    16906
  • 模型
    +關注

    關注

    1

    文章

    3305

    瀏覽量

    49220
  • ROS
    ROS
    +關注

    關注

    1

    文章

    280

    瀏覽量

    17095

原文標題:ROS部署PaddlePaddle的CV模型

文章出處:【微信號:vision263com,微信公眾號:新機器視覺】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    使用CUBEAI部署tflite模型到STM32F0中,模型創建失敗怎么解決?

    看到CUBE_AI已經支持到STM32F0系列芯片,就想拿來入門嵌入式AI。 生成的模型很小,是可以部署到F0上的,但是一直無法創建成功。 查閱CUBE AI文檔說在調用create函數前,要啟用
    發表于 03-15 08:10

    PaddlePaddle Fluid版本的PaddlePaddle如何保存模型

    PaddlePaddle Fluid版本的PaddlePaddle如何在訓練前加載此前訓練好的模型
    發表于 04-15 11:19

    PaddlePaddle Fluid版PaddlePaddle加載圖像數據出錯解決方案

    PaddlePaddle Fluid版的PaddlePaddle加載圖像數據報錯
    發表于 04-18 09:22

    PaddlePaddle使用預測模型預測圖片報錯及解決方法

    PaddlePaddle使用預測模型預測圖片時出現輸出數據維度錯誤
    發表于 05-31 09:39

    介紹在STM32cubeIDE上部署AI模型的系列教程

    介紹在STM32cubeIDE上部署AI模型的系列教程,開發板型號STM32H747I-disco,值得一看。MCUAI原文鏈接:【嵌入式AI開發】篇四|部署篇:STM32cubeIDE上部署
    發表于 12-14 09:05

    基于micropython的STM32單片機編程

    因為一直想去從零開始完全手寫代碼做一個ROS機器人,同時目前手里會的技能有基于micropython的STM32單片機編程、基于python的ROS學習基礎,再多一點就是基于PaddlePaddle
    發表于 01-14 07:01

    RV1126 PaddlePaddle編譯環境的搭建

    參照官方 API 文檔進行開發了。需要注意的是模型訓練轉換還是需要用 PaddlePaddle 在電腦上完成,PaddleLite 是裁剪版只能在設備端進行推理使用。原作者:板藍根
    發表于 06-06 17:26

    如何用Arm虛擬硬件在Arm Cortex-M上部署PaddlePaddle

    目突出了 Arm 和百度之間的合作,填補了之前在 Arm Cortex-M 上直接部署 PaddlePaddle 模型的工作流程中的空白。這增加了Cortex-M 上支持的深度學習模型
    發表于 09-02 14:48

    通過Cortex來非常方便的部署PyTorch模型

    到軟件中。如何從“跨語言語言模型”轉換為谷歌翻譯?在這篇博客文章中,我們將了解在生產環境中使用 PyTorch 模型意味著什么,然后介紹一種允許部署任何 PyTorch 模型以便在軟件
    發表于 11-01 15:25

    部署基于嵌入的機器學習模型

    1、如何在生產中部署基于嵌入的機器學習模型  由于最近大量的研究,機器學習模型的性能在過去幾年里有了顯著的提高。雖然這些改進的模型開辟了新的可能性,但是它們只有在可以
    發表于 11-02 15:09

    基于深度學習模型的點云目標檢測及ROS實現

    近年來,隨著深度學習在圖像視覺領域的發展,一類基于單純的深度學習模型的點云目標檢測方法被提出和應用,本文將詳細介紹其中一種模型——SqueezeSeg,并且使用ROS實現該模型的實時目
    的頭像 發表于 11-05 16:47 ?1.8w次閱讀

    使用OpenVINO? 部署PaddleSeg模型庫中的DeepLabV3+模型

    ? ? ? 01 概述 ? ? 本文是OpenVINO 工具套件與百度飛槳PaddlePaddle模型轉換/部署系列的第二部。這篇文章專注于展示如何將百度飛槳PaddelSeg項目
    的頭像 發表于 11-22 14:58 ?9951次閱讀
    使用OpenVINO? <b class='flag-5'>部署</b>PaddleSeg<b class='flag-5'>模型</b>庫中的DeepLabV3+<b class='flag-5'>模型</b>

    實現ARM+ROS(機器人操作系統)之運行ROS

    如何低成本搭建ARM+ROS的硬件載體?上文展示ROS部署前的籌備工作及步驟分解,本文將為大家演示ROS的移植及測試方法。
    的頭像 發表于 10-10 18:15 ?1303次閱讀
    實現ARM+<b class='flag-5'>ROS</b>(機器人操作系統)之運行<b class='flag-5'>ROS</b>!

    ros1和ros2的通信模型

    ros1: talker 注冊 listener 注冊 ROS Master 進行信息匹配 listener 發送鏈接請求 talker 確認請求 建立連接 talker 給 listener 發
    的頭像 發表于 11-27 11:26 ?872次閱讀
    <b class='flag-5'>ros</b>1和<b class='flag-5'>ros</b>2的通信<b class='flag-5'>模型</b>

    機器人的ROS模型建立

    這個系列主要介紹機器人ROS模型的建立方法,ROS系統帶來的好處之一就是: 我們無需自己建立復雜的數學模型來描述自己的機器人幾何尺寸、運動學和動力學等,只需要用它提供的
    的頭像 發表于 11-28 14:19 ?655次閱讀
    澳门赌盘| 上海玩百家乐官网算不算违法 | 香港百家乐官网赌场娱乐网规则 | 百家乐打印机破解| 高手百家乐赢钱法| 最佳场百家乐官网的玩法技巧和规则 | 516棋牌游戏中心| 威尼斯人娱乐网赌| 百家乐扑克多少张| 百家乐视频官方下载| 三国百家乐官网娱乐城| 任我赢百家乐官网软件| 百家乐官网怎么赢博彩正网| 线上百家乐官网可靠吗| 阜宁县| 澳门博彩网| 大发888棋牌| 尊龙百家乐娱乐场开户注册| 玩百家乐新太阳城| 百家乐娱乐官方网| 有看做生意风水的大师吗| 真人百家乐官网斗地主| 百家乐官网游戏客户端| 带有百家乐官网的棋牌游戏有哪些| 百家乐官网规则博彩正网| 百家乐官网五局八星| 顺义区| 大兴区| 百家乐官网发牌的介绍| 网上百家乐官网危险| 香港六合彩开奖结果| 盈禾娱乐城| 菲彩国际| 伟易博| 在线棋牌| 巨野县| 免费百家乐官网奥秘| 威尼斯人娱乐备用622| 真人游戏豆瓣| 大发888娱乐游戏博彩| 大发888黄金版下载|