Skip to content

Commit

Permalink
To add single capture...
Browse files Browse the repository at this point in the history
This closes ncsuarc#15
  • Loading branch information
Jason Chau committed Feb 23, 2018
1 parent b6eb099 commit 5923f45
Show file tree
Hide file tree
Showing 2 changed files with 236 additions and 0 deletions.
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}
};

0 comments on commit 5923f45

Please sign in to comment.