opencv.js issue with findTransformECC criteria

穿精又带淫゛_ 提交于 2021-02-08 09:15:48

问题


I'm attempting to use opencv.js to align images to a baseline image. I'm following some basic python guidance that i've seen work (example: https://alexanderpacha.com/2018/01/29/aligning-images-an-engineers-solution/)

but i'm getting tripped up with an error that I don't quite understand. The error is "opencv.js:30 Uncaught TypeError: Cannot use 'in' operator to search for 'type' in 1e-10" and it seems to be caused by the "criteria" variable passed to "cv.findTransformECC();" see here.

any guidance as to what I'm doing wrong here?

        function Align_img(){

            let image_baseline = cv.imread(imgElement_Baseline);
            let image = cv.imread('imageChangeup');

            let im1_gray = new cv.Mat();
            let im2_gray = new cv.Mat();
            let im2_aligned = new cv.Mat();

            //get size of baseline image
            width1 = image_baseline.cols;
            height1 = image_baseline.rows;

            //resize image to baseline image
            let dim1 = new cv.Size(width1, height1);
            cv.resize(image, image, dim1, cv.INTER_AREA);

            // Convert images to grayscale
            cv.cvtColor(image_baseline, im1_gray, cv.COLOR_BGR2GRAY);
            cv.cvtColor(image, im2_gray, cv.COLOR_BGR2GRAY);

            // Find size of image1
            let dsize = new cv.Size(image_baseline.rows, image_baseline.cols);

            // Define the motion model
            warp_mode = cv.MOTION_HOMOGRAPHY;

            // Define 3x3 matrix and initialize the matrix to identity
            let warp_matrix = cv.Mat.eye(3, 3, cv.CV_8U);

            // Specify the number of iterations.
            number_of_iterations = 5000;

            // Specify the threshold of the increment in the correlation coefficient between two iterations
            termination_eps = 0.0000000001; //1e-10;

            // Define termination criteria
            criteria = (cv.TERM_CRITERIA_EPS | cv.TERM_CRITERIA_COUNT, number_of_iterations,  termination_eps);

            //Run the ECC algorithm. The results are stored in warp_matrix.
            cv.findTransformECC(im1_gray, im2_gray, warp_matrix, warp_mode, criteria, null, 5);

            // Use warpPerspective for Homography
            cv.warpPerspective (image, im2_aligned, warp_matrix, dsize, cv.INTER_LINEAR + cv.WARP_INVERSE_MAP);

            cv.imshow('imageChangeup', im2_aligned);

            im1_gray.delete();
            im2_gray.delete();
            im2_aligned.delete();

        };

UPDATE: 2 things. 1. Found easy fix to error (code below) and 2. looks like a bug in the findTransformECC opencv.js API causing this method not to work. Here is current code.

The API has 2 optional parameters (inputMask and gaussFiltSize) but if you don't include them you get an error ("function findTransformECC called with 5 arguments, expected 7 args!").

The issue is what to use for inputMask - "null" does not work, there doesn't seem to be support for 'cv.noArray()' and I can't find a mask that doesn't lead to a 'uncaught exception' error.

I'll update again once I find a workaround. Let me know if anyone sees a work around.

   

 function Align_img(){

        let image_baseline = cv.imread(imgElement_Baseline);
        let image = cv.imread('imageChangeup');

        let im1_gray = new cv.Mat();
        let im2_gray = new cv.Mat();
        let im2_aligned = new cv.Mat();

        //get size of baseline image
        var width1 = image_baseline.cols;
        var height1 = image_baseline.rows;

        //resize image to baseline image
        let dim1 = new cv.Size(width1, height1);
        cv.resize(image, image, dim1, cv.INTER_AREA);

        // Convert images to grayscale
        cv.cvtColor(image_baseline, im1_gray, cv.COLOR_BGR2GRAY);
        cv.cvtColor(image, im2_gray, cv.COLOR_BGR2GRAY);

        // Find size of image1
        let dsize = new cv.Size(image_baseline.rows, image_baseline.cols);

        // Define the motion model
        const warp_mode = cv.MOTION_HOMOGRAPHY;

        // Define 3x3 matrix and initialize the matrix to identity
        let warp_matrix = cv.Mat.eye(3, 3, cv.CV_8U);

        // Specify the number of iterations.
        const number_of_iterations = 5000;

        // Specify the threshold of the increment in the correlation coefficient between two iterations
        const termination_eps = 0.0000000001; //1e-10;

        // Define termination criteria
        //const criteria = (cv.TERM_CRITERIA_EPS | cv.TERM_CRITERIA_COUNT, number_of_iterations,  termination_eps);
        let criteria = new cv.TermCriteria(cv.TERM_CRITERIA_EPS | cv.TERM_CRITERIA_COUNT, number_of_iterations,  termination_eps);

        //Run the ECC algorithm. The results are stored in warp_matrix.
        //let inputMask = new cv.Mat.ones(im1_gray.size(), cv.CV_8U); //uint8

        cv.findTransformECC(im1_gray, im2_gray, warp_matrix, warp_mode, criteria, null, 5);

        // Use warpPerspective for Homography
        cv.warpPerspective (image, im2_aligned, warp_matrix, dsize, cv.INTER_LINEAR + cv.WARP_INVERSE_MAP);

        getMatStats(im2_aligned, 1); //0 = baseline (srcMat), 1 = image (srcMat_compare)
        cv.imshow('imageChangeup', im2_aligned);

        im1_gray.delete();
        im2_gray.delete();
        im2_aligned.delete();

    };

UPDATE 2 I verified code works fine in Python. code below. The issue at hand now is simply, how do you this in Javascript: "inputMask=None"

Python:


    # Read the images to be aligned
    im1 =  cv2.imread(r"C:\temp\tcoin\69.jpg");
    im2 =  cv2.imread(r"C:\temp\tcoin\pic96_crop.jpg");
    
    #resize image to compare
    width1 = int(im1.shape[1])
    height1 = int(im1.shape[0])
    dim1 = (width1, height1)
    im2 = cv2.resize(im2, dim1, interpolation = cv2.INTER_AREA)
    
    # Convert images to grayscale
    im1_gray = cv2.cvtColor(im1,cv2.COLOR_BGR2GRAY)
    im2_gray = cv2.cvtColor(im2,cv2.COLOR_BGR2GRAY)
    
    # Find size of image1
    sz = im1.shape
    
    # Define the motion model
    warp_mode = cv2.MOTION_HOMOGRAPHY
    
    # Define 2x3 or 3x3 matrices and initialize the matrix to identity
    warp_matrix = np.eye(3, 3, dtype=np.float32)
    
    # Specify the number of iterations.
    number_of_iterations = 5000;
    
    # Specify the threshold of the increment
    # in the correlation coefficient between two iterations
    termination_eps = 1e-10;
    
    # Define termination criteria
    criteria = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, number_of_iterations,  termination_eps)
    
    # Run the ECC algorithm. The results are stored in warp_matrix.
    (cc, warp_matrix) = cv2.findTransformECC (im1_gray,im2_gray,warp_matrix, warp_mode, criteria, inputMask=None, gaussFiltSize=1)
    
    # Use warpPerspective for Homography 
    im2_aligned = cv2.warpPerspective (im2, warp_matrix, (sz[1],sz[0]), flags=cv2.INTER_LINEAR + cv2.WARP_INVERSE_MAP)
    
    # Show final results
    cv2.imshow("Aligned Image 2", im2_aligned)
    
    cv2.imwrite(r"c:\temp\tcoin\output\pic96_cropB.jpg", im2_aligned)
    
    cv2.waitKey(0)

来源:https://stackoverflow.com/questions/62744310/opencv-js-issue-with-findtransformecc-criteria

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!