得到的非几何线条的坐标在一个二进制图象 [英] Get coordinates of non-geometric lines in a binary image

查看:419
本文介绍了得到的非几何线条的坐标在一个二进制图象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图识别手,持仓 OpenCV的为Android。我想,以减少检测到的手的形状到设置简单的线条(=点序列)。我使用的是细化算法找到检测的手的形状的干线。下面是一个示范性结果(我的左手图像):

I'm trying to recognize hand positions in OpenCV for Android. I'd like to reduce a detected hand shape to a set of simple lines (= point sequences). I'm using a thinning algorithm to find the skeleton lines of detected hand shapes. Here's an exemplary result (image of my left hand):

在这个图片我想获得的骨架线,即矢量图像的坐标。我试过 HoughLinesP 但只生产了很短的线条庞大套,这不是我想要的。

In this image I'd like to get the coordinates of the skeleton lines, i.e. "vectorize" the image. I've tried HoughLinesP but this only produces huge sets of very short lines, which is not what I want.

我的第二种方法使用 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 返回的轮廓始终关闭,这意味着所有骨架线重新presented两次

This basically works; however, the contours returned by findContours are always closed, which means that all the skeleton lines are represented twice.

典型的结果是:(灰线=检测出轮廓,第一形象不干线)

Exemplary result: (gray lines = detected contours, not skeleton lines of first image)

我的问题是:?我怎样才能避免这些封闭的轮廓,只得到一个集单招点序列

我错过了什么,在OpenCV的文档?我不一定要求code,暗示一种算法我可以实现我自己也将是巨大的。谢谢!

Did I miss something in the OpenCV docs? I'm not necessarily asking for code, a hint for an algorithm I could implement myself would also be great. Thanks!

推荐答案

我将开始与真正的手骨架作为运动

I would start with real hand skeleton as kinematic

  1. 找到手指的端点和手/手腕基地及周边边界(红色)
  2. 解决反向运动学

  1. find fingers endpoints and hand/wrist base and perimeter boundary (red)
  2. solve inverse kinematics

  • 例如通过 CCD
  • 要配合手指的端点,而不是重叠的图像
  • 这样,你应该获得解剖学正确的答案

为了简化你可以使用这样的运动

for simplification you can use kinematics like this

  • 您应该处理男性/女性/小孩不同(不同的手指的长度)
  • 或使用,因为不同的手指长度的某种校正或测量的
  • ,你可以看到我跳过手/手腕基地的骨头,他们并不是那么重要
  • 红色的轮廓线,可以发现,其中周边具有较小的曲线半径
  • you should handle male/female/child differently (different finger lengths)
  • or use some kind of calibration or measurement because of the different finger lengths
  • as you can see I skip the hand/wrist base bones they are not that important
  • the red outline can be found where perimeter has smaller curve radius

如何解决你的问题,在当前的实现?

How to solve your problem in your current implementation?

  • 第一细化方法更好
  • 所以,当你得到了巨大的套系
  • 将它们连接到多义线
  • 在每行的计算后角
  • 如果两个连接线有相似的角度(不超过treshold),然后加入他们的行列
  • 应该做你想要什么
  • ,但不要期望你会得到类似于人类的骨骼行
  • 特别是对于曲线的结果将是多大的不同
  • 在线条和形状的两个计数

有关更好的效果,你需要使用几何细化

For better result you need to use geometrical thinning

  • ,但我不知道如果是在OpenCV的present(我不使用这个LIB)
  • 的想法是找到周线
  • 倒腾它向内垂直通过类似于这个
  • 一些小步骤
  • 如果被收购所需的宽度停止
  • 当外线转移导致过薄形停在那里
  • ,并连接到变薄从previous步点(黄线)
  • 这是所有对向量做(折线)没有图像像素!
  • 在宽度可以计算为最小垂直距离为附近的任何行
  • but I have no Idea if it is present in OpenCV (I do not use this lib)
  • the idea is to find the perimeter line
  • and shift it perpendicular inwards by some small step similar to this
  • stop if desired width is acquired
  • when shifted perimeter leads to too thin shape stop there
  • and connect to thinned point from previous step (yellow line)
  • this is all done on vectors (polylines) not on image pixels !!!
  • width can be computed as smallest perpendicular distance to any nearby line

这篇关于得到的非几何线条的坐标在一个二进制图象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆