日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

IntelRealSense 深度相机 测量物体的实际长度 —— rs-measure 官网文档翻译

發布時間:2024/1/1 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 IntelRealSense 深度相机 测量物体的实际长度 —— rs-measure 官网文档翻译 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

總覽

本教程顯示了使用深度數據測量真實世界距離的簡單方法。

## Note: 測量真實世界中物體的維度是深度相機的一個明顯的應用之一。此樣本不是適當的測量工具,而是展示關鍵概念。使用更好的算法可以顯著改善測量結果。

在這個教程中你將會學到怎樣:

  • 在空間上將顏色流與深度對齊(和在rs-align中深度到顏色的對齊相反)
  • 利用后處理來處理缺失和噪聲的深度數據
  • 在2D像素和3D空間中的點之間進行轉換
  • 利用多核來并行化數據流
  • 使用OpenGL在深度之上疊加顏色

預期輸出


這個例子允許用戶測量物理世界中的兩個點。

代碼總覽

深度處理流程

我們通過定義所有的處理塊來開始這個例子。我們將要使用

// Colorizer is used to visualize depth data // Colorizer 用于可視化深度數據 rs2::colorizer color_map; // Use black to white color map // 使用黑色到白色顏色映射 color_map.set_option(RS2_OPTION_COLOR_SCHEME, 2.f); // Decimation filter reduces the amount of data (while preserving best samples) // 抽取濾波器減小數據的數量(同時保持最佳樣本) rs2::decimation_filter dec; // If the demo is too slow, make sure you run in Release (-DCMAKE_BUILD_TYPE=Release) // but you can also increase the following parameter to decimate depth more (reducing quality) // 如果這個demo太慢,確保你在release中運行(-DCMAKE_BUILD_TYPE=Release) // 但是你可以同樣增加下面的參數來更多的減少深度(降低質量) dec.set_option(RS2_OPTION_FILTER_MAGNITUDE, 2); // Define transformations from and to Disparity domain // 定義從和到時差域的轉換 rs2::disparity_transform depth2disparity; rs2::disparity_transform disparity2depth(false); // Define spatial filter (edge-preserving) // 定于空間過濾器(保留邊) rs2::spatial_filter spat; // Enable hole-filling // Hole filling is an aggressive heuristic and it gets the depth wrong many times // However, this demo is not built to handle holes // (the shortest-path will always prefer to "cut" through the holes since they have zero 3D distance) // 開啟填孔 // 填孔是一個積極的啟發性策略,它多次錯誤地獲得深度 // 然而,這個demo不是用于處理填孔的 // (最短的路徑總是喜歡切穿這些孔,因為它們的3D距離為零。) spat.set_option(RS2_OPTION_HOLES_FILL, 5); // 5 = fill all the zero pixels 5 = 填充所有的零像素 // Define temporal filter // 定義時間過濾器 rs2::temporal_filter temp; // Spatially align all streams to depth viewport // We do this because: // a. Usually depth has wider FOV, and we only really need depth for this demo // b. We don't want to introduce new holes // 將所有流在空間上對齊到深度視口 // 我們這樣做是因為: // a. 通常深度有一個更廣的FOV,并且對于這個demo我們只需要深度 // b. 我們不想引入新的洞 rs2::align align_to(RS2_STREAM_DEPTH);

下面,我們為深度+顏色流配置相機管道

// Declare RealSense pipeline, encapsulating the actual device and sensors // 定義RealSense管道,封裝真正的設備和傳感器 rs2::pipeline pipe;rs2::config cfg; cfg.enable_stream(RS2_STREAM_DEPTH); // Enable default depth //啟用默認深度 // For the color stream, set format to RGBA // To allow blending of the color frame on top of the depth frame // 對于顏色流,設置格式為RGBA // 允許在深度幀頂部混合顏色幀 cfg.enable_stream(RS2_STREAM_COLOR, RS2_FORMAT_RGBA8); auto profile = pipe.start(cfg);

我們的目標是生成沒有任何孔的深度,因為這將會對我們的算法構成直接問題。
減少丟失像素的最好方法是讓硬件來處理。
D400相機具有我們可以利用的高密度預設。

auto sensor = profile.get_device().first<rs2::depth_sensor>();// Set the device to High Accuracy preset // 將設備設置為高密度預設 auto sensor = profile.get_device().first<rs2::depth_sensor>(); sensor.set_option(RS2_OPTION_VISUAL_PRESET, RS2_RS400_VISUAL_PRESET_HIGH_ACCURACY);

給定一個幀集,我們將按順序應用所有的處理塊。
首先我們應用align處理塊來將顏色幀對其到深度視口:

// First make the frames spatially aligned // 首先使幀空間對齊 data = align_to.process(data);

然后,我們應用深度后處理流:

rs2::frame depth = data.get_depth_frame(); // Decimation will reduce the resultion of the depth image, // closing small holes and speeding-up the algorithm // 抽取將減少深度圖像的結果 // 關閉小孔,并且加速算法 depth = dec.process(depth); // To make sure far-away objects are filtered proportionally // we try to switch to disparity domain // 確保按照比例過濾遠處的物體 // 我們嘗試轉換到視差域 depth = depth2disparity.process(depth); // Apply spatial filtering // 應用空間過濾器 depth = spat.process(depth); // Apply temporal filtering // 應用時間過濾 depth = temp.process(depth); // If we are in disparity domain, switch back to depth // 如果我們在視差域,切回到深度 depth = disparity2depth.process(depth); // Send the post-processed depth for path-finding // 發送后處理深度用于路徑查找 pathfinding_queue.enqueue(depth); 所有基于立體的3D相機都具有噪聲與距離平方成正比的特性。為了抵消這一點,我們將幀轉換為視差域,使噪聲在距離上更均勻。這對我們的結構光相機沒有任何作用(因為他們沒有這個屬性)

我們同樣應用標準顏色映射

// Apply color map for visualization of depth // 應用顏色映射來可視化深度 auto colorized = color_map(depth);

將像素和3D中的點進行轉換

要將深度圖像中的像素轉換為3D點,我們調用rs2_deproject_pixel_to_point C函數(定義在rsutil.h中)
這個函數需要深度內在函數(depths intrinsics),2D像素和距離(米為單位)。這是我們怎樣得到深度內部函數(depth intrinsics)的:

auto stream = profile.get_stream(RS2_STREAM_DEPTH).as<rs2::video_stream_profile>(); auto intrinsics = stream.get_intrinsics(); // Calibration data 校準數據

可以使用depth_frame類的get_distance函數獲取以米為單位的距離。

過度調用get_distance會導致性能不佳,因為編譯器無法跨模塊邊界進行優化,因此,直接從depth_sensor讀取 DEPTH_UNITS選項并使用它將原始深度像素轉換為米可能是有益的:

將所有內容放在一起會產生相當冗長的dist_3d函數:

float dist_3d(const rs2_intrinsics& intr, const rs2::depth_frame& frame, pixel u, pixel v) {float upixel[2]; // From pixel //從像素float upoint[3]; // From point (in 3D) //從點(3D中)float vpixel[2]; // To pixel //到像素float vpoint[3]; // To point (in 3D) //到點(3D中)// Copy pixels into the arrays (to match rsutil signatures)// 將像素拷貝到數組中(匹配rsutil簽名)upixel[0] = u.first;upixel[1] = u.second;vpixel[0] = v.first;vpixel[1] = v.second;// Query the frame for distance // Note: this can be optimized// It is not recommended to issue an API call for each pixel// (since the compiler can't inline these)// However, in this example it is not one of the bottlenecks// 查詢幀的距離// 注意:這個可以被優化// 不建議為每個像素發出API調用// (因為編譯器不能內聯這些)// 然而,在這里例子中它不是瓶頸之一auto udist = frame.get_distance(upixel[0], upixel[1]);auto vdist = frame.get_distance(vpixel[0], vpixel[1]);// Deproject from pixel to point in 3D// 將像素反映射到3D中的點rs2_deproject_pixel_to_point(upoint, &intr, upixel, udist);rs2_deproject_pixel_to_point(vpoint, &intr, vpixel, vdist);// Calculate euclidean distance between the two points// 計算空間中兩個點的歐幾里得距離return sqrt(pow(upoint[0] - vpoint[0], 2) +pow(upoint[1] - vpoint[1], 2) +pow(upoint[2] - vpoint[2], 2)); }

在后臺線程上運行處理

在此示例中的后處理運算可能相對較慢。為了不阻塞主(UI)線程,我們將有一個專門的線程進行后處理。

視頻處理線程

這個線程將消耗來自相機完整幀集,并且會產生包含顏色和著色深度幀的幀集(用于在主線程上渲染):

while (alive) {// Fetch frames from the pipeline and send them for processing// 從管道中獲取幀,并且發送它們進行處理 rs2::frameset fs;if (pipe.poll_for_frames(&fs)) {// Apply post processing// ...// 應用后處理過程// ...// Send resulting frames for visualization in the main thread// 發送結果幀,用于在主線程中進行可視化。postprocessed_frames.enqueue(data);} }

主線程

主線程是唯一允許用來渲染屏幕的。
它從postprocessed_frames中獲取,并且只是展示結果:

while(app) // Application still alive? // 應用仍然存在嗎? {postprocessed_frames.poll_for_frame(&current_frameset);if (current_frameset){auto depth = current_frameset.get_depth_frame();auto color = current_frameset.get_color_frame();glEnable(GL_BLEND);// Use the Alpha channel for blending // 使用Alpha通道進行混合glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);// First render the colorized depth image// 首先渲染著色的深度圖像depth_image.render(depth, { 0, 0, app.width(), app.height() });// Next, set global alpha for the color image to 90%// (to make it slightly translucent)// 下一步,將彩色圖像的全局alpha設置為90%// (使其略微半透明)glColor4f(1.f, 1.f, 1.f, 0.9f);// Render the color frame (since we have selected RGBA format// pixels out of FOV will appear transparent)// 渲染顏色幀(因為我們選擇了RGBA格式,超出FOV的像素將會顯示為透明)color_image.render(color, { 0, 0, app.width(), app.height() });// Render the simple pythagorean distance// 渲染簡單的Pythagorean距離(勾股距離)render_simple_distance(depth, app_state, app, intrinsics);// Render the ruler// 渲染直尺app_state.ruler_start.render(app);app_state.ruler_end.render(app);glDisable(GL_BLEND);} }

我們使用glBlendFunc使用顏色alpha通道在深度之上覆蓋對其的顏色(流必須是格式RGBA才能工作)。


這個例子演示了一個簡單而復雜的處理流程。每個線程都有一些不同的速率,它們都需要同步而不是相互堵塞。
這是使用線程安全的frame_queues作為同步原語和rs2::frame引用計數來實現的,用于跨線程的對象生命周期管理。

總結

以上是生活随笔為你收集整理的IntelRealSense 深度相机 测量物体的实际长度 —— rs-measure 官网文档翻译的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。