-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path0_camera_info.py
More file actions
130 lines (103 loc) · 3.66 KB
/
0_camera_info.py
File metadata and controls
130 lines (103 loc) · 3.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# -*- coding: utf-8 -*-
"""
Clean camera info printer for PySpin.
Design:
- Single-responsibility functions
- Robust cleanup (Init/DeInit scoped to the function)
- Pretty, width-aware box printing
"""
from typing import Dict, List
import PySpin
def get_node_value(nodemap: PySpin.INodeMap, node_name: str) -> str:
"""
Read a CString node as str if available/readable; otherwise 'N/A'.
Args:
nodemap (PySpin.INodeMap): Camera node map (requires cam.Init()).
node_name (str): Node name to read (e.g., 'DeviceModelName').
Returns:
str: Node value or 'N/A' when not readable.
"""
node = PySpin.CStringPtr(nodemap.GetNode(node_name))
if PySpin.IsAvailable(node) and PySpin.IsReadable(node):
return node.GetValue()
return "N/A"
def _format_block(title: str, kv_pairs: Dict[str, str]) -> List[str]:
"""
Build a pretty, width-aligned text block for printing.
Args:
title (str): Title to show at the top of the block.
kv_pairs (Dict[str, str]): Mapping from label -> value.
Returns:
List[str]: Lines to print (without trailing newline).
"""
# Prepare lines "label : value" with aligned label width
label_width = max(len(label) for label in kv_pairs.keys()) if kv_pairs else 0
body_lines = [f" ├─ {label:<{label_width}} : {value}" for label, value in kv_pairs.items()]
# Compute box width based on the longest body line
content_width = max([len(line) for line in body_lines] + [len(title) + 2]) # +2 for icon/space
top = f"\n📷 {title}".ljust(content_width)
bottom = " └" + "─" * (content_width - 2) + "┘"
return [top, *body_lines, bottom]
def print_camera_info(cam: PySpin.CameraPtr, index: int) -> None:
"""
Print a formatted info block for a single camera.
Args:
cam (PySpin.CameraPtr): Camera pointer (uninitialized).
index (int): Camera index (for display only).
Returns:
None
"""
cam.Init()
try:
nodemap = cam.GetNodeMap()
info_nodes = {
"Model Name": "DeviceModelName",
"Serial Number": "DeviceSerialNumber",
"Vendor Name": "DeviceVendorName",
"Firmware Ver.": "DeviceFirmwareVersion",
"Device Version": "DeviceVersion",
}
kv = {label: get_node_value(nodemap, node) for label, node in info_nodes.items()}
for line in _format_block(f"Camera [{index}]", kv):
print(line)
finally:
# Ensure the camera is properly de-initialized
try:
cam.EndAcquisition()
except Exception:
pass
try:
cam.DeInit()
except Exception:
pass
def main() -> None:
"""
Enumerate cameras and print basic information for each.
Args:
None
Returns:
None
"""
system = PySpin.System.GetInstance()
cam_list = system.GetCameras()
try:
num = cam_list.GetSize()
if num == 0:
print("❌ No cameras detected.")
return
print(f"✅ {num} camera(s) detected.")
for i in range(num):
cam = cam_list.GetByIndex(i)
# Do not keep references around longer than needed
print_camera_info(cam, i)
del cam
finally:
# Proper release order: clear list -> release system
try:
cam_list.Clear()
finally:
del cam_list
system.ReleaseInstance()
del system
if __name__ == "__main__":
main()