• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ANDROID_SERVERS_DISTORTIONMAPPER_H
18 #define ANDROID_SERVERS_DISTORTIONMAPPER_H
19 
20 #include <utils/Errors.h>
21 #include <array>
22 #include <mutex>
23 
24 #include "camera/CameraMetadata.h"
25 #include "device3/CoordinateMapper.h"
26 
27 namespace android {
28 
29 namespace camera3 {
30 
31 /**
32  * Utilities to transform between raw (distorted) and warped (corrected) coordinate systems
33  * for cameras that support geometric distortion
34  */
35 class DistortionMapper : public CoordinateMapper {
36   public:
37     DistortionMapper();
38 
DistortionMapper(const DistortionMapper & other)39     DistortionMapper(const DistortionMapper& other) :
40             mDistortionMapperInfo(other.mDistortionMapperInfo),
41             mDistortionMapperInfoMaximumResolution(other.mDistortionMapperInfoMaximumResolution) {
42             initRemappedKeys(); }
43 
44     void initRemappedKeys() override;
45 
46     /**
47      * Check whether distortion correction is supported by the camera HAL
48      */
49     static bool isDistortionSupported(const CameraMetadata &deviceInfo);
50 
51     /**
52      * Update static lens calibration info from camera characteristics
53      */
54     status_t setupStaticInfo(const CameraMetadata &deviceInfo);
55 
56     /**
57      * Return whether distortion correction can be applied currently
58      */
59     bool calibrationValid() const;
60 
61     /**
62      * Correct capture request if distortion correction is enabled
63      */
64     status_t correctCaptureRequest(CameraMetadata *request);
65 
66     /**
67      * Correct capture result if distortion correction is enabled
68      */
69     status_t correctCaptureResult(CameraMetadata *request);
70 
71 
72   public: // Visible for testing. Not guarded by mutex; do not use concurrently
73 
74     struct DistortionMapperInfo;
75 
76     /**
77      * Update lens calibration from capture results or equivalent
78      */
79     status_t updateCalibration(const CameraMetadata &result, bool isStatic = false,
80             bool maxResolution = false);
81 
82     /**
83      * Transform from distorted (original) to corrected (warped) coordinates.
84      * Coordinates are transformed in-place
85      *
86      *   coordPairs: A pointer to an array of consecutive (x,y) points
87      *   coordCount: Number of (x,y) pairs to transform
88      *   clamp: Whether to clamp the result to the bounds of the active array
89      *   simple: Whether to do complex correction or just a simple linear map
90      */
91     status_t mapRawToCorrected(int32_t *coordPairs, int coordCount,
92             DistortionMapperInfo *mapperInfo, bool clamp, bool simple = true);
93 
94     /**
95      * Transform from distorted (original) to corrected (warped) coordinates.
96      * Coordinates are transformed in-place
97      *
98      *   rects: A pointer to an array of consecutive (x,y, w, h) rectangles
99      *   rectCount: Number of rectangles to transform
100      *   clamp: Whether to clamp the result to the bounds of the active array
101      *   simple: Whether to do complex correction or just a simple linear map
102      */
103     status_t mapRawRectToCorrected(int32_t *rects, int rectCount,
104           DistortionMapperInfo *mapperInfo, bool clamp, bool simple = true);
105 
106     /**
107      * Transform from corrected (warped) to distorted (original) coordinates.
108      * Coordinates are transformed in-place
109      *
110      *   coordPairs: A pointer to an array of consecutive (x,y) points
111      *   coordCount: Number of (x,y) pairs to transform
112      *   clamp: Whether to clamp the result to the bounds of the precorrection active array
113      *   simple: Whether to do complex correction or just a simple linear map
114      */
115     status_t mapCorrectedToRaw(int32_t* coordPairs, int coordCount,
116             const DistortionMapperInfo *mapperInfo, bool clamp, bool simple = true) const;
117 
118     /**
119      * Transform from corrected (warped) to distorted (original) coordinates.
120      * Coordinates are transformed in-place
121      *
122      *   rects: A pointer to an array of consecutive (x,y, w, h) rectangles
123      *   rectCount: Number of rectangles to transform
124      *   clamp: Whether to clamp the result to the bounds of the precorrection active array
125      *   simple: Whether to do complex correction or just a simple linear map
126      */
127     status_t mapCorrectedRectToRaw(int32_t *rects, int rectCount,
128            const DistortionMapperInfo *mapperInfo, bool clamp, bool simple = true) const;
129 
130     struct GridQuad {
131         // Source grid quad, or null
132         const GridQuad *src;
133         // x,y coordinates of corners, in
134         // clockwise order
135         std::array<float, 8> coords;
136     };
137 
138     struct DistortionMapperInfo {
139         bool mValidMapping = false;
140         bool mValidGrids = false;
141 
142         // intrisic parameters, in pixels
143         float mFx, mFy, mCx, mCy, mS;
144         // pre-calculated inverses for speed
145         float mInvFx, mInvFy;
146         // radial/tangential distortion parameters
147         std::array<float, 5> mK;
148 
149         // pre-correction active array dimensions
150         float mArrayWidth, mArrayHeight;
151         // active array dimensions
152         float mActiveWidth, mActiveHeight;
153         // corner offsets between pre-correction and active arrays
154         float mArrayDiffX, mArrayDiffY;
155 
156         std::vector<GridQuad> mCorrectedGrid;
157         std::vector<GridQuad> mDistortedGrid;
158     };
159 
160     // Find which grid quad encloses the point; returns null if none do
161     static const GridQuad* findEnclosingQuad(
162             const int32_t pt[2], const std::vector<GridQuad>& grid);
163 
164     // Calculate 'horizontal' interpolation coordinate for the point and the quad
165     // Assumes the point P is within the quad Q.
166     // Given quad with points P1-P4, and edges E12-E41, and considering the edge segments as
167     // functions of U: E12(u), where E12(0) = P1 and E12(1) = P2, then we want to find a u
168     // such that the edge E12(u) -> E43(u) contains point P.
169     // This can be determined by checking if the cross product of vector [E12(u)-E43(u)] and
170     // vector [E12(u)-P] is zero. Solving the equation
171     // [E12(u)-E43(u)] x [E12(u)-P] = 0 gives a quadratic equation in u; the solution in the range
172     // 0 to 1 is the one chosen.
173     // If calculateU is true, then an interpolation coordinate for edges E12 and E43 is found;
174     // if it is false, then an interpolation coordinate for edges E14 and E23 is found.
175     static float calculateUorV(const int32_t pt[2], const GridQuad& quad, bool calculateU);
176 
177     DistortionMapperInfo *getMapperInfo(bool maxResolution = false) {
178           return maxResolution ? &mDistortionMapperInfoMaximumResolution :
179                   &mDistortionMapperInfo;
180     };
181 
182   private:
183     mutable std::mutex mMutex;
184 
185     // Number of quads in each dimension of the mapping grids
186     constexpr static size_t kGridSize = 15;
187     // Margin to expand the grid by to ensure it doesn't clip the domain
188     constexpr static float kGridMargin = 0.05f;
189     // Fuzziness for float inequality tests
190     constexpr static float kFloatFuzz = 1e-4;
191 
192     bool mMaxResolution = false;
193 
194     status_t setupStaticInfoLocked(const CameraMetadata &deviceInfo, bool maxResolution);
195 
196     // Single implementation for various mapCorrectedToRaw methods
197     template<typename T>
198     status_t mapCorrectedToRawImpl(T* coordPairs, int coordCount,
199             const DistortionMapperInfo *mapperInfo, bool clamp, bool simple) const;
200 
201     // Simple linear interpolation option
202     template<typename T>
203     status_t mapCorrectedToRawImplSimple(T* coordPairs, int coordCount,
204             const DistortionMapperInfo *mapperInfo, bool clamp) const;
205 
206     status_t mapRawToCorrectedSimple(int32_t *coordPairs, int coordCount,
207             const DistortionMapperInfo *mapperInfo, bool clamp) const;
208 
209     // Utility to create reverse mapping grids
210     status_t buildGrids(DistortionMapperInfo *mapperInfo);
211 
212     DistortionMapperInfo mDistortionMapperInfo;
213     DistortionMapperInfo mDistortionMapperInfoMaximumResolution;
214 
215 }; // class DistortionMapper
216 
217 } // namespace camera3
218 
219 } // namespace android
220 
221 #endif
222