Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update PyOpticam to the Latest Optitrack+Nanobind #9

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,6 @@ calib_images*
Rigel*
Europa*
local*
*.dll
*.dll
.venv
.vs
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,6 @@ nanobind_add_module(
NB_STATIC # Build static libnanobind (the extension module itself remains a shared library)
src/pyopticam_ext.cpp
)
target_link_libraries(pyopticam_ext PRIVATE "C:/Program Files (x86)/OptiTrack/Camera SDK/lib/CameraLibrary2015x64S.lib")
target_link_libraries(pyopticam_ext PRIVATE "C:/Program Files (x86)/OptiTrack/CameraSDK/lib/CameraLibrary2019x64S.lib")

install(TARGETS pyopticam_ext LIBRARY DESTINATION .)
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Installation
2. Install the [Optitrack Camera SDK](https://optitrack.com/software/camera-sdk/) to: `C:/Program Files (x86)/OptiTrack/Camera SDK`
3. Clone this repository
4. Navigate to the top-level `pyopticam` directory and run `pip install -e . ` (Do not upgrade pip, use pip version `21.1.1`)
5. Find `C:/Program Files (x86)/OptiTrack/Camera SDK/lib/CameraLibrary2015x64S.dll` and copy it to `pyopticam/src/pyopticam`
5. Find `C:/Program Files (x86)/OptiTrack/CameraSDK/lib/CameraLibrary2019x64S.dll` and copy it to `pyopticam/src/pyopticam`

Afterwards, make sure your Optitrack cameras are accessible on the network, and try the `video_viewer.py` or the `marker_viewer.py` example.

Expand Down
10 changes: 5 additions & 5 deletions cmake-modules/FindOTCSDK.cmake
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
find_path(OTCSDK_ROOT_DIR
NAMES include/camera.h
HINTS "C:/Program Files (x86)/OptiTrack/Camera SDK"
HINTS "C:/Program Files (x86)/OptiTrack/CameraSDK"
NO_CMAKE_PATH)

find_path(OTCSDK_INCLUDE_DIR
NAMES cameralibrary.h
HINTS "C:/Program Files (x86)/OptiTrack/Camera SDK/include"
HINTS "C:/Program Files (x86)/OptiTrack/CameraSDK/include"
NO_CMAKE_PATH)

#message(STATUS "OTCSDK ROOT DIR PATH ${NP_CAMERASDK}")
Expand All @@ -15,13 +15,13 @@ message(STATUS "OTCSDK ROOT DIR ${OTCSDK_ROOT_DIR}")

message(STATUS "OTCSDK INCLUDE DIR ${OTCSDK_INCLUDE_DIR}")

find_library(OTCSDK_IMPORT_LIB CameraLibrary2015x64S HINTS "${OTCSDK_ROOT_DIR}/lib")
find_file(OTCSDK_SHARED_LIB NAMES "CameraLibrary2015x64S.dll" HINTS "${OTCSDK_ROOT_DIR}/lib")
find_library(OTCSDK_IMPORT_LIB CameraLibrary2019x64S HINTS "${OTCSDK_ROOT_DIR}/lib")
find_file(OTCSDK_SHARED_LIB NAMES "CameraLibrary2019x64S.dll" HINTS "${OTCSDK_ROOT_DIR}/lib")

message(STATUS "OTCSDK IMPORT LIBRARY DIR ${OTCSDK_IMPORT_LIB}")
message(STATUS "OTCSDK SHARED LIBRARY DIR ${OTCSDK_SHARED_LIB}")

include_directories("C:/Program Files (x86)/OptiTrack/Camera SDK/include")
include_directories("C:/Program Files (x86)/OptiTrack/CameraSDK/include")

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(OTCSDK DEFAULT_MSG OTCSDK_ROOT_DIR OTCSDK_INCLUDE_DIR OTCSDK_IMPORT_LIB OTCSDK_SHARED_LIB)
Expand Down
16 changes: 9 additions & 7 deletions examples/optitrack_thread.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def __init__(self, mode=m.eVideoMode.MJPEGMode, exposure=50, delay_strobe=False,
print("Creating Sync Object...")
self.sync = m.cModuleSync.Create()
for i in range(len(self.camera_array)):
self.sync.AddCamera(self.camera_array[i], 0)
self.sync.AddCamera(self.camera_array[i])
else:
self.sync = None

Expand Down Expand Up @@ -105,17 +105,19 @@ def fetch_frame(self):
new_frame = np.nan_to_num(new_frame, nan=0.0)
else:
current_framegroup = m.GetFrameGroup(self.sync)
new_frame = np.zeros((current_framegroup.Count(), 512, 640), dtype=np.uint8)
m.FillTensorFromFrameGroup(current_framegroup, new_frame)
new_frame = np.zeros((current_framegroup.Count(), self.camera_array[0].Height(), self.camera_array[0].Width()), dtype=np.uint8)
m.FillTensorFromFrameGroup(self.camera_array[0], current_framegroup, new_frame)
self.current_frame = new_frame
self.newFrame = True

def run(self):
print("Beginning Optitrack Receive Thread!")

while(self.should_run and time.time() - self.deadmansSwitch < 4.0):
while(self.should_run):# and time.time() - self.deadmansSwitch < 6.0):
self.fetch_frame()

print("Should Run:", self.should_run, "Deadman Switch:", time.time() - self.deadmansSwitch)

if self.sync:
self.sync.RemoveAllCameras()
m.cModuleSync.Destroy(self.sync)
Expand All @@ -124,9 +126,9 @@ def run(self):
if self.camera_array[i].State() == m.eCameraState.Initialized:
print("Stopping Camera", i, "...")
#camera_array[i].Stop(True)
print("Stopped Camera", i," Releasing Camera...")
self.camera_array[i].Release()
print("Released Camera!")
print("Stopped Camera", i)#" Releasing Camera...")
#self.camera_array[i].Release()
#print("Released Camera!")

m.CameraManager.X().Shutdown()

Expand Down
77 changes: 39 additions & 38 deletions examples/video_viewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,45 +11,46 @@
ffmpeg_recording = False

fake = np.zeros((16, 16), dtype=np.uint8)
num_cams = 8
num_cams = 1
output_width = int(640 / 2)
#output_height = int(512 * num_cams / 2) # Dependent on the number of cameras; see below

print("Starting to retrieve frame groups...")
keypress = cv2.waitKey(1)
while(not (keypress & 0xFF == ord('q'))):
if optitrack.newFrame:
image_frame = optitrack.read()
num_cams = image_frame.shape[0]
output_height = int(512 * num_cams / 2)
if image_frame.shape[1] > 1:
image_frame = np.reshape(image_frame, (-1, image_frame.shape[2]))
#image_frame = np.vstack((np.hstack((image_frame[0], image_frame[1], image_frame[2], image_frame[3])),
# np.hstack((image_frame[4], image_frame[5], image_frame[6], image_frame[7]))))
image_frame = cv2.resize(image_frame, (output_width, output_height))

if (keypress & 0xFF == ord('w')):
if not ffmpeg_recording:
ffmpeg_process = mp4_thread.ffmpegThread("OptitrackOutput.mp4", width=output_width, height=output_height)#image_frame.shape[1], height=image_frame.shape[0])
ffmpeg_process.start()
ffmpeg_recording = True
else:
print("Killing FFMPEG process...")
ffmpeg_process.end_encoding()
ffmpeg_recording = False

if ffmpeg_recording:
ffmpeg_process.add_image(image_frame)
cv2.imshow("CameraFrame", image_frame)

try:
print("Starting to retrieve frame groups...")
keypress = cv2.waitKey(1)

if ffmpeg_recording:
print("Killing FFMPEG process...")
ffmpeg_process.end_encoding()
ffmpeg_recording = False

optitrack.stop()

cv2.destroyAllWindows()
print("Fin!")
while(not (keypress & 0xFF == ord('q'))):
if optitrack.newFrame:
image_frame = optitrack.read()
num_cams = image_frame.shape[0]
output_height = int(512 * num_cams / 2)
if image_frame.shape[1] > 1:
image_frame = np.reshape(image_frame, (-1, image_frame.shape[2]))
#image_frame = np.vstack((np.hstack((image_frame[0], image_frame[1], image_frame[2], image_frame[3])),
# np.hstack((image_frame[4], image_frame[5], image_frame[6], image_frame[7]))))
#image_frame = cv2.resize(image_frame, (output_width, output_height))

if (keypress & 0xFF == ord('w')):
if not ffmpeg_recording:
ffmpeg_process = mp4_thread.ffmpegThread("OptitrackOutput.mp4", width=output_width, height=output_height)#image_frame.shape[1], height=image_frame.shape[0])
ffmpeg_process.start()
ffmpeg_recording = True
else:
print("Killing FFMPEG process...")
ffmpeg_process.end_encoding()
ffmpeg_recording = False

if ffmpeg_recording:
ffmpeg_process.add_image(image_frame)
cv2.imshow("CameraFrame", image_frame)

keypress = cv2.waitKey(1)
finally:
if ffmpeg_recording:
print("Killing FFMPEG process...")
ffmpeg_process.end_encoding()
ffmpeg_recording = False

optitrack.stop()

cv2.destroyAllWindows()
print("Fin!")
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ requires = [
"wheel",
"scikit-build",
"cmake>=3.17",
"nanobind==0.0.9",
"nanobind",
"ninja; platform_system!='Windows'"
]

Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

setup(
name="pyopticam",
version="0.0.1",
version="0.0.2",
author="Johnathon Selstad",
author_email="[email protected]",
description="A nanobind wrapper for NaturalPoint's Optitrack Camera SDK",
Expand Down
2 changes: 1 addition & 1 deletion src/pyopticam/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
from .pyopticam_ext import GetCameraList, eVideoMode, eImagerGain, eCameraState, eOptimization, sStatusLightColor, cCameraLibraryStartupSettings, cModuleSync, FrameGroup, Modes, DroppedFrameInfo, GetFrameGroup, FillTensorFromFrameGroup, GetFrameGroupObjectArray, GetSlowFrameArray, Frame, Camera, CameraManager, CameraEntry, CameraList, HardwareKeyList, HubList, HardwareDeviceList, CameraManagerListener, cUID
from .pyopticam_ext import GetCameraList, eVideoMode, eImagerGain, eCameraState, eOptimization, sStatusLightColor, cCameraLibraryStartupSettings, FrameGroup, Modes, GetFrameGroup, FillTensorFromFrameGroup, GetFrameGroupObjectArray, GetSlowFrameArray, Frame, Camera, CameraManager, CameraEntry, CameraList, HardwareKeyList, HubList, HardwareDeviceList, CameraManagerListener, cUID, cModuleSync
Loading