【发布时间】:2021-03-10 12:17:29
【问题描述】:
使用 Python 和 OpenGL,我正在创建一个简单的 RGBA = (1,0,0,1) 红色三角形并将其保存为 bmp。然后我使用 CV2 加载图像并提取可以看到的 RGBA 颜色。
我希望红色和背景色成为图像中唯一的颜色。
这段代码并不漂亮,但成功生成三角形图像并将其保存为 bmp:
from OpenGL.GLUT import *
from OpenGL.GLU import *
from OpenGL.GL import *
from OpenGL.GL import shaders
import numpy as np
from PIL import Image
import cv2
VERTEX_SHADER = """
#version 330
in vec4 position;
void main() {
gl_Position = position;
}
"""
FRAGMENT_SHADER = """
#version 330
void main() {
gl_FragColor = vec4(1.0f, 0.0f, 0.0f, 1.0f);
}
"""
shaderProgram = None
WIDTH, HEIGHT = 200,200
def initialize():
global VERTEX_SHADER
global FRAGMENT_SHADER
global shaderProgram
vertexshader = shaders.compileShader(VERTEX_SHADER, GL_VERTEX_SHADER)
fragmentshader = shaders.compileShader(FRAGMENT_SHADER, GL_FRAGMENT_SHADER)
shaderProgram = shaders.compileProgram(vertexshader, fragmentshader)
triangles = [-0.5, -0.5, 0.0,
0.5, -0.5, 0.0,
0.0, 0.5, 0.0]
triangles = np.array(triangles, dtype=np.float32)
VBO = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, VBO)
glBufferData(GL_ARRAY_BUFFER, triangles.nbytes, triangles, GL_STATIC_DRAW)
position = glGetAttribLocation(shaderProgram, "position")
glVertexAttribPointer(position, 3, GL_FLOAT, GL_FALSE, 0, None)
glEnableVertexAttribArray(position)
def render():
glClearColor(0,0,0,1)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glUseProgram(shaderProgram)
glDrawArrays(GL_TRIANGLES,0,3)
glUseProgram(0)
# Save a screenshot
screenshot_file_path = 'test.bmp'
data = glReadPixels(0,0,200,200, GL_RGBA,GL_UNSIGNED_BYTE)
image = Image.frombytes('RGBA',(200, 200), data)
image.save(screenshot_file_path, 'bmp')
print('Image saved to ' + screenshot_file_path)
glutSwapBuffers()
def main():
glutInit()
glutInitWindowSize(WIDTH, HEIGHT)
glutInitWindowPosition(200,200)
glutCreateWindow("Modern Opengl Triangle")
initialize()
glutDisplayFunc(render)
glutMainLoop()
if __name__ == "__main__":
main()
但是当我解析图像的颜色时,我看到了 3 个 RGB 三元组!而不是预期的 2.
图片解析代码:
import cv2
import numpy as np
imgfile = r"test.bmp"
npimg = cv2.imread(imgfile)
# cv2 reads the file into BGR, but we want to see the color as RGB
npimg = cv2.cvtColor(npimg, cv2.COLOR_BGR2RGB)
# Get unique RGB colors
uniqueRGB, uniqueRGBcounts = np.unique(npimg.reshape(-1, npimg.shape[2]), axis=0, return_counts=True)
print(uniqueRGB)
结果是:
[[ 0 0 0] <- Background
[188 0 0] <- ??? some other red
[255 0 0]] <- Desired red
发生了什么事?谁能解释额外的三胞胎是从哪里来的?更重要的是,如何确保只有 (255,0,0) 和背景 (0,0,0) RGB 被保存到 bmp 图像中?
【问题讨论】:
-
首先想到的是您已将图形驱动程序的抗锯齿设置设置为强制或“增强”。但是,您确实想为您的用例使用屏幕外 FBO,否则屏幕上不可见的像素将具有未定义的值。
-
@derhass 感谢您的洞察力。我没有考虑任何图形驱动程序设置。会调查的。我同意使用屏幕外缓冲区。
-
@derhass 我在 NVIDIA 控制面板中禁用了抗锯齿设置,但在重新生成和解析图像后,我仍然看到额外的 RGB。禁用抗锯齿后,额外的 RGB 三元组从 [188,0,0] 更改为 [127,0,0]。不知道该怎么做。
标签: python opengl graphics pyopengl