cmvr-es-cli/cmvr/camera_client.py
2025-08-21 14:05:27 +08:00

138 lines
5.0 KiB
Python

import grpc
import numpy as np
from PIL import Image
from typing import Tuple
from . import generated
from .enums import CMVRErrorCode
from .models import CameraState
class CameraClient:
"""相机客户端"""
def __init__(self, device_id: str, stub):
self.device_id = device_id
self.stub = stub
def _create_command_header(self):
"""创建命令头"""
header = generated.common_pb2.CommandHeader.Request()
header.device_id = self.device_id
header.timestamp.GetCurrentTime()
return header
def get_status(self) -> Tuple[CMVRErrorCode, CameraState]:
"""获取相机状态"""
try:
request = generated.camera_service_pb2.GetCameraStateCommand.Request()
request.header.CopyFrom(self._create_command_header())
response = self.stub.GetStatus(request)
if not response.header.success:
return CMVRErrorCode.CMVR_RPC_FAILED, CameraState()
state = CameraState(
is_initialized=response.state.is_initialized,
is_opened=response.state.is_opened,
is_streaming=response.state.is_streaming,
is_recording=response.state.is_recording,
width=response.state.width,
height=response.state.height,
fps=response.state.fps
)
return CMVRErrorCode.CMVR_SUCCESS, state
except grpc.RpcError as e:
print(f"获取相机状态失败: {e}")
return CMVRErrorCode.CMVR_RPC_FAILED, CameraState()
def start_camera(self) -> CMVRErrorCode:
"""启动相机"""
try:
request = generated.camera_service_pb2.StartCameraCommand.Request()
request.header.CopyFrom(self._create_command_header())
response = self.stub.StartCamera(request)
return CMVRErrorCode.CMVR_SUCCESS if response.header.success else CMVRErrorCode.CMVR_RPC_FAILED
except grpc.RpcError as e:
print(f"启动相机失败: {e}")
return CMVRErrorCode.CMVR_RPC_FAILED
def stop_camera(self) -> CMVRErrorCode:
"""停止相机"""
try:
request = generated.camera_service_pb2.StopCameraCommand.Request()
request.header.CopyFrom(self._create_command_header())
response = self.stub.StopCamera(request)
return CMVRErrorCode.CMVR_SUCCESS if response.header.success else CMVRErrorCode.CMVR_RPC_FAILED
except grpc.RpcError as e:
print(f"停止相机失败: {e}")
return CMVRErrorCode.CMVR_RPC_FAILED
def get_rgb_image(self) -> Tuple[CMVRErrorCode, np.ndarray, int, int]:
"""获取RGB图像"""
try:
request = generated.camera_service_pb2.GetRGBImageCommand.Request()
request.header.CopyFrom(self._create_command_header())
response = self.stub.GetRGBImage(request)
if not response.header.success:
return CMVRErrorCode.CMVR_RPC_FAILED, np.array([]), 0, 0
width = response.color_frame.width
height = response.color_frame.height
size = len(response.color_frame.data)
# 将字节数据转换为numpy数组
img_data = np.frombuffer(response.color_frame.data, dtype=np.uint8)
# 重塑为图像格式 (height, width, channels)
channels = 3 # 假设是RGB图像
if size == width * height * channels:
img_array = img_data.reshape((height, width, channels))
else:
# 可能是灰度图或其他格式
img_array = img_data.reshape((height, width))
return CMVRErrorCode.CMVR_SUCCESS, img_array, width, height
except grpc.RpcError as e:
print(f"获取图像失败: {e}")
return CMVRErrorCode.CMVR_RPC_FAILED, np.array([]), 0, 0
def start_record(self, video_path: str) -> CMVRErrorCode:
"""开始录像"""
try:
request = generated.camera_service_pb2.StartCameraRecordingCommand.Request()
request.header.CopyFrom(self._create_command_header())
request.video_path = video_path
response = self.stub.StartRecording(request)
return CMVRErrorCode.CMVR_SUCCESS if response.header.success else CMVRErrorCode.CMVR_RPC_FAILED
except grpc.RpcError as e:
print(f"开始录像失败: {e}")
return CMVRErrorCode.CMVR_RPC_FAILED
def stop_record(self) -> CMVRErrorCode:
"""停止录像"""
try:
request = generated.camera_service_pb2.StopCameraRecordingCommand.Request()
request.header.CopyFrom(self._create_command_header())
response = self.stub.StopRecording(request)
return CMVRErrorCode.CMVR_SUCCESS if response.header.success else CMVRErrorCode.CMVR_RPC_FAILED
except grpc.RpcError as e:
print(f"停止录像失败: {e}")
return CMVRErrorCode.CMVR_RPC_FAILED