Skip to content
This repository was archived by the owner on Sep 22, 2022. It is now read-only.

To add single capture/single frame/snap... #20

Open
wants to merge 1 commit into
base: master
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
57 changes: 57 additions & 0 deletions ids.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,3 +164,60 @@ def color_mode(self, val):
# Free all memory and reallocate, as bitdepth may have changed
self.free_all()
self._allocate_memory()

def singlecapture(self, *args, **kwargs):
"""
Make one image from the camera.

Waits for an image to be available from the camera, and returns
it as a numpy array. Blocks until image is available, or timeout is
reached.

Returns:
(image, metadata) tuple, where image is a numpy array containing
the image in the camera color format, and metadata is a dictionary
with image metadata. Timestamp is provided as a datetime object in
UTC.

Raises:
IDSTimeoutError: An image was not available within the timeout.
IDSError: An unknown error occured in the uEye SDK.
NotImplementedError: The current color format cannot be converted
to a numpy array.
"""
while True:
try:
return super(Camera, self).singlecapture(*args, **kwargs)
except ids_core.IDSCaptureStatus:
self._check_capture_status()

def singlecapture_save(self, *args, **kwargs):
"""
Save one image to a file.

This function behaves similarly to Camera.singlecaptures(), however instead
of returning the image, it uses the IDS functions to save the image
to a file. The appropriate color mode for the filetype should be
used (eg. BGR for JPEG).

Arguments:
filename: File to save image to.
filetype (optional): Filetype to save as, defaults to
ids_core.FILETYPE_JPG.
quality (optional): Image quality for JPEG and PNG,
with 100 as maximum quality.

Returns:
Dictonary containing image metadata. Timestamp is provided as
a datetime object in UTC.

Raises:
ValueError: An invalid filetype was passed in.
IDSTimeoutError: An image was not available within the timeout.
IDSError: An unknown error occured in the uEye SDK.
"""
while True:
try:
return super(Camera, self).singlecapture_save(*args, **kwargs)
except ids_core.IDSCaptureStatus:
self._check_capture_status()
179 changes: 179 additions & 0 deletions ids_core/ids_core_Camera_methods.c
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,152 @@ static PyObject *create_matrix(ids_core_Camera *self, char *mem) {
return (PyObject*)matrix;
}

static int buffer_SingleCapture(ids_core_Camera *self, char **mem, INT *image_id, int timeout) {
int ret;

ret = is_SetExternalTrigger(self->handle, IS_SET_TRIGGER_SOFTWARE);
if (ret) {
PyErr_SetString(PyExc_IOError, "We could not set external trigger!");
return -1;
}

ret = is_FreezeVideo(self->handle, IS_WAIT);
if (ret) {
PyErr_SetString(PyExc_RuntimeError, "We could not save an image to active image memory!");
return -1;
}
ret = is_WaitForNextImage(self->handle, timeout, mem, image_id);
switch (ret) {
case IS_SUCCESS:
break;
case IS_TIMED_OUT:
PyErr_Format(IDSTimeoutError, "Timeout of %dms exceeded", timeout);
return 1;
case IS_CAPTURE_STATUS:
PyErr_SetString(IDSCaptureStatus, "Transfer error. Check capture status.");
return 1;
default:
raise_general_error(self, ret);
return 1;
}
ret = is_SetExternalTrigger(self->handle, IS_SET_TRIGGER_OFF);
if (ret) {
PyErr_SetString(PyExc_IOError, "We could not turn off trigger mode!");
return -1;
}

return 0;
}

static PyObject *ids_core_Camera_singlecapture(ids_core_Camera *self, PyObject *args, PyObject *kwds) {
static char *kwlist[] = {"timeout", NULL};
int ret;
char *mem;
INT image_id;
int timeout = IMG_TIMEOUT;

if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i", kwlist, &timeout)) {
return NULL; // If null is not returned, the exception is queued to return at next command...
}

ret = buffer_SingleCapture(self, &mem, &image_id, timeout);
if (ret) {
/* Exception set, return */
return NULL;
}

PyObject *image = create_matrix(self, mem);
if (!image) {
return NULL;
}

PyObject *info = image_info(self, image_id);
if (!info) {
Py_DECREF(image);
return NULL;
}

ret = is_UnlockSeqBuf(self->handle, image_id, mem);
switch (ret) {
case IS_SUCCESS:
break;
default:
Py_DECREF(image);
Py_DECREF(info);
raise_general_error(self, ret);
return NULL;
}

PyObject *tuple = Py_BuildValue("(OO)", image, info);

/* BuildValue INCREF's these objects, but we don't need them anymore */
Py_DECREF(image);
Py_DECREF(info);

return tuple;
}

static PyObject *ids_core_Camera_singlecapture_save(ids_core_Camera *self, PyObject *args, PyObject *kwds) {
static char *kwlist[] = {"filename", "filetype", "quality", NULL};
char *filename;
wchar_t fancy_filename[256];
int filetype = IS_IMG_JPG;
unsigned int quality = 100;
int timeout = IMG_TIMEOUT;

if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|iI", kwlist, &filename, &filetype, &quality)) {
return NULL;
}

swprintf(fancy_filename, 256, L"%hs", filename);

if (filetype != IS_IMG_JPG && filetype != IS_IMG_PNG && filetype != IS_IMG_BMP) {
PyErr_SetString(PyExc_ValueError, "Invalid image filetype");
}

int ret;
char *mem;
INT image_id;

ret = buffer_SingleCapture(self, &mem, &image_id, timeout);
if (ret) {
/* Exception set, return */
return NULL;
}

IMAGE_FILE_PARAMS ImageFileParams;
ImageFileParams.pwchFileName = fancy_filename;
ImageFileParams.nFileType = filetype;
ImageFileParams.nQuality = quality;
ImageFileParams.ppcImageMem = &mem;
ImageFileParams.pnImageID = (UINT*) &image_id;
ret = is_ImageFile(self->handle, IS_IMAGE_FILE_CMD_SAVE, (void*)&ImageFileParams, sizeof(ImageFileParams));
switch (ret) {
case IS_SUCCESS:
break;
default:
raise_general_error(self, ret);
return NULL;
}

PyObject *info = image_info(self, image_id);
if (!info) {
return NULL;
}

ret = is_UnlockSeqBuf(self->handle, image_id, mem);
switch (ret) {
case IS_SUCCESS:
break;
default:
Py_DECREF(info);
raise_general_error(self, ret);
return NULL;
}

return info;
}

PyMethodDef ids_core_Camera_methods[] = {
{"capture_status", (PyCFunction) ids_core_Camera_capture_status, METH_NOARGS,
"capture_status() -> status\n\n"
Expand Down Expand Up @@ -409,5 +555,38 @@ PyMethodDef ids_core_Camera_methods[] = {
" NotImplementedError: The current color format cannot be converted\n"
" to a numpy array."
},
{"singlecapture", (PyCFunction) ids_core_Camera_singlecapture, METH_VARARGS | METH_KEYWORDS,
"singlecapture() -> image, metadata\n"
"or\n"
"singlecapture(processingTimeout) -> image, metadata\n\n"
"Makes one image.\n\n"
"Makes one image as a Numpy array\n"
"Blocks until image is available, or timeout occurs.\n\n"
"Returns:\n"
" (image, metadata) tuple, where image is a Numpy array containing\n"
" the image, and metadata is a dictionary containing image metadata.\n"
" Timestamp is provided as a UTC datetime object\n\n"
"Raises:\n"
" IDSTimeoutError: An image was not available within the timeout.\n"
" IDSError: An unknown error occured in the uEye SDK."
" NotImplementedError: The current color format cannot be converted\n"
" to a numpy array."
},
{"singlecapture_save", (PyCFunction) ids_core_Camera_singlecapture_save, METH_VARARGS | METH_KEYWORDS,
"singlecapture_save(filename [, filetype=ids_core.FILETYPE_JPG, quality=100]) -> metadata\n\n"
"Saves one image.\n\n"
"Using the uEye SDK image saving functions to save one image\n"
"image to disk. Blocks until image is available, or timeout occurs.\n\n"
"Arguments:\n"
" filename: File to save image to.\n"
" filetype: Filetype to save as, one of ids_core.FILETYPE_*\n"
" quality: Image quality for JPEG and PNG, with 100 as maximum quality\n\n"
"Returns:\n"
" Dictionary containing image metadata. Timestamp is provided in UTC.\n\n"
"Raises:\n"
" ValueError: Invalid filetype.\n"
" IDSTimeoutError: An image was not available within the timeout.\n"
" IDSError: An unknown error occured in the uEye SDK."
},
{NULL}
};