無人機之眼 | ROS圖像RTMP協議推流到地面站,CPU表示軟件解碼

一、Nginx服務器搭建

因爲要將處理過的圖片串成rtmp碼流,因此,需要搭建一個rtmp服務器,常用的方案是Nginx服務器。

1.1 安裝依賴

sudo apt-get update
sudo apt-get install -y openssl libssl-dev libpcre3 libpcre3-dev zlib1g-dev 
sudo apt-get install -y autoconf automake build-essential git libass-dev libfreetype6-dev libsdl2-dev libtheora-dev libtool libva-dev libvdpau-dev libvorbis-dev libxcb1-dev libxcb-shm0-dev libxcb-xfixes0-dev pkg-config texinfo wget zlib1g-dev
sudo apt-get install -y ffmpeg

1.2 編譯源碼

  • 在工作空間下,新建一個nginx文件夾,用來存放需要下載nginx和nginx-rtmp-module兩個安裝包源碼。
  • nginx下載鏈接,nginx-rtmp-module下載鏈接。
  • 解壓文件,生成nginx-1.18.0文件夾,生成nginx-rtmp-module文件夾。
  • 然後編譯安裝nginx,cd進nginx的目錄。
cd nginx-1.18.0
./configure --add-module=../nginx-rtmp-module
make -j4
sudo make install

1.3 測試nginx

直接運行以下命令:

sudo /usr/local/nginx/sbin/nginx

在瀏覽器中輸入localhost:80(或者服務器的IP),看到如下畫面,表示安裝成功。

無人機之眼 | ROS圖像RTMP協議推流到地面站,CPU表示軟件解碼

1.4 配置

編輯 /usr/local/nginx/conf/nginx.conf文件()。sudo gedit /usr/local/nginx/conf/nginx.conf

#user  nobody;
worker_processes  1;
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;
#pid        logs/nginx.pid;
events {
    worker_connections  1024;
}
rtmp {            
    server {
        listen 1935;  # 服務端口--默認
        chunk_size 4096;   # 數據傳輸塊的大小--默認
        # 設置直播的application名稱是live
        application live { 
            live on; # live on表示開啓直播模式
        }
    }
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';
    #access_log  logs/access.log  main;
    sendfile        on;
    #tcp_nopush     on;
    #keepalive_timeout  0;
    keepalive_timeout  65;
    #gzip  on;
    server {
        listen       80;
        server_name  localhost;
        #charset koi8-r;
        #access_log  logs/host.access.log  main;
        location / {
            root   html;
            index  index.html index.htm;
        }
        location /info {
            rtmp_stat all;
            rtmp_stat_stylesheet stat.xsl;
        }
        location /stat.xsl {
            root html;
        }
        #error_page  404              /404.html;
        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

配置完之後,需要重啓nginx:

sudo cp nginx-rtmp-module/stat.xsl /usr/local/nginx/html/
sudo /usr/local/nginx/sbin/nginx -s reload

然後在瀏覽器中輸入localhost:80/info可看到如下畫面:

無人機之眼 | ROS圖像RTMP協議推流到地面站,CPU表示軟件解碼

至此,完成了rtmp-nginx服務器的全部配置。

1.5 讓系統啓動時自動加載nginx服務

  • 首先需要安裝sysv-rc-conf:
sudo apt-get update
apt install sysv-rc-conf
  • 設置nginx開機啓動:

先爲nginx在下創建一個啓動腳本/etc/init.d/

gedit /etc/init.d/nginx

添加內容如下:

#! /bin/sh
# chkconfig: 2345 55 25
# Description: Startup script for nginx webserver on Debian. Place in /etc/init.d and
# run 'update-rc.d -f nginx defaults', or use the appropriate command on your
# distro. For CentOS/Redhat run: 'chkconfig --add nginx'
### BEGIN INIT INFO
# Provides:          nginx
# Required-Start:    $all
# Required-Stop:     $all# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: starts the nginx web server
# Description:       starts nginx using start-stop-daemon
### END INIT INFO
# Author:   licess
# website:  http://lnmp.org
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
NAME=nginx
NGINX_BIN=/usr/local/nginx/sbin/$NAME
CONFIGFILE=/usr/local/nginx/conf/$NAME.conf
PIDFILE=/usr/local/nginx/logs/$NAME.pid
case "$1" in
    start)        echo -n "Starting $NAME... "
  
        if netstat -tnpl | grep -q nginx;then
            echo "$NAME (pid `pidof $NAME`) already running."
            exit 1   
        fi
    
        $NGINX_BIN -c $CONFIGFILE
    
        if [ "$?" != 0 ] ; then
            echo " failed"
            exit 1        else
            echo " done"
        fi
        ;;


    stop)    
       echo -n "Stoping $NAME... "


        if ! netstat -tnpl | grep -q nginx; then
            echo "$NAME is not running."
            exit 1   
        fi


        $NGINX_BIN -s stop    
    
        if [ "$?" != 0 ] ; then
            echo " failed. Use force-quit"
            exit 1   
        else
            echo " done"
        fi
        ;;


    status)    
        if netstat -tnpl | grep -q nginx; then
            PID=`pidof nginx`
            echo "$NAME (pid $PID) is running..."
        else
            echo "$NAME is stopped"
            exit 0        fi
        ;;


    force-quit)    
        echo -n "Terminating $NAME... "


        if ! netstat -tnpl | grep -q nginx; then
            echo "$NAME is not running."
            exit 1    
        fi


        kill `pidof $NAME`


        if [ "$?" != 0 ] ; then
            echo " failed"
            exit 1   
        else
            echo " done"
        fi
        ;;


    restart)    
        $0 stop
        sleep 1   
        $0 start
        ;;


    reload)        echo -n "Reload service $NAME... "


        if netstat -tnpl | grep -q nginx; then
            $NGINX_BIN -s reload        
            echo " done"
        else
            echo "$NAME is not running, can't reload."
            exit 1    
        fi
        ;;


    configtest)   
        echo -n "Test $NAME configure files... "


        $NGINX_BIN -t
        ;;   
    
    *)    
        echo "Usage: $0 {start|stop|force-quit|restart|reload|status|configtest}"
        exit 1
        ;;
esac
  • 保存成功之後我們要對這個管理腳本設置一個權限:
chmod +x /etc/init.d/nginx
  • 接下來我們可以看看這個腳本能否正確執行:
/etc/init.d/nginx restart

這個管理腳本支持的命令有start|stop|force-quit|restart|reload|status|configtest。

  • 如果沒有錯誤能正確執行,那我們可以開始把他加入啓動項了:
sysv-rc-conf --list    # 我們先查看一下list中有沒有我們剛剛加進去的這個nginx管理腳本
sysv-rc-conf nginx on  # 然後用這個命令添加開機自啓動

二、運行Prometheus推流示例程序(Python編寫)

運行如下命令:

roslaunch prometheus_detection web_cam0.launch     # 打開一個usb攝像頭0
roslaunch prometheus_detection rtmp_stream.launch  # 開始推流

具體的Python推流代碼如下(位置在):

Prometheus/Modules/object_detection/py_nodes/rtmp_stream/ocv_rtmp_stream.py#!/usr/bin/env python
# -*- coding: utf-8 -*-
import rospy
from sensor_msgs.msg import Image
from geometry_msgs.msg import Pose, Point, Quaternion
from cv_bridge import CvBridge
from std_msgs.msg import String
from std_msgs.msg import Bool
import numpy as np
import cv2
import subprocess
import os
import yaml
import math
rospy.init_node('rtmp_stream', anonymous=True)
rtmp = r'rtmp://localhost:1935/live'
size_str = str(640) + 'x' + str(400)
command = ['ffmpeg',    '-y', '-an',    '-f', 'rawvideo',    '-vcodec','rawvideo',    '-pix_fmt', 'bgr24',    '-s', size_str,    '-r', '25',    '-i', '-',    '-c:v', 'libx264',    '-pix_fmt', 'yuv420p',    '-preset', 'ultrafast',    '-f', 'flv',    rtmp]
pipe = subprocess.Popen(  
  command,  
  shell=False,  
  stdin=subprocess.PIPE
  )
  
  def image_callback(imgmsg):  
       bridge = CvBridge()  
       frame = bridge.imgmsg_to_cv2(imgmsg, "bgr8")  
       # processing
       # end


       h, w = frame.shape[:2]  
       img_resize = 400
       if h > w:    
       h = int(float(h) / w * img_resize)   
       w = img_resize
       else:    
       w = int(float(w) / h * img_resize)    
       h = img_resize
       frame = cv2.resize(frame, (w, h))  
       frame = frame[:, :640, :]  
       pipe.stdin.write(frame.tostring())  
       cv2.imshow("cap", frame)  
       # cv2.imshow("area", area)
       cv2.waitKey(10)
   
def rtmp_stream(topic_name):  
     rospy.Subscriber(topic_name, Image, image_callback)  
     rospy.spin()
   
if __name__ == '__main__':  
     subscriber = rospy.get_param('~camera_topic', '/prometheus/camera/rgb/image_raw')  
   
     try:   
         rtmp_stream(subscriber)   
     except rospy.ROSInterruptException:   
         pass


     pipe.terminate()
  • End -

技術發展的日新月異,阿木實驗室將緊跟技術的腳步,不斷把機器人行業最新的技術和硬件推薦給大家。看到經過我們培訓的學員在技術上突飛猛進,是我們培訓最大的價值。如果你在機器人行業,就請關注我們的公衆號,我們將持續發佈機器人行業最有價值的信息和技術。 阿木實驗室致力於爲機器人研發提供開源軟硬件工具和課程服務,讓研發更高效!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章