###### tags: `Construction` ## 示意圖 ![](https://hackmd.io/_uploads/ry0neBA9h.png) ## 推流 ```bash= $ gst-launch-1.0 -v v4l2src device=/dev/video0 ! video/x-raw,format=YUY2,width=1280,height=720,framerate=10/1 ! videoconvert ! x264enc bitrate=2000 ! h264parse ! flvmux ! rtmpsink location=rtmp://192.168.0.126:1935/live/stream $ gst-launch-1.0 -v v4l2src device=/dev/video0 ! videoconvert ! videoscale ! video/x-raw,width=640,height=480 ! x264enc tune=zerolatency bitrate=1500 key-int-max=30 ! mpegtsmux ! udpsink host=192.168.0.152 port=1935 ``` 檢查 ```cpp= $ cd /usr/local/nginx/html/hls ``` ## 小小解釋 名詞解釋 Web Server,他對於PC iPhone這些請求者他是Server,但對每個樹梅派(獲取畫面)Web Server同時也是Client,對其他樹梅派請求畫面,是對Server(樹梅派)來請求。 但為了避免搞混,統稱Web Server 為 Server,有畫面的樹梅派是Client。 ### 設定這個 Web Server 樹梅派需要先安裝 NGINX。 目前是在處理這裡 ![](https://hackmd.io/_uploads/B1hV8S052.png) 1. 安裝所需的依賴: 首先,您需要安裝一些必要的Requirement。 ```c++= # bash 終端機畫面 sudo apt update && sudo apt upgrade -y sudo apt install nginx -y ``` 2. 下載NGINX和RTMP模組: ```c++= # bash 下載並且解壓縮 cd ~ wget http://nginx.org/download/nginx-1.18.0.tar.gz tar -zxvf nginx-1.18.0.tar.gz git clone https://github.com/arut/nginx-rtmp-module.git ``` 3. 編譯和安裝: ```c++= # bash 新增必要rtmp模組 沒有NGINX他無法認出RTMP的串流 進而無法處理 如果編譯出錯 可以先試試安裝這個 sudo apt-get update sudo apt-get install libpcre3 libpcre3-dev sudo apt-get install libssl-dev cd nginx-1.18.0 ./configure --with-http_ssl_module --add-module=../nginx-rtmp-module make sudo make install ``` 4. 配置NGINX以支持RTMP和HLS: 編輯NGINX的配置文件: ```c++= # bash 開啟編輯文字工具修改NGINX conf參數 要讓他把RTMP的串流轉向成HLS (m3u8描述檔) sudo nano /usr/local/nginx/conf/nginx.conf 或 sudo vim /usr/local/nginx/conf/nginx.conf ``` 在http部分,加入HLS配置: ```javascript!= # 原始檔案 會有很多註解掉的功能都不要管 http { server { listen 80; # HTTP port server_name 192.168.0.126; # 替換為你的Domain IP location / { root /usr/local/nginx/html; index index.html; #這個index.html 要放在/usr/local/nginx/html 底下 } # 增加HLS播放路径 location /hls { types { application/vnd.apple.mpegurl m3u8; video/mp2t ts; } root /usr/local/nginx/html; add_header Cache-Control no-cache; add_header Access-Control-Allow-Origin *; # 允許跨域訪問 } } } ``` 在文件的底部,加入RTMP配置: ```javascript!= rtmp { server { listen 1935; chunk_size 4096; application live { live on; record off; hls on; hls_path /tmp/hls; #最後你需要確認你的本機有這個資料夾否則會無法寫入 hls_fragment 5s; # HLS切片时长 hls_playlist_length 30s; # HLS播放列表时长 } } } ``` 保存並退出編輯器。 5. 啟動NGINX: ```bash!= sudo /usr/local/nginx/sbin/nginx ``` 或是您已經安裝好並且已經運行了 那可以重新reload。 ```bash!= sudo /usr/local/nginx/sbin/nginx -s reload sudo /usr/local/nginx/sbin/nginx -s stop ``` ### 設定個別裝有CAM的Rpi 樹梅派需要安裝 FFmpeg。 6. 推流到NGINX: 使用OBS或其他任何RTMP源,設置您的推流URL為: ```bash!= rtmp://[你的樹梅派IP]/live/[流名稱] ``` 例如使用OBS 我就會把URL填入rtmp://192.168.0.126/live/ 金鑰填 stream 其中192.168.0.126是我Web Server的本機IP,通常不會一樣所以要記得改ㄛ。 如果是停車位旁邊的樹梅派,就使用ffmpeg推流,只要確保ffmpeg有正常安裝,並且推h264的串流給Web Server,就可以在第7步看到畫面了。 ffmpeg 我覺得類似 OBS,可以這樣去理解他。 7. 觀看串流: 您可以使用VLC或其他HLS支持的播放器,並打開以下URL來觀看流: ```bash= http://[你的樹梅派IP]/hls/[流名稱].m3u8 ``` 8. 小小說明 說明一下 NGINX 如果不懂原理可以看一下這個,他是一個反向代理的伺服器,當然他也可以作為一個HTTP的伺服器。 想像一下你去一家餐廳吃飯,這家餐廳特別忙碌,所以他們有一名「接待員」站在門口幫你接受訂單,然後再將你的訂單轉告給內部的廚師。在這個情境中,「接待員」其實就像是 NGINX 反向代理伺服器。 隱藏內部結構:就像你不需要知道餐廳有幾位廚師,或他們如何工作,反向代理會隱藏你的內部伺服器結構,使外部用戶只知道反向代理的存在。 負載平衡:如果餐廳內有多位廚師,接待員可以根據各位廚師的忙碌程度,決定將訂單給哪位廚師。同理,當有很多伺服器時,NGINX 可以根據伺服器的負載情況,將用戶的請求導向最適合的伺服器。 加速內容遞送:接待員可能已經知道某些客人常點的餐點,所以他們可以預先準備,從而更快地提供給客人。同樣地,NGINX 可以快取某些內容,當用戶請求這些內容時,可以直接從快取中取得,而不需要重新從伺服器取得。 安全性:如果有些客人的行為不太好,接待員可以決定不讓他們進入餐廳。反向代理也提供類似的功能,如防止惡意攻擊、限制某些請求等。 所以,總結一下,NGINX 反向代理伺服器就像是餐廳的接待員,他站在你的伺服器和用戶之間,幫忙接收和處理用戶的請求,並且提供了許多其他的功能和優點。 這樣就完成惹。 ## YOLO detection ### Installation ```bash= ## All the installation done in this video are given below: ## 1. Download yolov5 repository $ git clone https://github.com/ultralytics/yolov5 ## 2.Installing cv2 $ pip3 install opencv-python ## 3. To fix, import error: libcblas.so.3: cannot open shared object file: No such file or directory $ sudo apt-get install libatlas-base-dev ## 4. To fix, no module name: tqdm $ pip3 install tqdm ## 5. To fix, no module name: yaml $ pip3 install pyyaml ## 6. To fix, no module name: matplotlib $ pip3 install matplotlib ## 7. To fix no module name: pandas $ pip3 install pandas ## 8. To fix no module name: seaborn $ pip3 install seaborn ## 9. DistributionNotFound: The 'pycocotools ]=2.0' distribution was not found and is required by the application $ pip3 install cython $ pip3 install git+https://github.com/waleedka/coco.git#... ## 10. DistributionNotFound: The 'thop' distribution was not found and is required by the application $ pip3 install thop ## Execute $ python3 detect.py --source data/images --weight yolov5s.pt --conf 0.25 $ python3 detect.py --source 0 --weight yolov5s.pt --conf 0.25 ``` ### Result ![](https://hackmd.io/_uploads/SJw7_Syla.png) ![](https://hackmd.io/_uploads/SJ1HuSJl6.png) ![](https://hackmd.io/_uploads/Syzs_Pgga.png) ## Custom object https://core-electronics.com.au/guides/object-identify-raspberry-pi/ ```bash= $ sudo apt-get install build-essential cmake pkg-config $ sudo apt-get install libjpeg-dev libtiff5-dev libjasper-dev libpng12-dev $ sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev $ sudo apt-get install libxvidcore-dev libx264-dev $ sudo apt-get install libgtk2.0-dev libgtk-3-dev $ sudo apt-get install libatlas-base-dev gfortran $ sudo pip3 install numpy $ wget -O opencv.zip https://github.com/opencv/opencv/archive/4.4.0.zip $ wget -O opencv_contrib.zip https://github.com/opencv/opencv_contrib/archive/4.4.0.zip $ unzip opencv.zip $ unzip opencv_contrib.zip $ cd ~/opencv-4.4.0/ $ mkdir build $ cd build $ cmake -D CMAKE_BUILD_TYPE=RELEASE \ -D CMAKE_INSTALL_PREFIX=/usr/local \ -D INSTALL_PYTHON_EXAMPLES=ON \ -D OPENCV_EXTRA_MODULES_PATH=~/opencv_contrib-4.4.0/modules \ -D BUILD_EXAMPLES=ON .. $ make -j $(nproc) $ sudo make install && sudo ldconfig ## Download Attachment - Object_Detection_Files.zip $ unzip Object_Detection_Files.zip $ python3 object-ident-2.py ``` ### object-ident-2.py code ```bash= import cv2 #thres = 0.45 # Threshold to detect object classNames = [] classFile = "/home/eric/test/Object_Detection_Files/coco.names" with open(classFile,"rt") as f: classNames = f.read().rstrip("\n").split("\n") configPath = "/home/eric/test/Object_Detection_Files/ssd_mobilenet_v3_large_coco_2020_01_14.pbtxt" weightsPath = "/home/eric/test/Object_Detection_Files/frozen_inference_graph.pb" net = cv2.dnn_DetectionModel(weightsPath,configPath) net.setInputSize(320,320) net.setInputScale(1.0/ 127.5) net.setInputMean((127.5, 127.5, 127.5)) net.setInputSwapRB(True) def getObjects(img, thres, nms, draw=True, objects=[]): classIds, confs, bbox = net.detect(img,confThreshold=thres,nmsThreshold=nms) #print(classIds,bbox) if len(objects) == 0: objects = classNames objectInfo =[] if len(classIds) != 0: for classId, confidence,box in zip(classIds.flatten(),confs.flatten(),bbox): className = classNames[classId - 1] if className in objects: objectInfo.append([box,className]) if (draw): cv2.rectangle(img,box,color=(0,255,0),thickness=2) cv2.putText(img,classNames[classId-1].upper(),(box[0]+10,box[1]+30), cv2.FONT_HERSHEY_COMPLEX,1,(0,255,0),2) cv2.putText(img,str(round(confidence*100,2)),(box[0]+200,box[1]+30), cv2.FONT_HERSHEY_COMPLEX,1,(0,255,0),2) return img,objectInfo if _name_ == "__main__": cap = cv2.VideoCapture(0) cap.set(3,640) cap.set(4,480) #cap.set(10,70) while True: success, img = cap.read() result, objectInfo = getObjects(img,0.45,0.2, objects=['cup']) #print(objectInfo) cv2.imshow("Output",img) cv2.waitKey(1) ``` https://blog.csdn.net/weixin_43694096/article/details/127815800