将像素网格转换为轮廓?

1 投票
2 回答
510 浏览
提问于 2025-04-18 15:42

我有一个像素网格,这个网格可以是任何类型的二维数组(比如numpy数组),每个值代表一种颜色(最多有5种不同的颜色)。我想在OpenGL环境中显示这个网格,但逐个像素绘制既低效又不聪明。我想做的是把所有相邻的同色像素合并成一个形状,这样我就可以绘制这些形状。

简单来说,我想做到这一点: enter image description here 也就是从一个二维点数组转换成一个形状列表(一个形状就是一组顶点)。

我不知道该怎么做,所以我在寻找任何可以完成这个工作的东西,比如任何语言中的算法或任何可以实现这个功能的Python库。

2 个回答

0

我建议你使用 numpy 里的 np.extract 函数,我觉得这个函数会很有帮助!下面是一个例子:

import numpy as np
arr = np.arange(12).reshape((3, 4))
condition = np.mod(arr, 3)==0 # base on this condition the function extract the special arrays
print np.extract(condition, arr)

这是运行后的结果:

[0 3 6 9]

然后你可以用 numpy.concatenate((a1, a2, ...), axis=0) 函数把这个数组连接起来!想了解更多,可以查看这里:http://docs.scipy.org/doc/numpy/reference/index.html

1

我知道你在找向量解决方案,但我觉得简单直接的方法也能很好地满足你的需求,而且可能效果更好。

我会把你的颜色数据加载到一个纹理里,使用类似下面的调用方式(抱歉用的是C语言的写法,不过你应该能很容易地把它转换成Python的格式):

GLuint texId = 0;
glGenTexture(1, &texId);
glBindTexture(GL_TEXTURE_2D, texId);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, colorData);

这里的widthheight分别是横向和纵向的方块数量,而colorData是一个数组,里面存储了每个方块的RGB颜色值。

接下来,选择合适的采样参数也很重要。因为我们希望方块之间的边缘清晰,所以要用“最近邻”采样,而不是通常用于图像纹理的“线性”采样。这样可以确保方块之间的颜色有明显的分界,而不是模糊过渡:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

然后,为了渲染你的网格,你只需要用这个纹理渲染一个单独的带纹理的四边形。

我能想到的向量解决方案的唯一优势是,如果你想使用多重采样抗锯齿(也叫MSAA)。因为MSAA只在基本图形的边缘进行抗锯齿处理,所以它对两个方块之间的颜色过渡边缘没有帮助。而使用向量解决方案时,每个区域作为一个独立的图形渲染,就能对这些边缘进行抗锯齿处理。

不过,只要你在显示时缩放图像,锯齿问题应该不会太大。只有在你想要旋转图像时,这个问题才会显得重要。

撰写回答