如何正确排序我的 srcPoints 以使转换后的图像始终保持相同的方向?

问题描述 投票:0回答:1

我在使用 OpenCV (JS) 定位转换后的图像时遇到困难。 基本上,我上传一张图像,选择图像的四个点(四个角),然后将其转换为从鸟瞰图显示。

如果我有意从左上、右上、右下、左下选择点,则变换后图像的方向将与原始图像相同。 但是,如果我从右下角逆时针选择点,方向就会翻转。

有哪些方法可以将源点保留为 [[左上 x,y]、[右上 x,y]、[右下 x,y]、[左下 x,y] ]?

我从源点返回的数字数组如下:

const srcPoints = [261, 35.5, 514, 23.5, 677, 487.5, 181, 538.5];

这是我的整个转换逻辑:

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);
    };
  });
}

有什么想法吗?

javascript arrays sorting opencv
1个回答
0
投票

只需创建一个辅助函数来按左上/右上/右下/左下顺序对源点进行排序:

function sortSourcePoints(srcPoints) {
  const sortedPoints = [...srcPoints];
  sortedPoints.sort((a, b) => {
    if (a < b) return -1;
    if (a > b) return 1;
    return 0;
  });

  const [topLeft, topRight, bottomRight, bottomLeft] = sortedPoints;
  return [topLeft, topRight, bottomRight, bottomLeft];
}

然后,更新您的

transformPerspective
函数以使用排序后的源点:

export function transformPerspective({
  originalImage,
  padding,
  srcPoints,
}: TransformPerspective): Promise<HTMLImageElement> {
  return new Promise((resolve) => {
    // ...

    img.onload = () => {
      const sortedSrcPoints = sortSourcePoints(srcPoints);

      // ...

      let srcTri = cv.matFromArray(4, 1, cv.CV_32FC2, sortedSrcPoints);

      // ...
    };

    // ...
  });
}
© www.soinside.com 2019 - 2024. All rights reserved.