I’m having difficulties in orienting my transformed image using OpenCV (JS).
Basically, I upload an image, select four points of the image (four corners), and transform it to be shown from a bird’s eye-view.
If I purposefully select the points from top-left, top-right, bottom-right, bottom-left, the orientation of the transformed image will be the same as the original image.
However, if I select the points from let’s say bottom-right, going counter-clockwise, the orientation flips.
What are some ways I can keep the source points as [[top-left x,y], [top-right x,y], [bottom-right x,y], [bottom-left x,y] ]?
The array of numbers i get back from my source points is likeso:
const srcPoints = [261, 35.5, 514, 23.5, 677, 487.5, 181, 538.5];
here is my entire transformation logic:
export function transformPerspective({
originalImage,
padding,
srcPoints,
}: TransformPerspective): Promise<HTMLImageElement> {
return new Promise((resolve) => {
let img = new Image();
img.id = "konvaImage";
img.src = originalImage;
img.style.display = "none";
document.body.appendChild(img);
img.onload = () => {
// here the srcPoints need to be sorted in the top-left/top-right/bottom-right/bottom-left order
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);
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();
// used to update my canvas image
resolve(imageFromCanvas);
};
});
}
any ideas?
2
Answers
A kind samaritan helped me out with this, coming up with centroid of points, and getting it by getting the average of the four points. Then we can get the calculated angles. then sort angles array based on the angle value, which can sort the points in the counter-clockwise direction with respect to the centroid, which is what I needed.
might have been a bit complex, maybe there is another way?
but it works for now:
Just create a helper function to sort the source points in the top-left/top-right/bottom-right/bottom-left order:
Then, update your
transformPerspective
function to use the sorted source points: