You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
204 lines
7.6 KiB
204 lines
7.6 KiB
/*
|
|
* Copyright (C) 2018 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#ifndef ANDROID_SERVERS_DISTORTIONMAPPER_H
|
|
#define ANDROID_SERVERS_DISTORTIONMAPPER_H
|
|
|
|
#include <utils/Errors.h>
|
|
#include <array>
|
|
#include <mutex>
|
|
|
|
#include "camera/CameraMetadata.h"
|
|
#include "device3/CoordinateMapper.h"
|
|
|
|
namespace android {
|
|
|
|
namespace camera3 {
|
|
|
|
/**
|
|
* Utilities to transform between raw (distorted) and warped (corrected) coordinate systems
|
|
* for cameras that support geometric distortion
|
|
*/
|
|
class DistortionMapper : private CoordinateMapper {
|
|
public:
|
|
DistortionMapper();
|
|
|
|
DistortionMapper(const DistortionMapper& other) :
|
|
mValidMapping(other.mValidMapping), mValidGrids(other.mValidGrids),
|
|
mFx(other.mFx), mFy(other.mFy), mCx(other.mCx), mCy(other.mCy), mS(other.mS),
|
|
mInvFx(other.mInvFx), mInvFy(other.mInvFy), mK(other.mK),
|
|
mArrayWidth(other.mArrayWidth), mArrayHeight(other.mArrayHeight),
|
|
mActiveWidth(other.mActiveWidth), mActiveHeight(other.mActiveHeight),
|
|
mArrayDiffX(other.mArrayDiffX), mArrayDiffY(other.mArrayDiffY),
|
|
mCorrectedGrid(other.mCorrectedGrid), mDistortedGrid(other.mDistortedGrid) {}
|
|
|
|
/**
|
|
* Check whether distortion correction is supported by the camera HAL
|
|
*/
|
|
static bool isDistortionSupported(const CameraMetadata &deviceInfo);
|
|
|
|
/**
|
|
* Update static lens calibration info from camera characteristics
|
|
*/
|
|
status_t setupStaticInfo(const CameraMetadata &deviceInfo);
|
|
|
|
/**
|
|
* Return whether distortion correction can be applied currently
|
|
*/
|
|
bool calibrationValid() const;
|
|
|
|
/**
|
|
* Correct capture request if distortion correction is enabled
|
|
*/
|
|
status_t correctCaptureRequest(CameraMetadata *request);
|
|
|
|
/**
|
|
* Correct capture result if distortion correction is enabled
|
|
*/
|
|
status_t correctCaptureResult(CameraMetadata *request);
|
|
|
|
|
|
public: // Visible for testing. Not guarded by mutex; do not use concurrently
|
|
/**
|
|
* Update lens calibration from capture results or equivalent
|
|
*/
|
|
status_t updateCalibration(const CameraMetadata &result);
|
|
|
|
/**
|
|
* Transform from distorted (original) to corrected (warped) coordinates.
|
|
* Coordinates are transformed in-place
|
|
*
|
|
* coordPairs: A pointer to an array of consecutive (x,y) points
|
|
* coordCount: Number of (x,y) pairs to transform
|
|
* clamp: Whether to clamp the result to the bounds of the active array
|
|
* simple: Whether to do complex correction or just a simple linear map
|
|
*/
|
|
status_t mapRawToCorrected(int32_t *coordPairs, int coordCount, bool clamp,
|
|
bool simple = true);
|
|
|
|
/**
|
|
* Transform from distorted (original) to corrected (warped) coordinates.
|
|
* Coordinates are transformed in-place
|
|
*
|
|
* rects: A pointer to an array of consecutive (x,y, w, h) rectangles
|
|
* rectCount: Number of rectangles to transform
|
|
* clamp: Whether to clamp the result to the bounds of the active array
|
|
* simple: Whether to do complex correction or just a simple linear map
|
|
*/
|
|
status_t mapRawRectToCorrected(int32_t *rects, int rectCount, bool clamp,
|
|
bool simple = true);
|
|
|
|
/**
|
|
* Transform from corrected (warped) to distorted (original) coordinates.
|
|
* Coordinates are transformed in-place
|
|
*
|
|
* coordPairs: A pointer to an array of consecutive (x,y) points
|
|
* coordCount: Number of (x,y) pairs to transform
|
|
* clamp: Whether to clamp the result to the bounds of the precorrection active array
|
|
* simple: Whether to do complex correction or just a simple linear map
|
|
*/
|
|
status_t mapCorrectedToRaw(int32_t* coordPairs, int coordCount, bool clamp,
|
|
bool simple = true) const;
|
|
|
|
/**
|
|
* Transform from corrected (warped) to distorted (original) coordinates.
|
|
* Coordinates are transformed in-place
|
|
*
|
|
* rects: A pointer to an array of consecutive (x,y, w, h) rectangles
|
|
* rectCount: Number of rectangles to transform
|
|
* clamp: Whether to clamp the result to the bounds of the precorrection active array
|
|
* simple: Whether to do complex correction or just a simple linear map
|
|
*/
|
|
status_t mapCorrectedRectToRaw(int32_t *rects, int rectCount, bool clamp,
|
|
bool simple = true) const;
|
|
|
|
struct GridQuad {
|
|
// Source grid quad, or null
|
|
const GridQuad *src;
|
|
// x,y coordinates of corners, in
|
|
// clockwise order
|
|
std::array<float, 8> coords;
|
|
};
|
|
|
|
// Find which grid quad encloses the point; returns null if none do
|
|
static const GridQuad* findEnclosingQuad(
|
|
const int32_t pt[2], const std::vector<GridQuad>& grid);
|
|
|
|
// Calculate 'horizontal' interpolation coordinate for the point and the quad
|
|
// Assumes the point P is within the quad Q.
|
|
// Given quad with points P1-P4, and edges E12-E41, and considering the edge segments as
|
|
// functions of U: E12(u), where E12(0) = P1 and E12(1) = P2, then we want to find a u
|
|
// such that the edge E12(u) -> E43(u) contains point P.
|
|
// This can be determined by checking if the cross product of vector [E12(u)-E43(u)] and
|
|
// vector [E12(u)-P] is zero. Solving the equation
|
|
// [E12(u)-E43(u)] x [E12(u)-P] = 0 gives a quadratic equation in u; the solution in the range
|
|
// 0 to 1 is the one chosen.
|
|
// If calculateU is true, then an interpolation coordinate for edges E12 and E43 is found;
|
|
// if it is false, then an interpolation coordinate for edges E14 and E23 is found.
|
|
static float calculateUorV(const int32_t pt[2], const GridQuad& quad, bool calculateU);
|
|
|
|
private:
|
|
mutable std::mutex mMutex;
|
|
|
|
// Number of quads in each dimension of the mapping grids
|
|
constexpr static size_t kGridSize = 15;
|
|
// Margin to expand the grid by to ensure it doesn't clip the domain
|
|
constexpr static float kGridMargin = 0.05f;
|
|
// Fuzziness for float inequality tests
|
|
constexpr static float kFloatFuzz = 1e-4;
|
|
|
|
// Single implementation for various mapCorrectedToRaw methods
|
|
template<typename T>
|
|
status_t mapCorrectedToRawImpl(T* coordPairs, int coordCount, bool clamp, bool simple) const;
|
|
|
|
// Simple linear interpolation option
|
|
template<typename T>
|
|
status_t mapCorrectedToRawImplSimple(T* coordPairs, int coordCount, bool clamp) const;
|
|
|
|
status_t mapRawToCorrectedSimple(int32_t *coordPairs, int coordCount, bool clamp) const;
|
|
|
|
// Utility to create reverse mapping grids
|
|
status_t buildGrids();
|
|
|
|
|
|
bool mValidMapping;
|
|
bool mValidGrids;
|
|
|
|
// intrisic parameters, in pixels
|
|
float mFx, mFy, mCx, mCy, mS;
|
|
// pre-calculated inverses for speed
|
|
float mInvFx, mInvFy;
|
|
// radial/tangential distortion parameters
|
|
std::array<float, 5> mK;
|
|
|
|
// pre-correction active array dimensions
|
|
float mArrayWidth, mArrayHeight;
|
|
// active array dimensions
|
|
float mActiveWidth, mActiveHeight;
|
|
// corner offsets between pre-correction and active arrays
|
|
float mArrayDiffX, mArrayDiffY;
|
|
|
|
std::vector<GridQuad> mCorrectedGrid;
|
|
std::vector<GridQuad> mDistortedGrid;
|
|
|
|
}; // class DistortionMapper
|
|
|
|
} // namespace camera3
|
|
|
|
} // namespace android
|
|
|
|
#endif
|