Skip to content

Commit c69478e

Browse files
committed
Fix rotated size when rotating 180
1 parent 637209e commit c69478e

File tree

2 files changed

+68
-1
lines changed

2 files changed

+68
-1
lines changed

photon-core/src/main/java/org/photonvision/vision/calibration/CameraCalibrationCoefficients.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ public CameraCalibrationCoefficients rotateCoefficients(ImageRotationMode rotati
116116
double p1 = getDistCoeffsMat().get(0, 2)[0];
117117
double p2 = getDistCoeffsMat().get(0, 3)[0];
118118

119+
Size rotatedImageSize = null;
120+
119121
// A bunch of horrifying opaque rotation black magic. See image-rotation.md for more details.
120122
switch (rotation) {
121123
case DEG_0:
@@ -136,6 +138,8 @@ public CameraCalibrationCoefficients rotateCoefficients(ImageRotationMode rotati
136138
// P2
137139
rotatedDistCoeffs.put(0, 3, -p1);
138140

141+
// The rotated image size is the same as the unrotated image size, but the width and height are flipped
142+
rotatedImageSize = new Size(unrotatedImageSize.height, unrotatedImageSize.width);
139143
break;
140144
case DEG_180_CCW:
141145
// CX
@@ -147,6 +151,9 @@ public CameraCalibrationCoefficients rotateCoefficients(ImageRotationMode rotati
147151
rotatedDistCoeffs.put(0, 2, -p1);
148152
// P2
149153
rotatedDistCoeffs.put(0, 3, -p2);
154+
155+
// The rotated image size is the same as the unrotated image size
156+
rotatedImageSize = unrotatedImageSize;
150157
break;
151158
case DEG_90_CCW:
152159
// FX
@@ -164,6 +171,8 @@ public CameraCalibrationCoefficients rotateCoefficients(ImageRotationMode rotati
164171
// P2
165172
rotatedDistCoeffs.put(0, 3, p1);
166173

174+
// The rotated image size is the same as the unrotated image size, but the width and height are flipped
175+
rotatedImageSize = new Size(unrotatedImageSize.height, unrotatedImageSize.width);
167176
break;
168177
}
169178

@@ -174,7 +183,6 @@ public CameraCalibrationCoefficients rotateCoefficients(ImageRotationMode rotati
174183
rotatedIntrinsics.release();
175184
rotatedDistCoeffs.release();
176185

177-
var rotatedImageSize = new Size(unrotatedImageSize.height, unrotatedImageSize.width);
178186

179187
return new CameraCalibrationCoefficients(
180188
rotatedImageSize,

photon-core/src/test/java/org/photonvision/vision/pipeline/CalibrationRotationPipeTest.java

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,65 @@ public void testUndistortImagePointsWithRotation(@Enum ImageRotationMode rot) {
174174
}
175175
}
176176

177+
@Test
178+
public void testRotateCoefficients180multiple() {
179+
ImageRotationMode rot = ImageRotationMode.DEG_180_CCW;
180+
181+
// GIVEN A camera calibration
182+
var res = new Size(1270, 720);
183+
double fx = 900;
184+
double fy = 951;
185+
double cx = 500;
186+
double cy = 321;
187+
double[] intrinsics = {
188+
fx, 0, cx,
189+
0, fy, cy,
190+
0, 0, 1
191+
};
192+
double[] distCoeffs = {
193+
0.25,
194+
-1.5,
195+
0.0017808248356550637,
196+
.00004,
197+
2.179764689221826,
198+
-0.034952777924711353,
199+
0.09625562194891251,
200+
-0.1860797479660746
201+
};
202+
CameraCalibrationCoefficients coeffs =
203+
new CameraCalibrationCoefficients(
204+
res,
205+
new JsonMatOfDouble(3, 3, intrinsics),
206+
new JsonMatOfDouble(1, 8, distCoeffs),
207+
new double[] {},
208+
List.of(),
209+
new Size(),
210+
1,
211+
CameraLensModel.LENSMODEL_OPENCV);
212+
213+
// WHEN the camera calibration is rotated 180 degrees
214+
var coeffs2 = coeffs.rotateCoefficients(rot);
215+
216+
// THEN the optical center should be rotated 180 degrees
217+
double[] rotatedCamMat = {
218+
fx, 0, res.width-cx,
219+
0, fy, res.height-cy,
220+
0, 0, 1
221+
};
222+
assertArrayEquals(rotatedCamMat, coeffs2.cameraIntrinsics.data);
223+
// AND the image size should be the same
224+
assertEquals(res, coeffs2.unrotatedImageSize);
225+
226+
// WHEN the camera calibration is rotated 180 degrees
227+
var coeffs3 = coeffs2.rotateCoefficients(rot);
228+
229+
// THEN the camera matrix will be the same as the original
230+
assertArrayEquals(intrinsics, coeffs3.cameraIntrinsics.data);
231+
// AND the image size should be the same
232+
assertEquals(res, coeffs2.unrotatedImageSize);
233+
}
234+
235+
177236
@CartesianTest
178237
public void testCalibrationDataIsValidWithRotation(@Enum ImageRotationMode rot) {
179238
double[] intrinsics = {

0 commit comments

Comments
 (0)