出于调试目的,我决定编写纹理导出函数:
def image_export(self, file_name: str):
im_format = file_name.rsplit('.')[-1]
if im_format in ('jpg',):
iformat = gl.GL_BGR
elif im_format in ('png',):
iformat = gl.GL_BGRA
else:
raise NotImplementedError
with self: # binding texture
# gl.glPixelStorei(gl.GL_PACK_ALIGNMENT, 1)
im = (gl.glGetTexImage(gl.GL_TEXTURE_2D, 0, iformat, gl.GL_FLOAT) * 255).astype('uint8')
im = np.flip(im, axis=0)
cv2.imwrite(file_name, im)
使用500x500纹理进行测试,效果良好:
但当我尝试500x600时,事情变得很奇怪:
我必须重新塑造它以获得理想的形象:
# ...
im = im.reshape((600, 500, 3)) # added line
im = np.flip(im, axis=0)
cv2.imwrite(file_name, im)
然后会导致:
最近我问了一个问题glTexImage2D data not filled as expected,所以我尝试了gl.glPixelStorei(gl.GL_PACK_ALIGNMENT, 1)
,但没有发现它有任何影响。整形没有意义。没有整形,我应该简单地得到90度旋转的图像。我不明白什么?
增加:
阅读完评论后,试图总结我的理解。你(有人)能验证我的结论吗?
1条答案
按热度按时间p8ekf7hl1#
reshape
与transpose
不同。reshape
不会变更轴(因此不会旋转),但会变更数组的形体(长度和高度)。例如:
第一个
整形:
转置:
第一个
glGetTexImage
返回一个形状为(width,height,channels)的数组。这意味着RGB 200x100图像的形状为(200,100,3)。您可以使用print(im.shape)
验证此结果。但是,
numpy.ndarray.shape
是以行主顺序(* 行 , 列 *)指定的。这意味着numpy.array
的形状不是**(4,2)而是(2,4)。
表示RGB 4x2图像的数组的形状
是(2,4,3)。
PyOpenGL和NumPy(cv2)对形状的解释不同。因此,您必须更改形状和
reshape
数组:总结:这并不复杂。PyOpenGL以(w,h,c)的形式返回形状信息,但NumPy期望(h,w,c)。图像的像素是线性存储的。顺序不需要改变,但它们的解释方式必须改变。