Commit c20b5847 authored by Manuel Günther's avatar Manuel Günther

Handled color images in GeomNorm bindings

parent 13340f1d
Pipeline #11469 passed with stages
in 17 minutes and 15 seconds
......@@ -252,16 +252,25 @@ static auto process = bob::extension::FunctionDoc(
.add_return("transformed", "uint16", "The resulting GeomNorm code at the given position in the image")
;
template <typename T>
template <typename T,int N>
static PyObject* process_inner(PyBobIpBaseGeomNormObject* self, PyBlitzArrayObject* input, PyBlitzArrayObject* input_mask, PyBlitzArrayObject* output, PyBlitzArrayObject* output_mask, const blitz::TinyVector<double,2>& offset){
if (input_mask && output_mask){
self->cxx->process(*PyBlitzArrayCxx_AsBlitz<T,2>(input), *PyBlitzArrayCxx_AsBlitz<bool,2>(input_mask), *PyBlitzArrayCxx_AsBlitz<double,2>(output), *PyBlitzArrayCxx_AsBlitz<bool,2>(output_mask), offset);
self->cxx->process(*PyBlitzArrayCxx_AsBlitz<T,N>(input), *PyBlitzArrayCxx_AsBlitz<bool,N>(input_mask), *PyBlitzArrayCxx_AsBlitz<double,N>(output), *PyBlitzArrayCxx_AsBlitz<bool,N>(output_mask), offset);
} else {
self->cxx->process(*PyBlitzArrayCxx_AsBlitz<T,2>(input), *PyBlitzArrayCxx_AsBlitz<double,2>(output), offset);
self->cxx->process(*PyBlitzArrayCxx_AsBlitz<T,N>(input), *PyBlitzArrayCxx_AsBlitz<double,N>(output), offset);
}
Py_RETURN_NONE;
}
template <typename T>
static PyObject* process_inner1(PyBobIpBaseGeomNormObject* self, PyBlitzArrayObject* input, PyBlitzArrayObject* input_mask, PyBlitzArrayObject* output, PyBlitzArrayObject* output_mask, const blitz::TinyVector<double,2>& offset){
switch (input->ndim){
case 2: return process_inner<T,2>(self, input, input_mask, output, output_mask, offset);
case 3: return process_inner<T,3>(self, input, input_mask, output, output_mask, offset);
default: return 0;// already handled
}
}
static PyObject* PyBobIpBaseGeomNorm_process(PyBobIpBaseGeomNormObject* self, PyObject* args, PyObject* kwargs) {
BOB_TRY
char** kwlist1 = process.kwlist(0);
......@@ -343,9 +352,9 @@ static PyObject* PyBobIpBaseGeomNorm_process(PyBobIpBaseGeomNormObject* self, Py
// finally, process the data
switch (input->type_num){
case NPY_UINT8: return process_inner<uint8_t>(self, input, input_mask, output, output_mask, center);
case NPY_UINT16: return process_inner<uint16_t>(self, input, input_mask, output, output_mask, center);
case NPY_FLOAT64: return process_inner<double>(self, input, input_mask, output, output_mask, center);
case NPY_UINT8: return process_inner1<uint8_t>(self, input, input_mask, output, output_mask, center);
case NPY_UINT16: return process_inner1<uint16_t>(self, input, input_mask, output, output_mask, center);
case NPY_FLOAT64: return process_inner1<double>(self, input, input_mask, output, output_mask, center);
default:
PyErr_Format(PyExc_TypeError, "`%s' input array of type %s are currently not supported", Py_TYPE(self)->tp_name, PyBlitzArray_TypenumAsString(input->type_num));
process.print_usage();
......
......@@ -330,6 +330,33 @@ def test_geom_norm_position():
assert numpy.allclose(rotated, (40 - 5. * math.sqrt(2.) * 2, 80. ))
def test_geom_norm_color():
# tests the geom-norm functionality (copied from old C++ tests)
test_image = bob.io.base.load(bob.io.base.test_utils.datafile("image_r10.hdf5", "bob.ip.base", "data/affine"))
test_image = numpy.array([test_image, test_image, test_image])
processed = numpy.ndarray((3, 40, 40))
# Define a Geometric normalizer
# * rotation angle: 10 degrees
# * scaling factor: 0.65
# * Cropping area: 40x40
geom_norm = bob.ip.base.GeomNorm(-10., 0.65, (40, 40), (0, 0))
# Process giving the upper left corner as the rotation center (and the offset of the cropping area)
geom_norm(test_image, processed, (54, 27));
# compute normalized image
normalized = numpy.round(processed).astype(numpy.uint8)
# This is the actual test image that was copied from the old implementation of Bob
reference_file = bob.io.base.test_utils.datafile("image_r10_geom_norm.hdf5", "bob.ip.base", "data/affine")
reference_image = bob.io.base.load(reference_file)
for i in range(3):
assert numpy.allclose(normalized[i], reference_image)
###############################################
########## FaceEyesNorm #######################
###############################################
......@@ -357,15 +384,15 @@ def test_face_eyes_norm():
reference_image = bob.io.base.load(reference_file)
assert numpy.allclose(normalized, reference_image)
# check that the color conversion also works
color = numpy.array((test_image, test_image, test_image))
processed = fen(color, right_eye, left_eye)
assert processed.ndim == 3
normalized = numpy.round(processed).astype(numpy.uint8)
assert all(numpy.allclose(normalized[i], reference_image) for i in range(3))
# check that the eye positions are actually alligned correctly
center = ((right_eye[0] + left_eye[0]) / 2., (right_eye[1] + left_eye[1]) / 2.)
......@@ -382,5 +409,3 @@ def test_face_eyes_norm():
processed = fen(test_image, right_eye, left_eye)
normalized = numpy.round(processed).astype(numpy.uint8)
assert numpy.allclose(normalized, reference_image)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment