Merge "Camera: DistortionMapper: Fix to work consistently" into pi-dev

gugelfrei
Eino-Ville Talvala 6 years ago committed by Android (Google) Code Review
commit b50a84b3e1

@ -49,7 +49,7 @@ constexpr std::array<uint32_t, 1> DistortionMapper::kResultRectsToCorrect = {
};
// Only for capture result
constexpr std::array<uint32_t, 2> DistortionMapper::kResultPointsToCorrect = {
constexpr std::array<uint32_t, 2> DistortionMapper::kResultPointsToCorrectNoClamp = {
ANDROID_STATISTICS_FACE_RECTANGLES, // Says rectangles, is really points
ANDROID_STATISTICS_FACE_LANDMARKS,
};
@ -79,12 +79,21 @@ status_t DistortionMapper::setupStaticInfo(const CameraMetadata &deviceInfo) {
array = deviceInfo.find(ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE);
if (array.count != 4) return BAD_VALUE;
mArrayWidth = array.data.i32[2];
mArrayHeight = array.data.i32[3];
float arrayX = static_cast<float>(array.data.i32[0]);
float arrayY = static_cast<float>(array.data.i32[1]);
mArrayWidth = static_cast<float>(array.data.i32[2]);
mArrayHeight = static_cast<float>(array.data.i32[3]);
array = deviceInfo.find(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE);
mActiveWidth = array.data.i32[2];
mActiveHeight = array.data.i32[3];
if (array.count != 4) return BAD_VALUE;
float activeX = static_cast<float>(array.data.i32[0]);
float activeY = static_cast<float>(array.data.i32[1]);
mActiveWidth = static_cast<float>(array.data.i32[2]);
mActiveHeight = static_cast<float>(array.data.i32[3]);
mArrayDiffX = activeX - arrayX;
mArrayDiffY = activeY - arrayY;
return updateCalibration(deviceInfo);
}
@ -111,22 +120,13 @@ status_t DistortionMapper::correctCaptureRequest(CameraMetadata *request) {
if (weight == 0) {
continue;
}
res = mapCorrectedToRaw(e.data.i32 + j, 2);
res = mapCorrectedToRaw(e.data.i32 + j, 2, /*clamp*/true);
if (res != OK) return res;
for (size_t k = 0; k < 4; k+=2) {
int32_t& x = e.data.i32[j + k];
int32_t& y = e.data.i32[j + k + 1];
// Clamp to within active array
x = std::max(0, x);
x = std::min(mActiveWidth - 1, x);
y = std::max(0, y);
y = std::min(mActiveHeight - 1, y);
}
}
}
for (auto rect : kRequestRectsToCorrect) {
e = request->find(rect);
res = mapCorrectedRectToRaw(e.data.i32, e.count / 4);
res = mapCorrectedRectToRaw(e.data.i32, e.count / 4, /*clamp*/true);
if (res != OK) return res;
}
}
@ -156,27 +156,18 @@ status_t DistortionMapper::correctCaptureResult(CameraMetadata *result) {
if (weight == 0) {
continue;
}
res = mapRawToCorrected(e.data.i32 + j, 2);
res = mapRawToCorrected(e.data.i32 + j, 2, /*clamp*/true);
if (res != OK) return res;
for (size_t k = 0; k < 4; k+=2) {
int32_t& x = e.data.i32[j + k];
int32_t& y = e.data.i32[j + k + 1];
// Clamp to within active array
x = std::max(0, x);
x = std::min(mActiveWidth - 1, x);
y = std::max(0, y);
y = std::min(mActiveHeight - 1, y);
}
}
}
for (auto rect : kResultRectsToCorrect) {
e = result->find(rect);
res = mapRawRectToCorrected(e.data.i32, e.count / 4);
res = mapRawRectToCorrected(e.data.i32, e.count / 4, /*clamp*/true);
if (res != OK) return res;
}
for (auto pts : kResultPointsToCorrect) {
for (auto pts : kResultPointsToCorrectNoClamp) {
e = result->find(pts);
res = mapRawToCorrected(e.data.i32, e.count / 2);
res = mapRawToCorrected(e.data.i32, e.count / 2, /*clamp*/false);
if (res != OK) return res;
}
}
@ -232,9 +223,12 @@ status_t DistortionMapper::updateCalibration(const CameraMetadata &result) {
return OK;
}
status_t DistortionMapper::mapRawToCorrected(int32_t *coordPairs, int coordCount) {
status_t DistortionMapper::mapRawToCorrected(int32_t *coordPairs, int coordCount,
bool clamp, bool simple) {
if (!mValidMapping) return INVALID_OPERATION;
if (simple) return mapRawToCorrectedSimple(coordPairs, coordCount, clamp);
if (!mValidGrids) {
status_t res = buildGrids();
if (res != OK) return res;
@ -275,6 +269,12 @@ status_t DistortionMapper::mapRawToCorrected(int32_t *coordPairs, int coordCount
// Interpolate along left edge of corrected quad (which are axis-aligned) for y
float corrY = corrQuad->coords[1] + v * (corrQuad->coords[7] - corrQuad->coords[1]);
// Clamp to within active array
if (clamp) {
corrX = std::min(mActiveWidth - 1, std::max(0.f, corrX));
corrY = std::min(mActiveHeight - 1, std::max(0.f, corrY));
}
coordPairs[i] = static_cast<int32_t>(std::round(corrX));
coordPairs[i + 1] = static_cast<int32_t>(std::round(corrY));
}
@ -282,7 +282,30 @@ status_t DistortionMapper::mapRawToCorrected(int32_t *coordPairs, int coordCount
return OK;
}
status_t DistortionMapper::mapRawRectToCorrected(int32_t *rects, int rectCount) {
status_t DistortionMapper::mapRawToCorrectedSimple(int32_t *coordPairs, int coordCount,
bool clamp) const {
if (!mValidMapping) return INVALID_OPERATION;
float scaleX = mActiveWidth / mArrayWidth;
float scaleY = mActiveHeight / mArrayHeight;
for (int i = 0; i < coordCount * 2; i += 2) {
float x = coordPairs[i];
float y = coordPairs[i + 1];
float corrX = x * scaleX;
float corrY = y * scaleY;
if (clamp) {
corrX = std::min(mActiveWidth - 1, std::max(0.f, corrX));
corrY = std::min(mActiveHeight - 1, std::max(0.f, corrY));
}
coordPairs[i] = static_cast<int32_t>(std::round(corrX));
coordPairs[i + 1] = static_cast<int32_t>(std::round(corrY));
}
return OK;
}
status_t DistortionMapper::mapRawRectToCorrected(int32_t *rects, int rectCount, bool clamp,
bool simple) {
if (!mValidMapping) return INVALID_OPERATION;
for (int i = 0; i < rectCount * 4; i += 4) {
// Map from (l, t, width, height) to (l, t, r, b)
@ -293,7 +316,7 @@ status_t DistortionMapper::mapRawRectToCorrected(int32_t *rects, int rectCount)
rects[i + 1] + rects[i + 3]
};
mapRawToCorrected(coords, 2);
mapRawToCorrected(coords, 2, clamp, simple);
// Map back to (l, t, width, height)
rects[i] = coords[0];
@ -305,14 +328,24 @@ status_t DistortionMapper::mapRawRectToCorrected(int32_t *rects, int rectCount)
return OK;
}
status_t DistortionMapper::mapCorrectedToRaw(int32_t *coordPairs, int coordCount, bool clamp,
bool simple) const {
return mapCorrectedToRawImpl(coordPairs, coordCount, clamp, simple);
}
template<typename T>
status_t DistortionMapper::mapCorrectedToRaw(T *coordPairs, int coordCount) const {
status_t DistortionMapper::mapCorrectedToRawImpl(T *coordPairs, int coordCount, bool clamp,
bool simple) const {
if (!mValidMapping) return INVALID_OPERATION;
if (simple) return mapCorrectedToRawImplSimple(coordPairs, coordCount, clamp);
float activeCx = mCx - mArrayDiffX;
float activeCy = mCy - mArrayDiffY;
for (int i = 0; i < coordCount * 2; i += 2) {
// Move to normalized space
float ywi = (coordPairs[i + 1] - mCy) * mInvFy;
float xwi = (coordPairs[i] - mCx - mS * ywi) * mInvFx;
// Move to normalized space from active array space
float ywi = (coordPairs[i + 1] - activeCy) * mInvFy;
float xwi = (coordPairs[i] - activeCx - mS * ywi) * mInvFx;
// Apply distortion model to calculate raw image coordinates
float rSq = xwi * xwi + ywi * ywi;
float Fr = 1.f + (mK[0] * rSq) + (mK[1] * rSq * rSq) + (mK[2] * rSq * rSq * rSq);
@ -321,6 +354,11 @@ status_t DistortionMapper::mapCorrectedToRaw(T *coordPairs, int coordCount) cons
// Move back to image space
float xr = mFx * xc + mS * yc + mCx;
float yr = mFy * yc + mCy;
// Clamp to within pre-correction active array
if (clamp) {
xr = std::min(mArrayWidth - 1, std::max(0.f, xr));
yr = std::min(mArrayHeight - 1, std::max(0.f, yr));
}
coordPairs[i] = static_cast<T>(std::round(xr));
coordPairs[i + 1] = static_cast<T>(std::round(yr));
@ -329,10 +367,32 @@ status_t DistortionMapper::mapCorrectedToRaw(T *coordPairs, int coordCount) cons
return OK;
}
template status_t DistortionMapper::mapCorrectedToRaw(int32_t*, int) const;
template status_t DistortionMapper::mapCorrectedToRaw(float*, int) const;
template<typename T>
status_t DistortionMapper::mapCorrectedToRawImplSimple(T *coordPairs, int coordCount,
bool clamp) const {
if (!mValidMapping) return INVALID_OPERATION;
float scaleX = mArrayWidth / mActiveWidth;
float scaleY = mArrayHeight / mActiveHeight;
for (int i = 0; i < coordCount * 2; i += 2) {
float x = coordPairs[i];
float y = coordPairs[i + 1];
float rawX = x * scaleX;
float rawY = y * scaleY;
if (clamp) {
rawX = std::min(mArrayWidth - 1, std::max(0.f, rawX));
rawY = std::min(mArrayHeight - 1, std::max(0.f, rawY));
}
coordPairs[i] = static_cast<T>(std::round(rawX));
coordPairs[i + 1] = static_cast<T>(std::round(rawY));
}
return OK;
}
status_t DistortionMapper::mapCorrectedRectToRaw(int32_t *rects, int rectCount) const {
status_t DistortionMapper::mapCorrectedRectToRaw(int32_t *rects, int rectCount, bool clamp,
bool simple) const {
if (!mValidMapping) return INVALID_OPERATION;
for (int i = 0; i < rectCount * 4; i += 4) {
@ -344,7 +404,7 @@ status_t DistortionMapper::mapCorrectedRectToRaw(int32_t *rects, int rectCount)
rects[i + 1] + rects[i + 3]
};
mapCorrectedToRaw(coords, 2);
mapCorrectedToRaw(coords, 2, clamp, simple);
// Map back to (l, t, width, height)
rects[i] = coords[0];
@ -380,7 +440,8 @@ status_t DistortionMapper::buildGrids() {
};
mDistortedGrid[index].src = &mCorrectedGrid[index];
mDistortedGrid[index].coords = mCorrectedGrid[index].coords;
status_t res = mapCorrectedToRaw(mDistortedGrid[index].coords.data(), 4);
status_t res = mapCorrectedToRawImpl(mDistortedGrid[index].coords.data(), 4,
/*clamp*/false, /*simple*/false);
if (res != OK) return res;
}
}

@ -73,8 +73,11 @@ class DistortionMapper {
*
* 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);
status_t mapRawToCorrected(int32_t *coordPairs, int coordCount, bool clamp,
bool simple = true);
/**
* Transform from distorted (original) to corrected (warped) coordinates.
@ -82,8 +85,11 @@ class DistortionMapper {
*
* 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);
status_t mapRawRectToCorrected(int32_t *rects, int rectCount, bool clamp,
bool simple = true);
/**
* Transform from corrected (warped) to distorted (original) coordinates.
@ -91,9 +97,11 @@ class DistortionMapper {
*
* 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
*/
template<typename T>
status_t mapCorrectedToRaw(T* coordPairs, int coordCount) const;
status_t mapCorrectedToRaw(int32_t* coordPairs, int coordCount, bool clamp,
bool simple = true) const;
/**
* Transform from corrected (warped) to distorted (original) coordinates.
@ -101,8 +109,11 @@ class DistortionMapper {
*
* 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) const;
status_t mapCorrectedRectToRaw(int32_t *rects, int rectCount, bool clamp,
bool simple = true) const;
struct GridQuad {
// Source grid quad, or null
@ -150,8 +161,18 @@ class DistortionMapper {
// Only capture result
static const std::array<uint32_t, 1> kResultRectsToCorrect;
// Only for capture results
static const std::array<uint32_t, 2> kResultPointsToCorrect;
// Only for capture results; don't clamp
static const std::array<uint32_t, 2> kResultPointsToCorrectNoClamp;
// 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();
@ -168,9 +189,11 @@ class DistortionMapper {
float mK[5];
// pre-correction active array dimensions
int mArrayWidth, mArrayHeight;
float mArrayWidth, mArrayHeight;
// active array dimensions
int mActiveWidth, mActiveHeight;
float mActiveWidth, mActiveHeight;
// corner offsets between pre-correction and active arrays
float mArrayDiffX, mArrayDiffY;
std::vector<GridQuad> mCorrectedGrid;
std::vector<GridQuad> mDistortedGrid;

@ -30,6 +30,7 @@ using namespace android::camera3;
int32_t testActiveArray[] = {100, 100, 1000, 750};
int32_t testPreCorrActiveArray[] = {90, 90, 1020, 770};
float testICal[] = { 1000.f, 1000.f, 500.f, 500.f, 0.f };
@ -45,14 +46,19 @@ std::array<int32_t, 12> basicCoords = {
};
void setupTestMapper(DistortionMapper *m, float distortion[5]) {
void setupTestMapper(DistortionMapper *m,
float distortion[5], float intrinsics[5],
int32_t activeArray[4], int32_t preCorrectionActiveArray[4]) {
CameraMetadata deviceInfo;
deviceInfo.update(ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE,
testActiveArray, 4);
preCorrectionActiveArray, 4);
deviceInfo.update(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
activeArray, 4);
deviceInfo.update(ANDROID_LENS_INTRINSIC_CALIBRATION,
testICal, 5);
intrinsics, 5);
deviceInfo.update(ANDROID_LENS_DISTORTION,
distortion, 5);
@ -89,6 +95,9 @@ TEST(DistortionMapperTest, Initialization) {
ASSERT_FALSE(m.calibrationValid());
deviceInfo.update(ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE,
testPreCorrActiveArray, 4);
deviceInfo.update(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
testActiveArray, 4);
deviceInfo.update(ANDROID_LENS_INTRINSIC_CALIBRATION,
@ -118,17 +127,19 @@ TEST(DistortionMapperTest, IdentityTransform) {
status_t res;
DistortionMapper m;
setupTestMapper(&m, identityDistortion);
setupTestMapper(&m, identityDistortion, testICal,
/*activeArray*/ testActiveArray,
/*preCorrectionActiveArray*/ testActiveArray);
auto coords = basicCoords;
res = m.mapCorrectedToRaw(coords.data(), 5);
res = m.mapCorrectedToRaw(coords.data(), 5, /*clamp*/true);
ASSERT_EQ(res, OK);
for (size_t i = 0; i < coords.size(); i++) {
EXPECT_EQ(coords[i], basicCoords[i]);
}
res = m.mapRawToCorrected(coords.data(), 5);
res = m.mapRawToCorrected(coords.data(), 5, /*clamp*/true);
ASSERT_EQ(res, OK);
for (size_t i = 0; i < coords.size(); i++) {
@ -137,18 +148,18 @@ TEST(DistortionMapperTest, IdentityTransform) {
std::array<int32_t, 8> rects = {
0, 0, 100, 100,
testActiveArray[2] - 100, testActiveArray[3]-100, 100, 100
testActiveArray[2] - 101, testActiveArray[3] - 101, 100, 100
};
auto rectsOrig = rects;
res = m.mapCorrectedRectToRaw(rects.data(), 2);
res = m.mapCorrectedRectToRaw(rects.data(), 2, /*clamp*/true);
ASSERT_EQ(res, OK);
for (size_t i = 0; i < rects.size(); i++) {
EXPECT_EQ(rects[i], rectsOrig[i]);
}
res = m.mapRawRectToCorrected(rects.data(), 2);
res = m.mapRawRectToCorrected(rects.data(), 2, /*clamp*/true);
ASSERT_EQ(res, OK);
for (size_t i = 0; i < rects.size(); i++) {
@ -156,23 +167,39 @@ TEST(DistortionMapperTest, IdentityTransform) {
}
}
TEST(DistortionMapperTest, LargeTransform) {
TEST(DistortionMapperTest, SimpleTransform) {
status_t res;
DistortionMapper m;
setupTestMapper(&m, identityDistortion, testICal,
/*activeArray*/ testActiveArray,
/*preCorrectionActiveArray*/ testPreCorrActiveArray);
auto coords = basicCoords;
res = m.mapCorrectedToRaw(coords.data(), 5, /*clamp*/true, /*simple*/true);
ASSERT_EQ(res, OK);
ASSERT_EQ(coords[0], 0); ASSERT_EQ(coords[1], 0);
ASSERT_EQ(coords[2], testPreCorrActiveArray[2] - 1); ASSERT_EQ(coords[3], 0);
ASSERT_EQ(coords[4], testPreCorrActiveArray[2] - 1); ASSERT_EQ(coords[5], testPreCorrActiveArray[3] - 1);
ASSERT_EQ(coords[6], 0); ASSERT_EQ(coords[7], testPreCorrActiveArray[3] - 1);
ASSERT_EQ(coords[8], testPreCorrActiveArray[2] / 2); ASSERT_EQ(coords[9], testPreCorrActiveArray[3] / 2);
}
void RandomTransformTest(::testing::Test *test,
int32_t* activeArray, DistortionMapper &m, bool clamp, bool simple) {
status_t res;
constexpr int maxAllowedPixelError = 2; // Maximum per-pixel error allowed
constexpr int bucketsPerPixel = 3; // Histogram granularity
unsigned int seed = 1234; // Ensure repeatability for debugging
const size_t coordCount = 1e6; // Number of random test points
float bigDistortion[] = {0.1, -0.003, 0.004, 0.02, 0.01};
DistortionMapper m;
setupTestMapper(&m, bigDistortion);
const size_t coordCount = 1e5; // Number of random test points
std::default_random_engine gen(seed);
std::uniform_int_distribution<int> x_dist(0, testActiveArray[2] - 1);
std::uniform_int_distribution<int> y_dist(0, testActiveArray[3] - 1);
std::uniform_int_distribution<int> x_dist(0, activeArray[2] - 1);
std::uniform_int_distribution<int> y_dist(0, activeArray[3] - 1);
std::vector<int32_t> randCoords(coordCount * 2);
@ -186,12 +213,12 @@ TEST(DistortionMapperTest, LargeTransform) {
auto origCoords = randCoords;
base::Timer correctedToRawTimer;
res = m.mapCorrectedToRaw(randCoords.data(), randCoords.size() / 2);
res = m.mapCorrectedToRaw(randCoords.data(), randCoords.size() / 2, clamp, simple);
auto correctedToRawDurationMs = correctedToRawTimer.duration();
EXPECT_EQ(res, OK);
base::Timer rawToCorrectedTimer;
res = m.mapRawToCorrected(randCoords.data(), randCoords.size() / 2);
res = m.mapRawToCorrected(randCoords.data(), randCoords.size() / 2, clamp, simple);
auto rawToCorrectedDurationMs = rawToCorrectedTimer.duration();
EXPECT_EQ(res, OK);
@ -202,9 +229,9 @@ TEST(DistortionMapperTest, LargeTransform) {
(std::chrono::duration_cast<std::chrono::duration<double, std::micro>>(
rawToCorrectedDurationMs) / (randCoords.size() / 2) ).count();
RecordProperty("CorrectedToRawDurationPerCoordUs",
test->RecordProperty("CorrectedToRawDurationPerCoordUs",
base::StringPrintf("%f", correctedToRawDurationPerCoordUs));
RecordProperty("RawToCorrectedDurationPerCoordUs",
test->RecordProperty("RawToCorrectedDurationPerCoordUs",
base::StringPrintf("%f", rawToCorrectedDurationPerCoordUs));
// Calculate mapping errors after round trip
@ -239,17 +266,61 @@ TEST(DistortionMapperTest, LargeTransform) {
}
float rmsError = std::sqrt(totalErrorSq / randCoords.size());
RecordProperty("RmsError", base::StringPrintf("%f", rmsError));
test->RecordProperty("RmsError", base::StringPrintf("%f", rmsError));
for (size_t i = 0; i < histogram.size(); i++) {
std::string label = base::StringPrintf("HistogramBin[%f,%f)",
(float)i/bucketsPerPixel, (float)(i + 1)/bucketsPerPixel);
RecordProperty(label, histogram[i]);
test->RecordProperty(label, histogram[i]);
}
RecordProperty("HistogramOutOfRange", outOfHistogram);
test->RecordProperty("HistogramOutOfRange", outOfHistogram);
}
// Test a realistic distortion function with matching calibration values, enforcing
// clamping.
TEST(DistortionMapperTest, DISABLED_SmallTransform) {
int32_t activeArray[] = {0, 8, 3278, 2450};
int32_t preCorrectionActiveArray[] = {0, 0, 3280, 2464};
float distortion[] = {0.06875723, -0.13922249, 0.02818312, -0.00032781, -0.00025431};
float intrinsics[] = {1812.50000000, 1812.50000000, 1645.59533691, 1229.23229980, 0.00000000};
DistortionMapper m;
setupTestMapper(&m, distortion, intrinsics, activeArray, preCorrectionActiveArray);
RandomTransformTest(this, activeArray, m, /*clamp*/true, /*simple*/false);
}
// Test a realistic distortion function with matching calibration values, enforcing
// clamping, but using the simple linear transform
TEST(DistortionMapperTest, SmallSimpleTransform) {
int32_t activeArray[] = {0, 8, 3278, 2450};
int32_t preCorrectionActiveArray[] = {0, 0, 3280, 2464};
float distortion[] = {0.06875723, -0.13922249, 0.02818312, -0.00032781, -0.00025431};
float intrinsics[] = {1812.50000000, 1812.50000000, 1645.59533691, 1229.23229980, 0.00000000};
DistortionMapper m;
setupTestMapper(&m, distortion, intrinsics, activeArray, preCorrectionActiveArray);
RandomTransformTest(this, activeArray, m, /*clamp*/true, /*simple*/true);
}
// Test a very large distortion function; the regions aren't valid for such a big transform,
// so disable clamping. This test is just to verify round-trip math accuracy for big transforms
TEST(DistortionMapperTest, LargeTransform) {
float bigDistortion[] = {0.1, -0.003, 0.004, 0.02, 0.01};
DistortionMapper m;
setupTestMapper(&m, bigDistortion, testICal,
/*activeArray*/testActiveArray,
/*preCorrectionActiveArray*/testPreCorrActiveArray);
RandomTransformTest(this, testActiveArray, m, /*clamp*/false, /*simple*/false);
}
// Compare against values calculated by OpenCV
// undistortPoints() method, which is the same as mapRawToCorrected
// Ignore clamping
// See script DistortionMapperComp.py
#include "DistortionMapperTest_OpenCvData.h"
@ -262,11 +333,14 @@ TEST(DistortionMapperTest, CompareToOpenCV) {
const int32_t maxSqError = 2;
DistortionMapper m;
setupTestMapper(&m, bigDistortion);
setupTestMapper(&m, bigDistortion, testICal,
/*activeArray*/testActiveArray,
/*preCorrectionActiveArray*/testActiveArray);
using namespace openCvData;
res = m.mapRawToCorrected(rawCoords.data(), rawCoords.size() / 2);
res = m.mapRawToCorrected(rawCoords.data(), rawCoords.size() / 2, /*clamp*/false,
/*simple*/false);
for (size_t i = 0; i < rawCoords.size(); i+=2) {
int32_t dist = (rawCoords[i] - expCoords[i]) * (rawCoords[i] - expCoords[i]) +

Loading…
Cancel
Save