diff options
author | Chien-Yu Chen <cychen@google.com> | 2014-11-17 18:51:44 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2014-11-17 18:51:44 +0000 |
commit | 3171f4e12e5cabb2b496be6aa660aaa83e8fe77d (patch) | |
tree | 2a7457d5c3822951d182d4371cd9d62e61e7f9c3 /services | |
parent | addfc718ff85115355060d6b07ca67b41a3765c2 (diff) | |
parent | 5e15b80e801a0110bc1bad1190f02cb9c7d22e37 (diff) | |
download | frameworks_av-3171f4e12e5cabb2b496be6aa660aaa83e8fe77d.zip frameworks_av-3171f4e12e5cabb2b496be6aa660aaa83e8fe77d.tar.gz frameworks_av-3171f4e12e5cabb2b496be6aa660aaa83e8fe77d.tar.bz2 |
Merge "CameraService: normalize face rectangles properly" into lmp-mr1-dev
Diffstat (limited to 'services')
3 files changed, 90 insertions, 73 deletions
diff --git a/services/camera/libcameraservice/api1/client2/FrameProcessor.cpp b/services/camera/libcameraservice/api1/client2/FrameProcessor.cpp index 312a78c..40d53b3 100644 --- a/services/camera/libcameraservice/api1/client2/FrameProcessor.cpp +++ b/services/camera/libcameraservice/api1/client2/FrameProcessor.cpp @@ -168,6 +168,19 @@ status_t FrameProcessor::processFaceDetect(const CameraMetadata &frame, faceIds = entry.data.i32; } + entry = frame.find(ANDROID_SCALER_CROP_REGION); + if (entry.count < 4) { + ALOGE("%s: Camera %d: Unable to read crop region (count = %d)", + __FUNCTION__, client->getCameraId(), entry.count); + return res; + } + + Parameters::CropRegion scalerCrop = { + static_cast<float>(entry.data.i32[0]), + static_cast<float>(entry.data.i32[1]), + static_cast<float>(entry.data.i32[2]), + static_cast<float>(entry.data.i32[3])}; + faces.setCapacity(metadata.number_of_faces); size_t maxFaces = metadata.number_of_faces; @@ -183,26 +196,30 @@ status_t FrameProcessor::processFaceDetect(const CameraMetadata &frame, camera_face_t face; - face.rect[0] = l.mParameters.arrayXToNormalized(faceRects[i*4 + 0]); - face.rect[1] = l.mParameters.arrayYToNormalized(faceRects[i*4 + 1]); - face.rect[2] = l.mParameters.arrayXToNormalized(faceRects[i*4 + 2]); - face.rect[3] = l.mParameters.arrayYToNormalized(faceRects[i*4 + 3]); + face.rect[0] = l.mParameters.arrayXToNormalizedWithCrop( + faceRects[i*4 + 0], scalerCrop); + face.rect[1] = l.mParameters.arrayYToNormalizedWithCrop( + faceRects[i*4 + 1], scalerCrop); + face.rect[2] = l.mParameters.arrayXToNormalizedWithCrop( + faceRects[i*4 + 2], scalerCrop); + face.rect[3] = l.mParameters.arrayYToNormalizedWithCrop( + faceRects[i*4 + 3], scalerCrop); face.score = faceScores[i]; if (faceDetectMode == ANDROID_STATISTICS_FACE_DETECT_MODE_FULL) { face.id = faceIds[i]; - face.left_eye[0] = - l.mParameters.arrayXToNormalized(faceLandmarks[i*6 + 0]); - face.left_eye[1] = - l.mParameters.arrayYToNormalized(faceLandmarks[i*6 + 1]); - face.right_eye[0] = - l.mParameters.arrayXToNormalized(faceLandmarks[i*6 + 2]); - face.right_eye[1] = - l.mParameters.arrayYToNormalized(faceLandmarks[i*6 + 3]); - face.mouth[0] = - l.mParameters.arrayXToNormalized(faceLandmarks[i*6 + 4]); - face.mouth[1] = - l.mParameters.arrayYToNormalized(faceLandmarks[i*6 + 5]); + face.left_eye[0] = l.mParameters.arrayXToNormalizedWithCrop( + faceLandmarks[i*6 + 0], scalerCrop); + face.left_eye[1] = l.mParameters.arrayYToNormalizedWithCrop( + faceLandmarks[i*6 + 1], scalerCrop); + face.right_eye[0] = l.mParameters.arrayXToNormalizedWithCrop( + faceLandmarks[i*6 + 2], scalerCrop); + face.right_eye[1] = l.mParameters.arrayYToNormalizedWithCrop( + faceLandmarks[i*6 + 3], scalerCrop); + face.mouth[0] = l.mParameters.arrayXToNormalizedWithCrop( + faceLandmarks[i*6 + 4], scalerCrop); + face.mouth[1] = l.mParameters.arrayYToNormalizedWithCrop( + faceLandmarks[i*6 + 5], scalerCrop); } else { face.id = 0; face.left_eye[0] = face.left_eye[1] = -2000; diff --git a/services/camera/libcameraservice/api1/client2/Parameters.cpp b/services/camera/libcameraservice/api1/client2/Parameters.cpp index 42a5507..74bbb9d 100644 --- a/services/camera/libcameraservice/api1/client2/Parameters.cpp +++ b/services/camera/libcameraservice/api1/client2/Parameters.cpp @@ -2619,75 +2619,71 @@ int Parameters::normalizedYToCrop(int y) const { return (y + 1000) * (previewCrop.height - 1) / 2000; } -int Parameters::arrayXToCrop(int x) const { - CropRegion previewCrop = calculateCropRegion(CropRegion::OUTPUT_PREVIEW); - return x - previewCrop.left; -} - -int Parameters::arrayYToCrop(int y) const { - CropRegion previewCrop = calculateCropRegion(CropRegion::OUTPUT_PREVIEW); - return y - previewCrop.top; -} +int Parameters::normalizedXToArray(int x) const { -int Parameters::cropXToNormalized(int x) const { - CropRegion previewCrop = calculateCropRegion(CropRegion::OUTPUT_PREVIEW); - return x * 2000 / (previewCrop.width - 1) - 1000; -} + // Work-around for HAL pre-scaling the coordinates themselves + if (quirks.meteringCropRegion) { + return (x + 1000) * (fastInfo.arrayWidth - 1) / 2000; + } -int Parameters::cropYToNormalized(int y) const { - CropRegion previewCrop = calculateCropRegion(CropRegion::OUTPUT_PREVIEW); - return y * 2000 / (previewCrop.height - 1) - 1000; + return cropXToArray(normalizedXToCrop(x)); } -int Parameters::arrayXToNormalized(int width) const { - int ret = cropXToNormalized(arrayXToCrop(width)); - - ALOG_ASSERT(ret >= -1000, "Calculated normalized value out of " - "lower bounds %d", ret); - ALOG_ASSERT(ret <= 1000, "Calculated normalized value out of " - "upper bounds %d", ret); - +int Parameters::normalizedYToArray(int y) const { // Work-around for HAL pre-scaling the coordinates themselves if (quirks.meteringCropRegion) { - return width * 2000 / (fastInfo.arrayWidth - 1) - 1000; + return (y + 1000) * (fastInfo.arrayHeight - 1) / 2000; } - return ret; + return cropYToArray(normalizedYToCrop(y)); } -int Parameters::arrayYToNormalized(int height) const { - int ret = cropYToNormalized(arrayYToCrop(height)); - ALOG_ASSERT(ret >= -1000, "Calculated normalized value out of lower bounds" - " %d", ret); - ALOG_ASSERT(ret <= 1000, "Calculated normalized value out of upper bounds" - " %d", ret); +Parameters::CropRegion Parameters::calculatePreviewCrop( + const CropRegion &scalerCrop) const { + float left, top, width, height; + float previewAspect = static_cast<float>(previewWidth) / previewHeight; + float cropAspect = scalerCrop.width / scalerCrop.height; - // Work-around for HAL pre-scaling the coordinates themselves - if (quirks.meteringCropRegion) { - return height * 2000 / (fastInfo.arrayHeight - 1) - 1000; + if (previewAspect > cropAspect) { + width = scalerCrop.width; + height = cropAspect * scalerCrop.height / previewAspect; + + left = scalerCrop.left; + top = scalerCrop.top + (scalerCrop.height - height) / 2; + } else { + width = previewAspect * scalerCrop.width / cropAspect; + height = scalerCrop.height; + + left = scalerCrop.left + (scalerCrop.width - width) / 2; + top = scalerCrop.top; } - return ret; -} + CropRegion previewCrop = {left, top, width, height}; -int Parameters::normalizedXToArray(int x) const { + return previewCrop; +} +int Parameters::arrayXToNormalizedWithCrop(int x, + const CropRegion &scalerCrop) const { // Work-around for HAL pre-scaling the coordinates themselves if (quirks.meteringCropRegion) { - return (x + 1000) * (fastInfo.arrayWidth - 1) / 2000; + return x * 2000 / (fastInfo.arrayWidth - 1) - 1000; + } else { + CropRegion previewCrop = calculatePreviewCrop(scalerCrop); + return (x - previewCrop.left) * 2000 / (previewCrop.width - 1) - 1000; } - - return cropXToArray(normalizedXToCrop(x)); } -int Parameters::normalizedYToArray(int y) const { +int Parameters::arrayYToNormalizedWithCrop(int y, + const CropRegion &scalerCrop) const { // Work-around for HAL pre-scaling the coordinates themselves if (quirks.meteringCropRegion) { - return (y + 1000) * (fastInfo.arrayHeight - 1) / 2000; + return y * 2000 / (fastInfo.arrayHeight - 1) - 1000; + } else { + CropRegion previewCrop = calculatePreviewCrop(scalerCrop); + return (y - previewCrop.top) * 2000 / (previewCrop.height - 1) - 1000; } - - return cropYToArray(normalizedYToCrop(y)); } status_t Parameters::getFilteredSizes(Size limit, Vector<Size> *sizes) { diff --git a/services/camera/libcameraservice/api1/client2/Parameters.h b/services/camera/libcameraservice/api1/client2/Parameters.h index 815cc55..389cb92 100644 --- a/services/camera/libcameraservice/api1/client2/Parameters.h +++ b/services/camera/libcameraservice/api1/client2/Parameters.h @@ -325,13 +325,17 @@ struct Parameters { // Note that this doesn't apply to the (deprecated) single FPS value. static const int kFpsToApiScale = 1000; - // Transform between (-1000,-1000)-(1000,1000) normalized coords from camera - // API and HAL2 (0,0)-(activePixelArray.width/height) coordinates - int arrayXToNormalized(int width) const; - int arrayYToNormalized(int height) const; + // Transform from (-1000,-1000)-(1000,1000) normalized coords from camera + // API to HAL2 (0,0)-(activePixelArray.width/height) coordinates int normalizedXToArray(int x) const; int normalizedYToArray(int y) const; + // Transform from HAL3 (0,0)-(activePixelArray.width/height) coordinates to + // (-1000,-1000)-(1000,1000) normalized coordinates given a scaler crop + // region. + int arrayXToNormalizedWithCrop(int x, const CropRegion &scalerCrop) const; + int arrayYToNormalizedWithCrop(int y, const CropRegion &scalerCrop) const; + struct Range { int min; int max; @@ -341,20 +345,20 @@ struct Parameters { private: - // Convert between HAL2 sensor array coordinates and - // viewfinder crop-region relative array coordinates + // Convert from viewfinder crop-region relative array coordinates + // to HAL2 sensor array coordinates int cropXToArray(int x) const; int cropYToArray(int y) const; - int arrayXToCrop(int x) const; - int arrayYToCrop(int y) const; - // Convert between viewfinder crop-region relative array coordinates - // and camera API (-1000,1000)-(1000,1000) normalized coords - int cropXToNormalized(int x) const; - int cropYToNormalized(int y) const; + // Convert from camera API (-1000,1000)-(1000,1000) normalized coords + // to viewfinder crop-region relative array coordinates int normalizedXToCrop(int x) const; int normalizedYToCrop(int y) const; + // Given a scaler crop region, calculate preview crop region based on + // preview aspect ratio. + CropRegion calculatePreviewCrop(const CropRegion &scalerCrop) const; + Vector<Size> availablePreviewSizes; Vector<Size> availableVideoSizes; // Get size list (that are no larger than limit) from static metadata. |