Building a front-end only image processing application and I am struggling to perform an un-transform logic for my image.
FYI, I am using https://docs.opencv.org/4.7.0/opencv.js
I have a canvas that shows an image from a user upload.
The user then can select four points of the image and see a birds-eye-view perspective. After the image has transformed, the user can further add shapes onto it.
When the user is done adding things on to the transformed image, I want to be able to untransform the image back to the original with the added shapes.
here’s my transform logic:
export function transformPerspective({
originalImage,
padding,
srcPoints,
}: Omit<
TransformPerspective,
"inverseMatrix" | "transformedImage"
>): Promise<Transform> {
return new Promise((resolve) => {
let img = new Image();
img.id = "konvaImage";
img.src = originalImage;
img.style.display = "none";
document.body.appendChild(img);
img.onload = () => {
let srcTri = cv.matFromArray(4, 1, cv.CV_32FC2, srcPoints);
const dstWidth = 900;
const dstHeight = 1000;
let dstTri = cv.matFromArray(4, 1, cv.CV_32FC2, [
padding,
padding,
dstWidth - padding,
padding,
dstWidth - padding,
dstHeight - padding,
padding,
dstHeight - padding,
]);
let matrix = cv.getPerspectiveTransform(srcTri, dstTri);
const inverseMatrix = matrix.inv(cv.DECOMP_LU);
let dsize = new cv.Size(dstWidth, dstHeight);
let myimg = cv.imread(
document.querySelector("#konvaImage") as HTMLImageElement
);
let warpedImage = new cv.Mat();
cv.warpPerspective(myimg, warpedImage, matrix, dsize);
const outputCanvas = document.createElement("canvas");
outputCanvas.id = "outputCanvas";
outputCanvas.width = 900;
outputCanvas.height = 1000;
outputCanvas.style.display = "none";
document.body.append(outputCanvas);
cv.imshow("outputCanvas", warpedImage);
const imageFromCanvas = new window.Image();
imageFromCanvas.src = outputCanvas.toDataURL();
// cleanup
myimg.delete();
warpedImage.delete();
matrix.delete();
srcTri.delete();
dstTri.delete();
outputCanvas.remove();
resolve({ imageFromCanvas, inverseMatrix });
};
});
}
and here’s my un-transform logic:
export function reverseTransformPerspective({
inverseMatrix,
padding,
srcPoints,
transformedImage,
}: Omit<TransformPerspective, "originalImage">): Promise<HTMLImageElement> {
return new Promise((resolve) => {
let img = new Image();
img.id = "konvaImage";
img.src = transformedImage;
img.style.display = "none";
document.body.appendChild(img);
img.onload = () => {
let dstTri = cv.matFromArray(4, 1, cv.CV_32FC2, srcPoints);
const srcWidth = img.width;
const srcHeight = img.height;
let srcTri = cv.matFromArray(4, 1, cv.CV_32FC2, [
padding,
padding,
srcWidth - padding,
padding,
srcWidth - padding,
srcHeight - padding,
padding,
srcHeight - padding,
]);
let matrix = cv.getPerspectiveTransform(srcTri, dstTri);
let dsize = new cv.Size(srcWidth, srcHeight);
let myimg = cv.imread(img);
let unTransformedImage = new cv.Mat();
cv.warpPerspective(myimg, unTransformedImage, inverseMatrix, dsize);
const outputCanvas = document.createElement("canvas");
outputCanvas.id = "outputCanvas";
outputCanvas.width = srcWidth;
outputCanvas.height = srcHeight;
outputCanvas.style.display = "none";
document.body.append(outputCanvas);
cv.imshow("outputCanvas", unTransformedImage);
const imageFromCanvas = new window.Image();
imageFromCanvas.src = outputCanvas.toDataURL();
// cleanup
myimg.delete();
unTransformedImage.delete();
matrix.delete();
srcTri.delete();
dstTri.delete();
outputCanvas.remove();
resolve(imageFromCanvas);
};
});
}
again the un-transform works, slightly, however the end result shows the transformed image (with the added shapes) and it is warped.
I’m trying to get the original image with the shapes
any ideas?