android – 获取二进制图像中非几何线的坐标

我正在尝试识别OpenCV for
Android中的手势.我想将检测到的手形缩小为一组简单的线条(=点序列).我正在使用细化算法来查找检测到的手形的骨架线.这是一个示例性的结果(左手的图像):

在这个图像中,我想得到骨架线的坐标,即“矢量化”图像.我已经尝试了HoughLinesP,但这只会产生大量非常短的线,这不是我想要的.

我的第二种方法使用findContours:

// Get contours
Mat skeletonFrame; //image above
ArrayList<MatOfPoint> contours = new ArrayList<MatOfPoint>();
Imgproc.findContours(skeletonFrame, contours, new Mat(), Imgproc.RETR_CCOMP, Imgproc.CHAIN_APPROX_SIMPLE);

// Find longest contour
double maxLen = 0;
MatOfPoint max = null;
for (MatOfPoint c : contours) {
    double len = Imgproc.arcLength(Util.convert(c), true);  //Util.convert converts between MatOfPoint and MatOfPoint2f
    if (len > maxLen) {
        maxLen = len;
        max = c;
    }
}

// Simplify detected contour
MatOfPoint2f result = new MatOfPoint2f();
Imgproc.approxPolyDP(Util.convert(max), result, 5.0, false);

这基本上有效;但是,findContours返回的轮廓始终是闭合的,这意味着所有骨架线都会被表示两次.

示例性结果:(灰线=检测到的轮廓,而不是第一图像的骨架线)

所以我的问题是:我怎样才能避免这些封闭的轮廓,只得到一系列“单击”点序列?

我是否遗漏了OpenCV文档中的内容?我不一定要求代码,我可以自己实现的算法提示也很棒.谢谢!

最佳答案 我会从真正的手骨架开始作为运动学

>找到手指端点和手/手腕基部和周边边界(红色)
>解决逆运动学

例如,通过CCD匹配手指端点而不是重叠图像.这样你就可以获得解剖学上正确的答案
>为简化起见,您可以使用这样的运动学

您应该以不同的方式处理男/女/儿童(不同的手指长度)或使用某种校准或测量,因为手指长度不同.正如你所看到的那样,我跳过了手/手腕基部骨骼并不重要.可以找到红色轮廓,其中周长小于curve radius.

如何解决当前实施中的问题?

第一种细化方法更好,所以当你得到大量的线条时,在每条线的计算角度之后将它们连接到折线.如果两个连接的线具有相似的角度(达到阈值),那么加入它们应该做你想要的但是不要指望你会得到类似于人骨的线,特别是对于曲线,结果会有很大不同.在线数和形状的计数.

为了获得更好的结果,您需要使用几何细化

但我不知道如果它存在于OpenCV中(我不使用这个lib)的想法是找到周边线并将其向内垂直移动一些类似于this的小步骤.如果需要宽度,则停止

当移动周边导致太薄的形状停在那里并从前一步骤(黄线)连接到变薄点.这都是在矢量(折线)上完成的,不在图像像素上!宽度可以计算为与任何附近线的最小垂直距离.

点赞