nginx + ffmpeg 實現 rtsp視頻實時播放和歷史播放

nginx和ffmpeg 的安裝請參考我的另一篇文章

Nginx+rtmp+ffmpeg搭建視頻轉碼服務_nginx-rtmp-module-master-CSDN博客

目錄

1、整體方案設計如圖

2、nginx下目錄創建和配置文件創建

3、創建視頻流生成腳本

4、修改nginx配置

5、管理界面 (video.html)

6、ffmpeg后臺啟動

方案1:使用nohup和后臺運行

6.1啟動腳本編寫

6.2停止腳本編寫

方案2:使用systemd服務(推薦生產環境使用)


1、整體方案設計如圖

其中config下是視頻配置文件,live存放視頻實時流,archive存放視頻歷史流

2、nginx下目錄創建和配置文件創建

cd /usr/local/nginx/html
mkdir streams
cd streams
mkdir config
vi cameras.json在json文件中填充如下內容{"cameras": [{"id": "zl","rtsp": "rtsp://admin:123456@172.168.2.11:554/Streaming/Channels/101","name": "走廊監控"},{"id": "blm","rtsp": "rtsp://admin:123456@172.168.2.11:554/Streaming/Channels/201","name": "玻璃門監控"},{"id": "cg","rtsp": "rtsp://admin:123456@172.168.2.11:554/Streaming/Channels/301","name": "采購監控"},{"id": "yf","rtsp": "rtsp://admin:123456@172.168.2.11:554/Streaming/Channels/401","name": "研發監控"},{"id": "qt","rtsp": "rtsp://admin:123456@172.168.2.11:554/Streaming/Channels/501","name": "前臺監控"}],"hls_time": 2,"max_archive_hours": 24,"live_segments": 2
}

? ? 1:"hls_time": 2,#每個切片時長 2s
? ? 2:"max_archive_hours": 24,#歷史數據保留24小時

? ? 3:live_segments?指定播放列表(m3u8文件)中保留的最新TS視頻分片數量

? ? 3.1:當設置為5時:

  • 播放列表始終保留最新的5個TS分片

  • 當第6個分片生成時,最舊的分片會被移除

  • 例如:segment_001.ts 到 segment_005.ts → 新分片產生 → segment_002.ts 到 segment_006.ts

? ? 3.2:計算公式

  • 實時流延遲 ≈?live_segments?×?hls_time

  • 上面示例:5 × 2秒 = 約10秒延遲

3、創建視頻流生成腳本

創建start_streams.sh腳本vi start_streams.sh在腳本中填充如下內容#!/bin/bashCONFIG_FILE="/usr/local/nginx/html/streams/config/cameras.json"
STREAMS_DIR="/home/streams"  #流媒體存儲目錄
#STREAMS_DIR="/usr/local/nginx/html/streams"
NGINX_USER="nginx"                   # Nginx運行用戶# 創建目錄并設置權限
mkdir -p $STREAMS_DIR/{live,archive}
chown -R $NGINX_USER:$NGINX_USER $STREAMS_DIR
chmod -R 755 $STREAMS_DIR# 讀取配置
CAMERAS=$(jq -r '.cameras[] | .id' $CONFIG_FILE)
HLS_TIME=$(jq -r '.hls_time' $CONFIG_FILE)
MAX_HOURS=$(jq -r '.max_archive_hours' $CONFIG_FILE)
LIVE_SEGMENTS=$(jq -r '.live_segments' $CONFIG_FILE)# 為每個攝像頭啟動FFmpeg進程
for CAMERA in $CAMERAS; doRTSP_URL=$(jq -r --arg id "$CAMERA" '.cameras[] | select(.id==$id) | .rtsp' $CONFIG_FILE)# 創建目錄mkdir -p $STREAMS_DIR/live/$CAMERAmkdir -p $STREAMS_DIR/archive/$CAMERA# 啟動實時流ffmpeg -i "$RTSP_URL" \-c copy \-f hls \-hls_time $HLS_TIME \-hls_list_size $LIVE_SEGMENTS \-hls_flags delete_segments \-hls_segment_filename "$STREAMS_DIR/live/$CAMERA/segment_%03d.ts" \"$STREAMS_DIR/live/$CAMERA/live.m3u8" &# 啟動歷史流ffmpeg -i "$RTSP_URL" \-c copy \-f hls \-hls_time $HLS_TIME \-hls_list_size 0 \-hls_flags append_list \-hls_segment_filename "$STREAMS_DIR/archive/$CAMERA/%Y%m%d_%H%M%S.ts" \-strftime 1 \"$STREAMS_DIR/archive/$CAMERA/archive.m3u8" &
done# 定時清理舊歷史文件
while true; dofor CAMERA in $CAMERAS; dofind "$STREAMS_DIR/archive/$CAMERA" -name "*.ts" -mmin +$(($MAX_HOURS*60)) -deletedonesleep 3600  # 每小時清理一次
done

該腳本啟動時如果系統沒有安裝 jq,啟動腳本提示提示 jq: 未找到命令

需要安裝一下jq

wget https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64
mv jq-1.6 jq
chmod +x jq          # 添加可執行權限
sudo mv jq /usr/local/bin/  # 移動到系統路徑查看jq是否安裝成功
jq --version

腳本如果繼續執行報錯 這行報錯parse error: Invalid numeric literal
把json配置文件中的#注釋去掉

啟動腳本

4、修改nginx配置

nginx全局配置如下


#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;      #監聽的端口號application myapp {     #自定義的名字live on;  }  application hls {  live on;  hls on;  hls_path /tmp/hls;   hls_fragment 1s;hls_playlist_length 3s;  }  } 
}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 /live {#alias /usr/local/nginx/html/streams/live;#根據自己文視頻流生成的位置配置,我這邊因為要存歷史視頻,占用空間大,所以把視頻流放到/home/streams 目錄下去了alias /home/streams/live;types {application/vnd.apple.mpegurl m3u8;video/mp2t ts;}add_header Cache-Control no-cache;}# 歷史流訪問location /archive {#alias /usr/local/nginx/html/streams/archive;alias /home/streams/archive;types {application/vnd.apple.mpegurl m3u8;video/mp2t ts;}add_header Cache-Control no-cache;}# 配置API  訪問json配置文件location /api/cameras {alias /usr/local/nginx/html/streams/config/cameras.json;default_type application/json;}#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;}# proxy the PHP scripts to Apache listening on 127.0.0.1:80##location ~ \.php$ {#    proxy_pass   http://127.0.0.1;#}# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000##location ~ \.php$ {#    root           html;#    fastcgi_pass   127.0.0.1:9000;#    fastcgi_index  index.php;#    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;#    include        fastcgi_params;#}# deny access to .htaccess files, if Apache's document root# concurs with nginx's one##location ~ /\.ht {#    deny  all;#}}# another virtual host using mix of IP-, name-, and port-based configuration##server {#    listen       8000;#    listen       somename:8080;#    server_name  somename  alias  another.alias;#    location / {#        root   html;#        index  index.html index.htm;#    }#}# HTTPS server##server {#    listen       443 ssl;#    server_name  localhost;#    ssl_certificate      cert.pem;#    ssl_certificate_key  cert.key;#    ssl_session_cache    shared:SSL:1m;#    ssl_session_timeout  5m;#    ssl_ciphers  HIGH:!aNULL:!MD5;#    ssl_prefer_server_ciphers  on;#    location / {#        root   html;#        index  index.html index.htm;#    }#}}

配置完成后,啟動nginx

5、管理界面 (video.html)

自己通過一個html頁面查看視頻是否正常播放,或者通過流媒體播放軟件查看

video.html頁面內容如下

<!DOCTYPE html>
<html>
<head><title>多路視頻監控</title><!-- 替換為國內CDN -->
<script src="https://cdn.bootcdn.net/ajax/libs/hls.js/1.1.5/hls.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script><style>.video-container {display: inline-block;margin: 10px;vertical-align: top;}.video-title {text-align: center;font-weight: bold;}</style>
</head>
<body><h1>視頻監控系統</h1><div id="cameras-container"></div><script>$(document).ready(function() {// 獲取攝像頭列表$.getJSON("http://192.168.3.35/api/cameras", function(data) {const cameras = data.cameras;cameras.forEach(camera => {// 創建視頻容器const container = $(`<div class="video-container"><div class="video-title">${camera.name}</div><div><button onclick="playLive('${camera.id}')">實時</button><input type="datetime-local" id="${camera.id}-start"><input type="datetime-local" id="${camera.id}-end"><button onclick="playArchive('${camera.id}')">回放</button></div><video id="${camera.id}-video" controls width="640" height="360"></video></div>`);$("#cameras-container").append(container);// 默認播放實時視頻playLive(camera.id);});});});function playLive(cameraId) {const video = document.getElementById(`${cameraId}-video`);if(Hls.isSupported()) {const hls = new Hls();hls.loadSource(`/live/${cameraId}/live.m3u8`);hls.attachMedia(video);video.play();} else if (video.canPlayType('application/vnd.apple.mpegurl')) {video.src = `/live/${cameraId}/live.m3u8`;video.play();}}function playArchive(cameraId) {const start = document.getElementById(`${cameraId}-start`).value;const end = document.getElementById(`${cameraId}-end`).value;const video = document.getElementById(`${cameraId}-video`);// 簡單實現 - 實際項目中應該調用后端API篩選時間范圍if(Hls.isSupported()) {const hls = new Hls();hls.loadSource(`/archive/${cameraId}/archive.m3u8`);hls.attachMedia(video);video.play();}}</script>
</body>
</html>

在nginx html下面創建video文件夾,把video.html放進去,啟動nginx,訪問頁面內容如下

6、ffmpeg后臺啟動

上面的啟動腳本不是后臺啟動,關閉ssh連接后,服務會中斷,

方案1:使用nohup和后臺運行

6.1啟動腳本編寫

注意:腳本啟動后,不要通過ctrl+c 方式退出啟動命令,程序會終止,直接通過叉掉ssh頁面即可

#!/bin/bashCONFIG_FILE="/usr/local/nginx/html/streams/config/cameras.json"
STREAMS_DIR="/home/streams"  #流媒體存儲目錄
#STREAMS_DIR="/usr/local/nginx/html/streams"
NGINX_USER="nginx"                   # Nginx運行用戶
PID_FILE="$STREAMS_DIR/process_ids.txt"  # PID記錄文件# 清空或創建PID文件
> "$PID_FILE"# 創建目錄并設置權限
mkdir -p $STREAMS_DIR/{live,archive,logs}
chown -R $NGINX_USER:$NGINX_USER $STREAMS_DIR
chmod -R 755 $STREAMS_DIR# 讀取配置
CAMERAS=$(jq -r '.cameras[] | .id' $CONFIG_FILE)
HLS_TIME=$(jq -r '.hls_time' $CONFIG_FILE)
MAX_HOURS=$(jq -r '.max_archive_hours' $CONFIG_FILE)
LIVE_SEGMENTS=$(jq -r '.live_segments' $CONFIG_FILE)# 為每個攝像頭啟動FFmpeg(使用nohup)
for CAMERA in $CAMERAS; doRTSP_URL=$(jq -r --arg id "$CAMERA" '.cameras[] | select(.id==$id) | .rtsp' $CONFIG_FILE)# 為每個攝像創建目錄mkdir -p $STREAMS_DIR/live/$CAMERAmkdir -p $STREAMS_DIR/archive/$CAMERA# 實時流 - 使用nohup和后臺運行nohup ffmpeg -i "$RTSP_URL" \-c copy \-f hls \-hls_time $HLS_TIME \-hls_list_size $LIVE_SEGMENTS \-hls_flags delete_segments \-hls_segment_filename "$STREAMS_DIR/live/$CAMERA/segment_%03d.ts" \"$STREAMS_DIR/live/$CAMERA/live.m3u8" > "$STREAMS_DIR/logs/$CAMERA-live.log" 2>&1 &echo "$! camera_$CAMERA live" >> "$PID_FILE"  # 記錄PID# 歷史流 - 使用nohup和后臺運行nohup ffmpeg -i "$RTSP_URL" \-c copy \-f hls \-hls_time $HLS_TIME \-hls_list_size 0 \-hls_flags append_list \-hls_segment_filename "$STREAMS_DIR/archive/$CAMERA/%Y%m%d_%H%M%S.ts" \-strftime 1 \"$STREAMS_DIR/archive/$CAMERA/archive.m3u8" > "$STREAMS_DIR/logs/$CAMERA-archive.log" 2>&1 &echo "$! camera_$CAMERA archive" >> "$PID_FILE"  # 記錄PID
done# 定時清理舊歷史文件
while true; dofor CAMERA in $CAMERAS; dofind "$STREAMS_DIR/archive/$CAMERA" -name "*.ts" -mmin +$(($MAX_HOURS*60)) -deletedonesleep 3600  # 每小時清理一次
done

腳本執行如果提示 無效的用戶: "nginx:nginx"? 則創建nginx用戶

# 創建nginx用戶和組
sudo groupadd nginx
sudo useradd -g nginx -s /sbin/nologin -d /var/nginx -M nginx# 驗證用戶
id nginx

6.2停止腳本編寫

在home目錄創建停止腳本 vi?stop_streams.sh

#!/bin/bash# 文件用來存儲進程ID
PID_FILE="/home/streams/process_ids.txt"
LOG_FILE="/home/streams/stop.log"# 記錄日志函數
log() {echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}# 腳本結束前,關閉所有記錄的進程
cleanup() {if [ ! -f "$PID_FILE" ]; thenlog "錯誤:PID文件 $PID_FILE 不存在"return 1filog "開始停止所有FFmpeg進程..."total=0killed=0while read -r line; do# 解析PID和描述信息pid=$(echo "$line" | awk '{print $1}')desc=$(echo "$line" | cut -d' ' -f2-)((total++))# 檢查PID是否有效if kill -0 "$pid" 2>/dev/null; thenlog "正在停止進程 $pid ($desc)"if kill "$pid"; then((killed++))log "成功停止進程 $pid"elselog "警告:無法停止進程 $pid"fielselog "進程 $pid 已停止或不存在"fidone < "$PID_FILE"log "操作完成:共找到 $total 個記錄,成功停止 $killed 個進程"# 清空PID文件(可選)> "$PID_FILE"
}# 確保腳本退出時調用cleanup函數
trap cleanup EXIT# 主執行
log "====== 開始執行停止腳本 ======"
cleanup
exit 0

方案2:使用systemd服務(推薦生產環境使用)

  1. 創建systemd服務文件?/etc/systemd/system/rtsp_to_hls.service:

[Unit]
Description=RTSP to HLS Stream Service
After=network.target[Service]
Type=forking
User=nginx
WorkingDirectory=/home/streams
ExecStart=/path/to/your/start_streams.sh
Restart=always
RestartSec=10
StandardOutput=append:/home/streams/logs/service.log
StandardError=append:/home/streams/logs/service-error.log[Install]
WantedBy=multi-user.target
  1. 建日志目錄并設置權限:

    sudo mkdir -p /home/streams/logs
    sudo chown nginx:nginx /home/streams/logs
  2. 啟用并啟動服務:

sudo systemctl daemon-reload
sudo systemctl enable rtsp_to_hls.service
sudo systemctl start rtsp_to_hls.service

驗證服務是否正常運行

# 檢查systemd服務狀態
systemctl status rtsp_to_hls.service# 檢查進程
pgrep -a ffmpeg# 檢查日志
tail -f /home/streams/logs/*.log

停止服務的正確方式

sudo systemctl stop rtsp_to_hls.service

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/84200.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/84200.shtml
英文地址,請注明出處:http://en.pswp.cn/web/84200.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

全國產!瑞芯微 RK3576 ARM 八核 2.2GHz 工業核心板—硬件說明書

前 言 本文為創龍科技 SOM-TL3576 工業核心板硬件說明書,主要提供 SOM-TL3576 工業 核心板的產品功能特點、技術參數、引腳定義等內容,以及為用戶提供相關電路設計指導。 為便于閱讀,下表對文檔出現的部分術語進行解釋;對于廣泛認同釋義的術語,在此不做注釋。 硬件參考…

web3 瀏覽器注入 (如 MetaMask)

以下是關于 瀏覽器注入方式(如 MetaMask) 的完整詳解,包括原理、使用方法、安全注意事項及常見問題解決方案: 1. 核心原理 當用戶安裝 MetaMask 等以太坊錢包擴展時,錢包會向瀏覽器的 window 對象注入一個全局變量 window.ethereum,這個對象遵循 EIP-1193 標準,提供與區…

解密提示詞工程師:AI 時代的新興職業

大家好!在人工智能飛速發展的當下&#xff0c;有一個新興職業正悄然崛起——提示詞工程師。他們雖不如數據科學家般廣為人知&#xff0c;卻在 AI 應用領域發揮著獨特且關鍵的作用。 何為提示詞工程師&#xff1f; 提示詞工程師專注于設計和優化與 AI 模型進行交互的提示詞&…

linux 下 jenkins 構建 uniapp node-sass 報錯

背景: jenkins 中構建 uniapp 應用 配置: 1. 將windows HbuilderX 插件目錄下的 uniapp-cli 文件夾復制到 服務器 /var/jenkins_home/uniapp-cli 2. jenkins 構建步驟增加 執行 shell ,內容如下 echo ">> 構建中..."# 打包前端 export LANGen_US.UTF-8…

QT常見問題(1)

QT常見問題&#xff08;1&#xff09; 1.問題描述 Qt在編譯器中直接運行沒有任何問題&#xff0c;但是進入exe生成目錄直接雙擊運行就報錯&#xff1a;文件無法定位程序輸入點_zn10qarraydata10deallocateepsyy于動態鏈接庫。 2.問題原因 這個錯誤通常是由于程序運行時找不…

『大模型筆記』第2篇:并發請求中的 Prefill 與 Decode:優化大語言模型性能

『大模型筆記』并發請求中的 Prefill 與 Decode:優化大語言模型性能 文章目錄 一. Token 生成的兩個階段:Prefill 和 Decode1.1. 指標分析1.2. 資源利用率分析二. 并發處理機制2.1. 靜態批處理 vs 持續批處理(Static Batching vs. Continuous Batching)2.2. Prefill 優先策略…

JVM(7)——詳解標記-整理算法

核心思想 標記-整理算法同樣分為兩個主要階段&#xff0c;但第二個階段有所不同&#xff1a; 標記階段&#xff1a; 與標記-清除算法完全一致。遍歷所有可達對象&#xff08;從 GC Roots 開始&#xff09;&#xff0c;標記它們為“存活”。 整理階段&#xff1a; 不再簡單地清…

進程虛擬地址空間

1. 程序地址空間回顧 我們在學習語言層面時&#xff0c;會了解到這樣的空間布局圖&#xff0c;我們先對他進行分區了解&#xff1a; 如果以靜態static修飾的變量就會當成已初始化全局變量來看待&#xff0c;存放在已初始化數據區和未初始化數據區之前。 如果不用static修飾test…

C語言學習day17-----位運算

目錄 1.位運算 1.1基礎知識 1.1.1定義 1.1.2用途 1.1.3軟件控制硬件 1.2運算符 1.2.1與 & 1.2.2或 | 1.2.3非 ~ 1.2.4異或 ^ 1.2.5左移 << 1.2.6右移 >> 1.2.7代碼實現 1.2.8置0 1.2.9置1 1.2.10不借助第三方變量&#xff0c;實現兩個數的交換…

【linux】簡單的shell腳本練習

簡單易學 解釋性語言&#xff0c;不需要編譯即可執行 對于一個合格的系統管理員來說&#xff0c;學習和掌握Shell編程是非常重要的&#xff0c;通過shell程序&#xff0c;可以在很大程度上簡化日常的維護工作&#xff0c;使得管理員從簡單的重復勞動中解脫出來 用戶輸入任意兩…

機構運動分析系統開發(Python實現)

機構運動分析系統開發(Python實現) 一、引言 機構運動分析是機械工程的核心內容,涉及位置、速度和加速度分析。本系統基于Python開發,實現了平面連桿機構的完整運動學分析,包含數學建模、數值計算和可視化功能。 二、系統架構設計 #mermaid-svg-bT8TPKQ98UU9ERet {font…

工程師生活:清除電熱水壺(鍋)水垢方法

清除電熱水壺&#xff08;鍋&#xff09;水垢方法 水垢是水加熱時自然形成的鈣質沉淀物&#xff0c;常粘附在水壺內壁及發熱盤上。它不僅影響水的品質&#xff0c;還會縮短水壺的使用壽命&#xff0c;因此需要定期清除。建議根據各地水質不同&#xff0c;每年除垢 2 至 4 次。…

[分布式并行策略] 數據并行 DP/DDP/FSDP/ZeRO

上篇文章【[論文品鑒] DeepSeek V3 最新論文 之 DeepEP】 介紹了分布式并行策略中的EP&#xff0c;簡單的提到了其他幾種并行策略&#xff0c;但礙于精力和篇幅限制決定將內容分幾期&#xff0c;本期首先介紹DP&#xff0c;但并不是因為DP簡單&#xff0c;相反DP的水也很深&…

LeeCode144二叉樹的前序遍歷

項目場景&#xff1a; 給你二叉樹的根節點 root &#xff0c;返回它節點值的 前序 遍歷。 示例 1&#xff1a; 輸入&#xff1a;root [1,null,2,3] 輸出&#xff1a;[1,2,3] 解釋&#xff1a; 示例 2&#xff1a; 輸入&#xff1a;root [1,2,3,4,5,null,8,null,null,6,7…

日本生活:日語語言學校-日語作文-溝通無國界(3)-題目:わたしの友達

日本生活&#xff1a;日語語言學校-日語作文-溝通無國界&#xff08;&#xff13;&#xff09;-題目&#xff1a;わたしの友達 1-前言2-作文原稿3-作文日語和譯本&#xff08;1&#xff09;日文原文&#xff08;2&#xff09;對應中文&#xff08;3&#xff09;對應英文 4-老師…

使用 rsync 拉取文件(從遠程服務器同步到本地)

最近在做服務器遷移&#xff0c;文件好幾個T。。。。只能單向訪問&#xff0c;服務器。怎么辦&#xff01;&#xff01;&#xff01; 之前一直是使用rsync 服務器和服務器之間的雙向同步、備份&#xff08;這是推的&#xff09;。現在服務器要遷移&#xff0c;只能單向訪問&am…

Linux 并發編程:從線程池到單例模式的深度實踐

文章目錄 一、普通線程池&#xff1a;高效線程管理的核心方案1. 線程池概念&#xff1a;為什么需要 "線程工廠"&#xff1f;2. 線程池的實現&#xff1a;從 0 到 1 構建基礎框架 二、模式封裝&#xff1a;跨語言線程庫實現1. C 模板化實現&#xff1a;類型安全的泛型…

2013年SEVC SCI2區,自適應變領域搜索算法Adaptive VNS+多目標設施布局,深度解析+性能實測

目錄 1.摘要2.自適應局部搜索原理3.自適應變領域搜索算法Adaptive VNS4.結果展示5.參考文獻6.代碼獲取7.算法輔導應用定制讀者交流 1.摘要 VNS是一種探索性的局部搜索方法&#xff0c;其基本思想是在局部搜索過程中系統性地更換鄰域。傳統局部搜索應用于進化算法每一代的解上&…

詳細介紹醫學影像顯示中窗位和窗寬

在醫學影像&#xff08;如DICOM格式的CT圖像&#xff09;中&#xff0c;**窗寬&#xff08;Window Width, WW&#xff09;和窗位&#xff08;Window Level, WL&#xff09;**是兩個核心參數&#xff0c;用于調整圖像的顯示對比度和亮度&#xff0c;從而優化不同組織的可視化效果…

Unity_VR_如何用鍵鼠模擬VR輸入

文章目錄 [TOC] 一、創建項目1.直接創建VR核心模板&#xff08;簡單&#xff09;2.創建3D核心模板導入XR包 二、添加XR設備模擬器1.打開包管理器2.添加XR設備模擬器3.將XR設備模擬器拖到場景中4.運行即可用鍵盤模擬VR輸入 一、創建項目 1.直接創建VR核心模板&#xff08;簡單&…