针对原始pyk4a进行了修改,适用于双AzureKinect相机同时采图,该库使用详情请见后续博客
资源内容介绍
主要将AzureKinect相机的python-SDK进行了重写,添加了一个capture类,使得其调用后能够提取两台相机的视频流,根据此原理,只要主机算力足够,理论上可以实现三相机、四相机的图像采集 #include <Python.h>#include <numpy/arrayobject.h>#include <k4a/k4a.h>#include <k4arecord/playback.h>#include <k4arecord/record.h>#include <stdio.h>#ifdef __cplusplusextern "C" {#endif// to debug, use fprintf(stdout, "debug msg\n") or fprintf(stderr, "debug// msg\n");;#define NON_THREAD_SAFE 0// Simple way to map k4a_color_resolution_t to dimensionsconst int RESOLUTION_TO_DIMS[][2] = {{0, 0}, {1280, 720}, {1920, 1080}, {2560, 1440}, {2048, 1536}, {3840, 2160}, {4096, 3072}};const char *CAPSULE_PLAYBACK_NAME = "pyk4a playback handle";const char *CAPSULE_DEVICE_NAME = "pyk4a device handle";const char *CAPSULE_CALIBRATION_NAME = "pyk4a calibration handle";const char *CAPSULE_TRANSFORMATION_NAME = "pyk4a transformation handle";const char *CAPSULE_CAPTURE_NAME = "pyk4a capture handle";const char *CAPSULE_RECORD_NAME = "pyk4a record handle";static PyThreadState *_gil_release(int thread_safe) { PyThreadState *thread_state = NULL; if (thread_safe == NON_THREAD_SAFE) { thread_state = PyEval_SaveThread(); } return thread_state;}static void _gil_restore(PyThreadState *thread_state) { if (thread_state != NULL) { PyEval_RestoreThread(thread_state); }}static void capsule_cleanup_device(PyObject *capsule) { k4a_device_t *device_handle; device_handle = (k4a_device_t *)PyCapsule_GetPointer(capsule, CAPSULE_DEVICE_NAME); free(device_handle);}static void capsule_cleanup_image(PyObject *capsule) { k4a_image_t *image = (k4a_image_t *)PyCapsule_GetContext(capsule); k4a_image_release(*image); free(image);}static void capsule_cleanup_calibration(PyObject *capsule) { k4a_calibration_t *calibration = (k4a_calibration_t *)PyCapsule_GetPointer(capsule, CAPSULE_CALIBRATION_NAME); free(calibration);}static void capsule_cleanup_capture(PyObject *capsule) { k4a_capture_t *capture = (k4a_capture_t *)PyCapsule_GetPointer(capsule, CAPSULE_CAPTURE_NAME); k4a_capture_release(*capture); free(capture);}static void capsule_cleanup_playback(PyObject *capsule) { k4a_playback_t *playback_handle; playback_handle = (k4a_playback_t *)PyCapsule_GetPointer(capsule, CAPSULE_PLAYBACK_NAME); free(playback_handle);}static void capsule_cleanup_record(PyObject *capsule) { k4a_record_t *record_handle; record_handle = (k4a_record_t *)PyCapsule_GetPointer(capsule, CAPSULE_RECORD_NAME); free(record_handle);}static void capsule_cleanup_transformation(PyObject *capsule) { k4a_transformation_t *transformation = (k4a_transformation_t *)PyCapsule_GetPointer(capsule, CAPSULE_TRANSFORMATION_NAME); k4a_transformation_destroy(*transformation); free(transformation);}static PyObject *device_open(PyObject *self, PyObject *args) { uint32_t device_id; int thread_safe; PyThreadState *thread_state; PyArg_ParseTuple(args, "Ip", &device_id, &thread_safe); k4a_device_t *device_handle = (k4a_device_t *)malloc(sizeof(k4a_device_t)); if (device_handle == NULL) { fprintf(stderr, "Cannot allocate memory"); return Py_BuildValue("IN", K4A_RESULT_FAILED, Py_None); } thread_state = _gil_release(thread_safe); k4a_result_t result = k4a_device_open(device_id, device_handle); _gil_restore(thread_state); if (result == K4A_RESULT_FAILED) { free(device_handle); return Py_BuildValue("IN", result, Py_None); } PyObject *capsule = PyCapsule_New(device_handle, CAPSULE_DEVICE_NAME, capsule_cleanup_device); return Py_BuildValue("IN", result, capsule);}static PyObject *device_get_installed_count(PyObject *self, PyObject *args) { uint32_t count; count = k4a_device_get_installed_count(); return Py_BuildValue("I", count);}static PyObject *device_get_serialnum(PyObject *self, PyObject *args) { k4a_device_t *device_handle; PyObject *capsule; int thread_safe; PyThreadState *thread_state; k4a_buffer_result_t result; size_t data_size; PyArg_ParseTuple(args, "Op", &capsule, &thread_safe); device_handle = (k4a_device_t *)PyCapsule_GetPointer(capsule, CAPSULE_DEVICE_NAME); thread_state = _gil_release(thread_safe); result = k4a_device_get_serialnum(*device_handle, NULL, &data_size); if (result == K4A_BUFFER_RESULT_FAILED) { _gil_restore(thread_state); return Py_BuildValue("s", ""); } char *data = (char *)malloc(data_size); if (data == NULL) { _gil_restore(thread_state); fprintf(stderr, "Cannot allocate memory"); return Py_BuildValue("s", ""); } result = k4a_device_get_serialnum(*device_handle, data, &data_size); if (result != K4A_BUFFER_RESULT_SUCCEEDED) { free(data); return Py_BuildValue("s", ""); } _gil_restore(thread_state); PyObject *res = Py_BuildValue("s", data); free(data); return res;}static PyObject *device_close(PyObject *self, PyObject *args) { k4a_device_t *device_handle; PyObject *capsule; int thread_safe; PyThreadState *thread_state; PyArg_ParseTuple(args, "Op", &capsule, &thread_safe); device_handle = (k4a_device_t *)PyCapsule_GetPointer(capsule, CAPSULE_DEVICE_NAME); thread_state = _gil_release(thread_safe); k4a_device_close(*device_handle); _gil_restore(thread_state); return Py_BuildValue("I", K4A_RESULT_SUCCEEDED);}static PyObject *device_get_sync_jack(PyObject *self, PyObject *args) { k4a_device_t *device_handle; PyObject *capsule; int thread_safe; PyThreadState *thread_state; bool in_jack = 0; bool out_jack = 0; PyArg_ParseTuple(args, "Op", &capsule, &thread_safe); device_handle = (k4a_device_t *)PyCapsule_GetPointer(capsule, CAPSULE_DEVICE_NAME); thread_state = _gil_release(thread_safe); k4a_result_t result = k4a_device_get_sync_jack(*device_handle, &in_jack, &out_jack); _gil_restore(thread_state); return Py_BuildValue("III", result, in_jack, out_jack);}static PyObject *device_get_color_control(PyObject *self, PyObject *args) { k4a_device_t *device_handle; PyObject *capsule; int thread_safe; PyThreadState *thread_state; k4a_color_control_command_t command; k4a_color_control_mode_t mode; int32_t value = 0; PyArg_ParseTuple(args, "OpI", &capsule, &thread_safe, &command); device_handle = (k4a_device_t *)PyCapsule_GetPointer(capsule, CAPSULE_DEVICE_NAME); thread_state = _gil_release(thread_safe); k4a_result_t result = k4a_device_get_color_control(*device_handle, command, &mode, &value); _gil_restore(thread_state); if (result == K4A_RESULT_FAILED) { return Py_BuildValue("IIi", 0, 0, 0); } return Py_BuildValue("IIi", result, mode, value);}static PyObject *device_set_color_control(PyObject *self, PyObject *args) { k4a_device_t *device_handle; PyObject *capsule; int thread_safe; PyThreadState *thread_state; k4a_color_control_command_t command = K4A_COLOR_CONTROL_EXPOSURE_TIME_ABSOLUTE; k4a_color_control_mode_t mode = K4A_COLOR_CONTROL_MODE_MANUAL; int32_t value = 0; PyArg_ParseTuple(args, "OpIIi", &capsule, &thread_safe, &command, &mode, &value); device_handle = (k4a_device_t *)PyCapsule_GetPointer(capsule, CAPSULE_DEVICE_NAME); thread_state = _gil_release(thread_safe); k4a_result_t result = k4a_device_set_color_control(*device_handle, command, mode, value); _gil_restore(thread_state); if (result == K4A_RESULT_FAILED) { return Py_BuildValue("I", K4A_RESULT_FAILED); } return Py_BuildValue("I", result);}static PyObject *device_get_color_control_capabilities(PyObject *self, PyObject *args) { k4a_device_t *device_handle; PyObject *capsule; int thread_safe; PyThreadState *thread_state; k4a_color_control_command_t command; bool supports_auto; int min_value; int max_value; int step_value; int default_value; k4a_color_control_mode_t default_mode; PyArg_ParseTuple(args, "OpI", &capsule, &thread_safe, &command); device_handle = (k4a_device_t *)PyCapsule_GetPointer(capsule, CAPSULE_DEVICE_NAME); thread_state = _gil_release(thread_safe); k4a_result_t result = k4a_device_get_color_control_capabili