Skip to content
Snippets Groups Projects
Commit 1438763f authored by André Anjos's avatar André Anjos :speech_balloon:
Browse files

Merge branch '7-full-image-does-not-work-in-locate' into 'master'

Resolve "Full image does not work in locate()"

Closes #7 

I have implemented the default values for the bounding box and solved the issue that happened when the (automatically extended) bounding box was outside the image boundaries.

See merge request !10
parents 248fd3a6 d6e2e8e1
No related branches found
No related tags found
1 merge request!10Resolve "Full image does not work in locate()"
Pipeline #
...@@ -921,7 +921,7 @@ void flandmark_maximize_gdotprod(double * maximum, double * idx, const double * ...@@ -921,7 +921,7 @@ void flandmark_maximize_gdotprod(double * maximum, double * idx, const double *
void flandmark_imcrop(const blitz::Array<uint8_t, 2>& input, blitz::Array<uint8_t,2>& output, int* bbx) void flandmark_imcrop(const blitz::Array<uint8_t, 2>& input, blitz::Array<uint8_t,2>& output, int* bbx)
{ {
if (bbx[0] < 0 or bbx[2] >= input.extent(0) or bbx[1] < 0 or bbx[3] >= input.extent(1)) if (bbx[0] < 0 or bbx[2] > input.extent(0) or bbx[1] < 0 or bbx[3] > input.extent(1))
throw std::runtime_error("Bounding box exceeds image resolution"); throw std::runtime_error("Bounding box exceeds image resolution");
output.resize(bbx[2]-bbx[0], bbx[3]-bbx[1]); output.resize(bbx[2]-bbx[0], bbx[3]-bbx[1]);
...@@ -947,6 +947,12 @@ void flandmark_get_normalized_image_frame(const blitz::Array<uint8_t, 2>& input, ...@@ -947,6 +947,12 @@ void flandmark_get_normalized_image_frame(const blitz::Array<uint8_t, 2>& input,
corrected_bbx[2] = int(c[0] + nd[0]/2.); corrected_bbx[2] = int(c[0] + nd[0]/2.);
corrected_bbx[3] = int(c[1] + nd[1]/2.); corrected_bbx[3] = int(c[1] + nd[1]/2.);
// if extended bbx is larger than the image, reduce it
corrected_bbx[0] = std::max(corrected_bbx[0], 0);
corrected_bbx[1] = std::max(corrected_bbx[1], 0);
corrected_bbx[2] = std::min(corrected_bbx[2], bbox[2]);
corrected_bbx[3] = std::min(corrected_bbx[3], bbox[3]);
blitz::Array<uint8_t, 2> croppedImage; blitz::Array<uint8_t, 2> croppedImage;
blitz::Array<double, 2> scaledImage(model->data.options.bw[1], model->data.options.bw[0]); blitz::Array<double, 2> scaledImage(model->data.options.bw[1], model->data.options.bw[0]);
......
Source diff could not be displayed: it is too large. Options to address this: view the blob.
...@@ -122,8 +122,8 @@ static auto s_locate = bob::extension::FunctionDoc( ...@@ -122,8 +122,8 @@ static auto s_locate = bob::extension::FunctionDoc(
) )
.add_prototype("image, y, x, height, width", "landmarks") .add_prototype("image, y, x, height, width", "landmarks")
.add_parameter("image", "array-like (2D, uint8)", "The image Flandmark will operate on") .add_parameter("image", "array-like (2D, uint8)", "The image Flandmark will operate on")
.add_parameter("y, x", "int", "The top left-most corner of the bounding box containing the face image you want to locate keypoints on.") .add_parameter("y, x", "int", "The top left-most corner of the bounding box containing the face image you want to locate keypoints on, defaults to 0.")
.add_parameter("height, width", "int", "The dimensions accross ``y`` (height) and ``x`` (width) for the bounding box, in number of pixels.") .add_parameter("height, width", "int", "The dimensions accross ``y`` (height) and ``x`` (width) for the bounding box, in number of pixels; defaults to full image resolution.")
.add_return("landmarks", "array (2D, float64)", "Each row in the output array contains the locations of keypoints in the format ``(y, x)``") .add_return("landmarks", "array (2D, float64)", "Each row in the output array contains the locations of keypoints in the format ``(y, x)``")
; ;
...@@ -132,13 +132,10 @@ BOB_TRY ...@@ -132,13 +132,10 @@ BOB_TRY
char** kwlist = s_locate.kwlist(); char** kwlist = s_locate.kwlist();
PyBlitzArrayObject* image; PyBlitzArrayObject* image;
int bbx[4]; int bbx[] = {0,0,-1,-1};
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&iiii", kwlist, &PyBlitzArray_Converter, &image, &bbx[0], &bbx[1], &bbx[2], &bbx[3])) return 0; if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&|iiii", kwlist, &PyBlitzArray_Converter, &image, &bbx[0], &bbx[1], &bbx[2], &bbx[3])) return 0;
// create bounding box in format (top, left, bottom, right)
bbx[2] += bbx[0] - 1;
bbx[3] += bbx[1] - 1;
auto image_ = make_safe(image); auto image_ = make_safe(image);
...@@ -148,9 +145,19 @@ BOB_TRY ...@@ -148,9 +145,19 @@ BOB_TRY
return 0; return 0;
} }
auto cxx_image = PyBlitzArrayCxx_AsBlitz<uint8_t, 2>(image);
// create bounding box in format (top, left, bottom, right)
if (bbx[2] < 0)
bbx[2] = cxx_image->extent(0);
if (bbx[3] < 0)
bbx[3] = cxx_image->extent(1);
bbx[2] += bbx[0] - 1;
bbx[3] += bbx[1] - 1;
// detect // detect
std::vector<double> detected(2*self->flandmark->data.options.M); std::vector<double> detected(2*self->flandmark->data.options.M);
bob::ip::flandmark::flandmark_detect(*PyBlitzArrayCxx_AsBlitz<uint8_t, 2>(image), bbx, self->flandmark, &detected[0]); bob::ip::flandmark::flandmark_detect(*cxx_image, bbx, self->flandmark, &detected[0]);
// extract landmarks // extract landmarks
blitz::Array<double, 2> landmarks(self->flandmark->data.options.M, 2); blitz::Array<double, 2> landmarks(self->flandmark->data.options.M, 2);
......
...@@ -101,6 +101,18 @@ def test_lena(): ...@@ -101,6 +101,18 @@ def test_lena():
for k in keypoints: for k in keypoints:
assert is_inside(k, (y, x, height, width), eps=1) assert is_inside(k, (y, x, height, width), eps=1)
def test_full_image():
img = bob.io.base.load(LENA)
gray = bob.ip.color.rgb_to_gray(img)
flm = Flandmark()
lm1 = flm.locate(gray, 0, 0, gray.shape[0], gray.shape[1])
lm2 = flm.locate(gray)
assert all(numpy.allclose(lm1[i],lm2[i]) for i in range(len(lm1)))
def test_multi(): def test_multi():
img = bob.io.base.load(MULTI) img = bob.io.base.load(MULTI)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment