extractAlignedSquare function
Mat?
extractAlignedSquare(})
Extracts a rotated square region from a cv.Mat using OpenCV's warpAffine.
This function uses SIMD-accelerated warpAffine which is 10-50x faster than pure Dart bilinear interpolation.
Parameters:
src: Source cv.Mat imagecx: Center X coordinate in pixelscy: Center Y coordinate in pixelssize: Side length of the square region in source pixelstheta: Rotation angle in radians (positive = counter-clockwise)outSize: Optional output side length in pixels. When set, the warp scales thesize-by-sizesource region directly tooutSize-by-outSizein a single resample, equivalent to cropping atsizeand thencv.resize-ing tooutSize(the scaled matrix uses the same pixel-center alignment as cv.resize). Use this to extract crops at a model's input resolution without paying for a full-size warp plus a second resample.
Returns the cropped and rotated cv.Mat. Caller must dispose. Returns null if size is invalid.
Implementation
cv.Mat? extractAlignedSquare(
cv.Mat src,
double cx,
double cy,
double size,
double theta, {
int? outSize,
}) {
final int sizeInt = size.round();
if (sizeInt <= 0) return null;
final int dstSize = outSize ?? sizeInt;
final double scale = dstSize / sizeInt;
final double angleDegrees = -theta * 180.0 / math.pi;
final cv.Mat rotMat = cv.getRotationMatrix2D(
cv.Point2f(cx, cy),
angleDegrees,
scale,
);
// Pixel-center alignment matching crop-then-cv.resize: a resize by factor
// s samples src((x + 0.5) / s - 0.5), so the source center must land at
// dstSize / 2 + 0.5 * (s - 1) rather than dstSize / 2. Reduces to the
// plain crop placement when outSize is null (s == 1).
final double outCenter = dstSize / 2.0 + 0.5 * (scale - 1.0);
final double tx = rotMat.at<double>(0, 2) + outCenter - cx;
final double ty = rotMat.at<double>(1, 2) + outCenter - cy;
rotMat.set<double>(0, 2, tx);
rotMat.set<double>(1, 2, ty);
final cv.Mat output = cv.warpAffine(
src,
rotMat,
(dstSize, dstSize),
borderMode: cv.BORDER_CONSTANT,
borderValue: cv.Scalar.black,
);
rotMat.dispose();
return output;
}