Код: Выделить всё
_start_capture_thread(self)< /code> считывает кадры из веб -камеры с указанной частотой через фоновый поток.
_apply_texture_update(self)
import threading
import time
import cv2
import numpy as np
import open3d as o3d
from open3d.visualization import gui, rendering
CAM_INDEX = 0
FRAME_WIDTH = 3840
FRAME_HEIGHT = 2160
FPS = 30
class WebcamPlaneApp:
def __init__(self):
self.window = gui.Application.instance.create_window("Webcam Plane Open3D", 1280, 720)
self.window.set_on_close(self._on_close)
self.scene_widget = gui.SceneWidget()
self.scene_widget.scene = rendering.Open3DScene(self.window.renderer)
self.window.add_child(self.scene_widget)
self.running = True
self.latest_frame = None
self._tex_update_pending = False
self._init_camera_capture()
self._init_scene()
self._start_capture_thread()
self._request_texture_update()
def _init_camera_capture(self):
self.cap = cv2.VideoCapture(CAM_INDEX, cv2.CAP_DSHOW)
self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, FRAME_WIDTH)
self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, FRAME_HEIGHT)
self.cap.set(cv2.CAP_PROP_FPS, FPS)
self.cap.set(cv2.CAP_PROP_AUTOFOCUS, 0)
def _init_scene(self):
self.texture = o3d.geometry.Image(np.zeros((FRAME_HEIGHT, FRAME_WIDTH, 3), dtype=np.uint8))
self.material = rendering.MaterialRecord()
self.material.shader = "defaultUnlit"
self.material.albedo_img = self.texture
w = 1.0
h = FRAME_HEIGHT / FRAME_WIDTH
verts = np.array([
[-w/2, -h/2, 0],
[ w/2, -h/2, 0],
[ w/2, h/2, 0],
[-w/2, h/2, 0],
], dtype=np.float32)
uvs = np.array([[0,1],[1,1],[1,0],[0,0]], dtype=np.float32)
triangles = np.array([[0,1,2],[0,2,3]], dtype=np.int32)
plane = o3d.t.geometry.TriangleMesh()
plane.vertex["positions"] = o3d.core.Tensor(verts, o3d.core.Dtype.Float32)
plane.triangle["indices"] = o3d.core.Tensor(triangles, o3d.core.Dtype.Int32)
plane.vertex["texCoord"] = o3d.core.Tensor(uvs, o3d.core.Dtype.Float32)
plane_legacy = plane.to_legacy()
self.scene_widget.scene.add_geometry("video_plane", plane_legacy, self.material)
bounds = plane_legacy.get_axis_aligned_bounding_box()
center = bounds.get_center()
extent = bounds.get_extent()
half_diag = 0.5 * np.linalg.norm(extent[:2])
fov = 60.0
dist = half_diag / np.tan(np.deg2rad(fov / 2))
eye = center + np.array([0, 0, dist])
up = [0, 1, 0]
cam = self.scene_widget.scene.camera
aspect = FRAME_WIDTH / FRAME_HEIGHT
cam.set_projection(fov, aspect, 0.01, 10.0 * dist, rendering.Camera.FovType.Vertical)
cam.look_at(center, eye, up)
self.scene_widget.scene.show_skybox(False)
self.scene_widget.scene.set_background([0, 0, 0, 1])
def _start_capture_thread(self):
def loop():
interval = 1.0 / FPS
while self.running:
start = time.time()
ret, frame = self.cap.read()
if ret:
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
with self.frame_lock:
self.latest_frame = frame
sleep = interval - (time.time() - start)
if sleep > 0:
time.sleep(sleep)
threading.Thread(target=loop, daemon=True).start()
def _apply_texture_update(self):
if not self.running:
self._tex_update_pending = False
return
with self.frame_lock:
frame = self.latest_frame
if frame is not None and frame.shape[:2] == (FRAME_HEIGHT, FRAME_WIDTH):
np.asarray(self.texture)[:] = frame
self.scene_widget.scene.modify_geometry_material("video_plane", self.material)
self._tex_update_pending = False
if self.running:
self._request_texture_update()
def _request_texture_update(self):
if not self.running or self._tex_update_pending:
return
self._tex_update_pending = True
gui.Application.instance.post_to_main_thread(self.window, self._apply_texture_update)
def _on_close(self):
self.running = False
try:
self.cap.release()
except:
pass
return True
def main():
gui.Application.instance.initialize()
WebcamPlaneApp()
gui.Application.instance.run()
if __name__ == "__main__":
main()
< /code>
Я пытался работать с буфером текстур для видео плоскости (например, ниже), но та же проблема: < /p>
texture_buffer = np.asarray(self.texture)
np.copyto(texture_buffer, self.frameDisplay)
self.video_material.albedo_img = self.texture
self._scene.scene.modify_geometry_material(
"video_plane", self.video_material)
< /code>
Кто -нибудь уже делал это в Open3d+OpenCV раньше? (Не удалось найти доступное репо).
Подробнее здесь: https://stackoverflow.com/questions/797 ... cam-stream