我有以下代码可以在屏幕上加载和显示(使用 PyQt)图像:
gVShader = """
attribute vec4 position;
attribute vec2 texture_coordinates;
varying vec2 v_texture_coordinates;
void main() {
v_texture_coordinates = texture_coordinates;
v_texture_coordinates.y = 1.0 - v_texture_coordinates.y;
gl_Position = position;
}"""
gFShader = """
uniform sampler2D texture1;
uniform sampler2D texture2;
varying vec2 v_texture_coordinates;
void main() {
gl_FragColor = texture2D(texture1, texture2.rg);
}"""
class ProjectiveGLViewer(QtOpenGL.QGLWidget):
def __init__(self, parent=None):
super(ProjectiveGLViewer, self).__init__(parent)
def initializeGL(self):
vshader = QtOpenGL.QGLShader(QtOpenGL.QGLShader.Vertex, self)
if not vshader.compileSourceCode(gVShader):
print vshader.log()
fshader = QtOpenGL.QGLShader(QtOpenGL.QGLShader.Fragment, self)
if not fshader.compileSourceCode(gFShader):
print fshader.log()
self._program = QtOpenGL.QGLShaderProgram()
self._program.addShader(vshader)
self._program.addShader(fshader)
self._program.link()
self._program.bind()
# data array (2 [position], 4 [color])
data = np.array([-1.0, -1.0, 0.0, 0.0, 1.0, -1.0, 1.0, 0.0, -1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0], dtype=np.float32)
self.bufferID = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, self.bufferID)
glBufferData(GL_ARRAY_BUFFER, data.nbytes, data, GL_DYNAMIC_DRAW)
loc = self._program.attributeLocation("position")
glEnableVertexAttribArray(loc)
glVertexAttribPointer(loc, 2, GL_FLOAT, False, 16, ctypes.c_void_p(0))
loc = self._program.attributeLocation("texture_coordinates")
glEnableVertexAttribArray(loc)
glVertexAttribPointer(loc, 2, GL_FLOAT, False, 16, ctypes.c_void_p(8))
image = QtGui.QImage("image.jpg")
ptr = image.bits()
ptr.setsize(image.byteCount())
image_data = np.asarray(ptr).reshape(image.width(), image.height(), 4)
self._imageTextureID = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, self._imageTextureID)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 0, GL_BGRA, GL_UNSIGNED_BYTE, image_data)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
glActiveTexture(GL_TEXTURE0)
self._program.setUniformValue('texture1', 0)
image2 = QtGui.QImage("st_map.tif")
ptr2 = image2.bits()
ptr2.setsize(image2.byteCount())
image_data2 = np.asarray(ptr).reshape(image2.width(), image2.height(), 4)
self._stTextureID = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, self._stTextureID)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image2.width(), image2.height(), 0, GL_BGRA, GL_UNSIGNED_BYTE, image_data2)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
self._program.setUniformValue('texture2', 1)
def paintGL(self):
glBindBuffer(GL_ARRAY_BUFFER, self.bufferID)
glClearColor(0, 0.2, 0.3, 1.0)
glClearDepth(1.0)
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)
def resizeGL(self, w, h):
glViewport(0, 0, w, h)
现在,我想使用 STMap (UVmap) 重新映射该图像的像素。 对于那些不熟悉它的人,STMap 看起来像这样:link 但可以有多种形状。 它与我的原始图像大小相同,仅包含红色和绿色 channel (蓝色为空)。红色代表 X 轴,绿色代表 Y 轴。 因此,例如,要获取原始图像中位于 [100,100] 位置的像素的新坐标,我将转到 STMap 中的相同位置并查找该像素的红色 channel 值(这将是新的 X 值)和绿色值(新的 Y 值)。
那我该怎么做呢?我不太确定.. 我尝试添加 STMap 纹理,但它不允许我使用它的红色和绿色 channel 值(请参阅片段着色器)。谢谢!
编辑:
我用我试过但没有用的东西编辑了我的代码..
请您参考如下方法:
由于我没有所有资源,所以我无法在此处运行您的代码。
从着色器的角度来看,您可以使用texture2 坐标修改texture1 坐标。 有很多方法可以做到这一点,例如,您可以通过向其添加 UVMap 值来转换它们。这里,texture2 包含 UVMap 数据:
uniform sampler2D texture1;
uniform sampler2D texture2;
varying vec2 v_texture_coordinates;
vec2 my_new_coords;
vec4 uvmap;
void main() {
// uv map data at current position
uvmap = texture2D(texture2, v_texture_coordinates);
// map current position by using uv map data
my_new_coords.x = v_texture_coordinates.x + uvmap.r;
my_new_coords.y = v_texture_coordinates.y + uvmap.g;
// sample texture 2 with new mapped coordinates
gl_FragColor = texture2D(texture1, my_new_coords);
}
或者如果你只想使用来自 UVMap 的坐标,你可以这样做
gl_FragColor = texture2D(texture1, uvmap);
