如何在保留边角的同时简化折线?

时间:2019-05-25 14:49:50

标签: c++ algorithm computer-vision

我正在尝试为我的CG项目编写一个简单的“矢量化器”。目标是对二进制图像中的字符/形状进行矢量化处理。

我的方法是:

1。删除每个黑色像素以及周围4个像素(不包括对角线)

2。扫描图像并分组连接像素(包括diaganol)

3。在每组点上使用Ramer–Douglas–Peucker(RDP)算法

4。使用折线或b样条线连接每个组中的点

但是结果有点令人失望。 RDP不够简化,例如,如果我输入一个正方形的点列表,它应该将其减少到只有四个角。

This是显示上述问题的示例。粉色是RDP简化后的像素,仍然太多。

如果需要,这是我用C ++ / Qt编写的代码。 (有一些冗余代码,但我认为没有错)

QList<T> rdp(const QList<T> & list, double eps = 2) {//reduce the number of points in a curve
    QStack<QPoint> stk;
    stk.append({ 0,list.size() - 1 });
    bool* indices = new bool[list.size()];
    for(int i=0,n=list.size();i<n;++i){
        indices[i]=true;
    }
    while (!stk.empty()) {
        auto t = stk.pop();
        int s, id = s = t.x(), e = t.y();
        if(e-s<=1){
            break;
        }
        auto p = list[s]-list[e];
        double dmax = 0, len=sqrt(pow(p.x(), 2) + pow(p.y(), 2));
        for (int i = id + 1; i < e; ++i) {
            if (indices[i]) {
                auto q = list[i]-list[e];
                double d=0;
                if (len < 1e-3) {
                    d = sqrt(pow(q.x(), 2) + pow(q.y(), 2));
                }else{
                    d = abs(p.x() * q.y() - p.y() * q.x()) / len;
                }
                if (d > dmax) {
                    id = i;
                    dmax = d;
                }
            }
        }
        if (dmax > eps) {
            stk.append({ s,id });
            stk.append({ id,e });
        } else {
            for (int i = s + 1; i < e; ++i) {
                indices[i] = false;
            }
        }
    }
    QList<T> re;
    for (int i = 0, j = list.size(); i < j; ++i) {
        if (indices[i]) {
            re.append(list[i]);
        }
    }
    delete[] indices;
    return re;
}

欢迎对我的方法/代码或其他更好的方法提出建议。

0 个答案:

没有答案