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 26 namespace android { 27 28 namespace camera3 { 29 30 /** 31 * Utilities to transform between raw (distorted) and warped (corrected) coordinate systems 32 * for cameras that support geometric distortion 33 */ 34 class DistortionMapper { 35 public: 36 DistortionMapper(); 37 38 /** 39 * Check whether distortion correction is supported by the camera HAL 40 */ 41 static bool isDistortionSupported(const CameraMetadata &deviceInfo); 42 43 /** 44 * Update static lens calibration info from camera characteristics 45 */ 46 status_t setupStaticInfo(const CameraMetadata &deviceInfo); 47 48 /** 49 * Return whether distortion correction can be applied currently 50 */ 51 bool calibrationValid() const; 52 53 /** 54 * Correct capture request if distortion correction is enabled 55 */ 56 status_t correctCaptureRequest(CameraMetadata *request); 57 58 /** 59 * Correct capture result if distortion correction is enabled 60 */ 61 status_t correctCaptureResult(CameraMetadata *request); 62 63 64 public: // Visible for testing. Not guarded by mutex; do not use concurrently 65 /** 66 * Update lens calibration from capture results or equivalent 67 */ 68 status_t updateCalibration(const CameraMetadata &result); 69 70 /** 71 * Transform from distorted (original) to corrected (warped) coordinates. 72 * Coordinates are transformed in-place 73 * 74 * coordPairs: A pointer to an array of consecutive (x,y) points 75 * coordCount: Number of (x,y) pairs to transform 76 */ 77 status_t mapRawToCorrected(int32_t *coordPairs, int coordCount); 78 79 /** 80 * Transform from distorted (original) to corrected (warped) coordinates. 81 * Coordinates are transformed in-place 82 * 83 * rects: A pointer to an array of consecutive (x,y, w, h) rectangles 84 * rectCount: Number of rectangles to transform 85 */ 86 status_t mapRawRectToCorrected(int32_t *rects, int rectCount); 87 88 /** 89 * Transform from corrected (warped) to distorted (original) coordinates. 90 * Coordinates are transformed in-place 91 * 92 * coordPairs: A pointer to an array of consecutive (x,y) points 93 * coordCount: Number of (x,y) pairs to transform 94 */ 95 template<typename T> 96 status_t mapCorrectedToRaw(T* coordPairs, int coordCount) const; 97 98 /** 99 * Transform from corrected (warped) to distorted (original) coordinates. 100 * Coordinates are transformed in-place 101 * 102 * rects: A pointer to an array of consecutive (x,y, w, h) rectangles 103 * rectCount: Number of rectangles to transform 104 */ 105 status_t mapCorrectedRectToRaw(int32_t *rects, int rectCount) const; 106 107 struct GridQuad { 108 // Source grid quad, or null 109 const GridQuad *src; 110 // x,y coordinates of corners, in 111 // clockwise order 112 std::array<float, 8> coords; 113 }; 114 115 // Find which grid quad encloses the point; returns null if none do 116 static const GridQuad* findEnclosingQuad( 117 const int32_t pt[2], const std::vector<GridQuad>& grid); 118 119 // Calculate 'horizontal' interpolation coordinate for the point and the quad 120 // Assumes the point P is within the quad Q. 121 // Given quad with points P1-P4, and edges E12-E41, and considering the edge segments as 122 // functions of U: E12(u), where E12(0) = P1 and E12(1) = P2, then we want to find a u 123 // such that the edge E12(u) -> E43(u) contains point P. 124 // This can be determined by checking if the cross product of vector [E12(u)-E43(u)] and 125 // vector [E12(u)-P] is zero. Solving the equation 126 // [E12(u)-E43(u)] x [E12(u)-P] = 0 gives a quadratic equation in u; the solution in the range 127 // 0 to 1 is the one chosen. 128 // If calculateU is true, then an interpolation coordinate for edges E12 and E43 is found; 129 // if it is false, then an interpolation coordinate for edges E14 and E23 is found. 130 static float calculateUorV(const int32_t pt[2], const GridQuad& quad, bool calculateU); 131 132 private: 133 mutable std::mutex mMutex; 134 135 // Number of quads in each dimension of the mapping grids 136 constexpr static size_t kGridSize = 15; 137 // Margin to expand the grid by to ensure it doesn't clip the domain 138 constexpr static float kGridMargin = 0.05f; 139 // Fuzziness for float inequality tests 140 constexpr static float kFloatFuzz = 1e-4; 141 142 // Metadata key lists to correct 143 144 // Both capture request and result 145 static const std::array<uint32_t, 3> kMeteringRegionsToCorrect; 146 147 // Only capture request 148 static const std::array<uint32_t, 1> kRequestRectsToCorrect; 149 150 // Only capture result 151 static const std::array<uint32_t, 1> kResultRectsToCorrect; 152 153 // Only for capture results 154 static const std::array<uint32_t, 2> kResultPointsToCorrect; 155 156 // Utility to create reverse mapping grids 157 status_t buildGrids(); 158 159 160 bool mValidMapping; 161 bool mValidGrids; 162 163 // intrisic parameters, in pixels 164 float mFx, mFy, mCx, mCy, mS; 165 // pre-calculated inverses for speed 166 float mInvFx, mInvFy; 167 // radial/tangential distortion parameters 168 float mK[5]; 169 170 // pre-correction active array dimensions 171 int mArrayWidth, mArrayHeight; 172 // active array dimensions 173 int mActiveWidth, mActiveHeight; 174 175 std::vector<GridQuad> mCorrectedGrid; 176 std::vector<GridQuad> mDistortedGrid; 177 178 }; // class DistortionMapper 179 180 } // namespace camera3 181 182 } // namespace android 183 184 #endif 185