检测物体后的像素轮廓无凸包

问题描述

想法是使用grabcut(OpenCV)检测矩形内的图像并使用Direct2D创建几何。

我的测试图像是这样:

enter image description here

执行抓取切割后,得到以下图像:

enter image description here

这个想法是概述它。我可以使用opacity brush将其从背景中排除,但是我想使用几何笔刷,以便能够像在编辑器中的所有其他选择(多边形,套索,矩形一样)上附加/加宽/组合几何形状等)。

如果我将凸包算法应用于这些点,我会得到:

enter image description here

我的情况当然不需要。如何勾勒图像?

从抓取图像中获取图像后,我根据亮度保留点:

DWORD* pixels = ...
    for (UINT y = 0; y < he; y++)
    {
        for (UINT x = 0; x < wi; x++)
        {
            DWORD& col = pixels[y * wi + x];
            auto lumthis = lum(col);
            if (lumthis > Lum_Threshold)
            {
                points.push_back({x,y});
            }
        }
    }

然后我对Y和X上的点进行排序:

std::sort(points.begin(),points.end(),[](D2D1_POINT_2F p1,D2D1_POINT_2F p2) -> bool
        {
            if (p1.y < p2.y)
                return true;
            if ((int)p1.y == (int)p2.y && p1.x < p2.x)
                return true;
            return false;
        });

然后,对于每条线(将上述点数组从顶部Y遍历到bototm Y),我为每条线创建“组”:

    struct SECTION
    {
        float left = 0,right = 0;
    };
    auto findgaps = [](D2D1_POINT_2F* p,size_t n) -> std::vector<SECTION>
    {
        std::vector<SECTION> j;
        SECTION* jj = 0;

        for (size_t i = 0; i < n; i++)
        {
            if (i == 0)
            {
                SECTION jp;
                jp.left = p[i].x;
                jp.right = p[i].x;
                j.push_back(jp);
                jj = &j[j.size() - 1];
                continue;
            }
            if ((p[i].x - jj->right) < 1.5f)
            {
                jj->right = p[i].x;
            }
            else
            {
                SECTION jp;
                jp.left = p[i].x;
                jp.right = p[i].x;
                j.push_back(jp);
                jj = &j[j.size() - 1];
            }

        }

        return j;
    };

我被困在这一点上。我知道从任意点集中可以有许多多边形,但是在我的情况下,这些点定义了什么是“左”和什么是“右”。我怎么从这里开始?

解决方法

对于感兴趣的任何人,解决方案都是OpenCV contours。工作示例here