【问题标题】:Why are extra RGB colors appearing in PyOpenGL generated bitmap image?为什么 PyOpenGL 生成的位图图像中会出现额外的 RGB 颜色?
【发布时间】: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


【解决方案1】:

就像@derhass 建议的那样,这是由于抗锯齿。在我上面的评论中,我没有完全关闭抗锯齿并且仍然看到奇怪的结果。完全禁用它后,我的位图中只有我想要的红色和背景颜色!

因此,对于任何其他涉足图像生成的新手,如果您需要指定或读取图像中的确切颜色,请确保禁用抗锯齿!

编辑:下面的评论建议我提供有关如何禁用抗锯齿的更多详细信息:

我相信这将取决于所使用的 GPU 或图形驱动程序。我有一个 NVIDIA GPU,所以我使用 NVIDIA 控制面板应用程序更改了我的设置。任何引用“抗锯齿”的功能都已更改为关闭设置。这是我的 NVIDIA 控制面板(3D 设置选项卡)设置的屏幕截图

【讨论】:

  • 如果您提供有关如何明确禁用抗锯齿的详细信息,这将是一个更好的答案。
猜你喜欢
  • 2020-10-04
  • 1970-01-01
  • 1970-01-01
  • 2018-04-01
  • 2019-12-03
  • 2012-08-31
  • 2010-10-26
  • 1970-01-01
  • 2011-11-22
相关资源
最近更新 更多