opencv-wasm
opencv-wasm copied to clipboard
Opencv.js - findPerspective returns wrong corners coordinates
Hi,
I'm trying to implement AKAZE with opencv.js and opencv-wasm.
Here is my code:
const { cv, cvTranslateError } = require('opencv-wasm');
const Jimp = require('jimp');
const util = require('./util.js');
(async () => {
try {
console.log("Enter 1");
const jimpSrc = await Jimp.read("./images/how_to_play.png");
const jimpSrcToMatch = await Jimp.read("./images/scene.png");
console.log("Enter 2");
// initiate ORB detector, default number of features to retain is 500, bit too low
let akaze = new cv.AKAZE();
let img1 = await cv.matFromImageData(jimpSrc.bitmap);
let img2 = await cv.matFromImageData(jimpSrcToMatch.bitmap);
let res = new cv.Mat();
let mask1 = new cv.Mat();
let mask2 = new cv.Mat();
console.log("Enter 3");
cv.cvtColor(img1, img1, cv.COLOR_BGRA2GRAY, 0);
cv.cvtColor(img2, img2, cv.COLOR_BGRA2GRAY, 0);
// find descriptors and keypoints with AKAZE detector
let kp1 = new cv.KeyPointVector();
let kp2 = new cv.KeyPointVector();
let des1 = new cv.Mat();
let des2 = new cv.Mat();
akaze.detectAndCompute(img1, mask1, kp1, des1);
akaze.detectAndCompute(img2, mask2, kp2, des2);
// create BFMatcher object and and match descriptors
let matcher = new cv.BFMatcher();
let matches = new cv.DMatchVectorVector();
let filteredMatches = new cv.DMatchVector();
matcher.knnMatch(des1, des2, matches, 2);
// filter matches
for (let i = 0; i < matches.size(); ++i) {
let match = matches.get(i);
let dMatch1 = match.get(0);
let dMatch2 = match.get(1);
if (dMatch1.distance <= dMatch2.distance * 0.7) {
filteredMatches.push_back(dMatch1);
}
}
cv.drawMatches(img1, kp1, img2, kp2, filteredMatches, res);
util.saveMat(res, "matcher-output.png");
if (filteredMatches.size() > 13) {
let objectPoints = [];
let scenePoints = [];
for (let i = 0; i < filteredMatches.size(); ++i) {
let dMatch = filteredMatches.get(i);
objectPoints.push(
new cv.Point(kp1.get(dMatch.queryIdx).pt.x, kp1.get(dMatch.queryIdx).pt.y));
scenePoints.push(
new cv.Point(kp2.get(dMatch.trainIdx).pt.x, kp2.get(dMatch.trainIdx).pt.y));
}
let homography = cv.findHomography(
cv.matFromArray(objectPoints.length, 3, cv.CV_32F, objectPoints),
cv.matFromArray(scenePoints.length, 3, cv.CV_32F, scenePoints), cv.RANSAC, 3);
let sceneCorners = new cv.Mat(4, 1, cv.CV_32FC2);
//let objCorners = cv.matFromArray(4, 1, cv.CV_32FC2, [0, 0, img1.cols - 1, 0, img1.cols - 1, img1.rows - 1, 0, img1.rows - 1]);
let objCorners = new cv.Mat(4, 1, cv.CV_32FC2);
console.log("Transforming object corners to scene corners...");
// cv.perspectiveTransform(objCorners, sceneCorners, homography);
var view = objCorners.data32F;
view[0] = 0;
view[1] = 0;
view[2] = img1.cols;
view[3] = 0;
view[4] = img1.cols;
view[5] = img1.rows;
view[6] = 0;
view[7] = img1.rows;
cv.perspectiveTransform(objCorners, sceneCorners, homography);
var dataAns = sceneCorners.data32F;
var x1 = new cv.Point(dataAns[0], dataAns[1]);
var x2 = new cv.Point(dataAns[2], dataAns[3]);
var x3 = new cv.Point(dataAns[4], dataAns[5]);
var x4 = new cv.Point(dataAns[6], dataAns[7]);
cv.line(res, x1, x2,
new cv.Scalar(0, 0, 0), 10, cv.LINE_AA, 0);
cv.line(res, x2, x3,
new cv.Scalar(0, 0, 0), 10, cv.LINE_AA, 0);
cv.line(res, x3, x4,
new cv.Scalar(0, 0, 0), 10, cv.LINE_AA, 0);
cv.line(res, x4, x1,
new cv.Scalar(0, 0, 0), 10, cv.LINE_AA, 0);
}
} catch (err) {
console.log(cvTranslateError(cv, err));
}
})();
The problem is, that final corners coordinates x1, x2, x3, x4 are always like 1.00007678, 0.9999767623, -0.9878787.... Any ideas why?
P.S I'm well familiar with opencv for Java and Python.
Hello @dzaiats,
I've tried running your code, the matching works fine:
But it gave me this error when running the perspectiveTransform:
Exception: OpenCV(4.3.0) /code/modules/core/src/matmul.dispatch.cpp:531: error: (-215:Assertion failed) scn + 1 == m.cols in function 'perspectiveTransform'
Can you provide the exact images that you used? I can't get the numbers (x1, x2, x3, x4) that you mentioned.