我试图用带有点的数组创建一个带有opencv.js的凸包,有没有人知道如何正确有效地做到这一点?数组看起来像这样:
[
[5,5],
[10,10],
[15,15]
...
]
- >其中第一个值为x
,第二个值为y
值,但将此格式更改为更合适的格式不会有问题。
Thnx的帮助:)
答案 0 :(得分:0)
让我们说你的点代表一个轮廓:
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网站的this tutorial:
// 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();
}
答案 1 :(得分:0)
到目前为止,我可以尝试使用OpenCV以Mat
格式存储CV_32SC2
类型的轮廓/船体数据:本质上是[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()方法将其从2D数组([[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>
请注意,以上只是一个粗略的示例,没有数据验证或任何其他更高级的检查,但希望它能说明这一思想,以便可以根据需要进行稳健的扩展。