我正在尝试为我的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;
}
欢迎对我的方法/代码或其他更好的方法提出建议。