繁体   English   中英

在 opencv.js 中使用点数组创建凸包

[英]Create convex hull with array of points in opencv.js

我试图用基于点数组的 opencv.js 创建一个凸包,有没有人知道正确有效的方法? 一个数组看起来像这样:

[
    [5,5],
    [10,10],
    [15,15]
    ...
] 

-> 第一个值是x ,第二个值是y值,但将此格式更改为更合适的格式不会有问题。

谢谢你的帮助:)

到目前为止,我可以试验 OpenCV 以CV_32SC2类型以Mat格式存储轮廓/船体数据:本质上是一个按[x1,y1,x2,y2,x3,y3,...]顺序排列的 32 位短整数的平面列表。

注意 32S C2的两个通道/平面部分:一个通道用于所有 x 值,另一个用于所有 y 值

您可以手动创建这样一个Mat ,访问它的data32S属性并填写每个值:

let testHull = cv.Mat.ones(4, 1, cv.CV_32SC2);
testHull.data32S[0] = 100;
testHull.data32S[1] = 100;
testHull.data32S[2] = 200;
testHull.data32S[3] = 100;
testHull.data32S[4] = 200;
testHull.data32S[5] = 200;
testHull.data32S[6] = 100;
testHull.data32S[7] = 200;

然而,OpenCV.js 提供了一个方便的方法来将一个平面的值数组转换为这样的 Mat:

let testHull = cv.matFromArray(4, 1, cv.CV_32SC2, [100,100,200,100,200,200,100,200])

如果您的数组是嵌套的,您可以简单地使用 JS Array 的flat()方法将其从二维数组( [[x1,y1]...] )展平为一维数组( [x1,y1,...] ) .

因此,您不必担心Mat类型以及您可以将其全部包装成一个不错的函数的所有内容,例如:

function nestedPointsArrayToMat(points){
   return cv.matFromArray(points.length, 1, cv.CV_32SC2, points.flat());
}

这是一个快速演示:

 function onOpenCvReady(){ cv.then(test); } function nestedPointsArrayToMat(points){ return cv.matFromArray(points.length, 1, cv.CV_32SC2, points.flat()); } function test(cv){ console.log("cv loaded"); // make a Mat to draw into let mainMat = cv.Mat.zeros(30, 30, cv.CV_8UC3); // make a fake hull let points = [ [ 5, 5], [25, 5], [25,25], [ 5,25] ] let hull = nestedPointsArrayToMat(points); console.log("hull data", hull.data32S); // make a fake hulls vector let hulls = new cv.MatVector(); // add the recently created hull hulls.push_back(hull); // test drawing it cv.drawContours(mainMat, hulls, 0, [192,64,0,0], -1, 8); // output to canvas cv.imshow('canvasOutput', mainMat); }
 <script async src="https://docs.opencv.org/4.4.0/opencv.js" onload="onOpenCvReady();" type="text/javascript"></script> <canvas id="canvasOutput" width="30" height="30"></canvas>

请注意,上面是一个粗略的示例,没有数据验证或任何其他更高级的检查,但希望它说明了这个想法,因此可以根据需要对其进行稳健扩展。

假设您的点代表一个轮廓:

var contours = new cv.MatVector();
for (var i = 0; i < points.size(); ++i) {
   contours.push_back(new cv.Mat(points[i][0], points[i][1])
}

现在按照 opencv 网站上的本教程进行操作:

// approximates each contour to convex hull
for (var i = 0; i < contours.size(); ++i) {
    var tmp = new cv.Mat();
    var cnt = contours.get(i);
    // You can try more different parameters
    cv.convexHull(cnt, tmp, false, true);
    hull.push_back(tmp);
    cnt.delete(); tmp.delete();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM