[英]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.