Почему в растровом изображении, сгенерированном PyOpenGL, появляются дополнительные цвета RGB?

Используя 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-изображении?


person holli    schedule 27.11.2020    source источник
comment
Первое, что приходит на ум, это то, что вы установили настройки сглаживания графического драйвера на принудительные или улучшенные . Тем не менее, вы действительно хотите использовать закадровый FBO для вашего варианта использования, пиксели, которые не видны на экране, в противном случае будут иметь неопределенные значения.   -  person derhass    schedule 27.11.2020
comment
@derhass спасибо за понимание. Я не учел никаких настроек графического драйвера. Рассмотрю это. Я согласен с использованием закадрового буфера.   -  person holli    schedule 27.11.2020
comment
@derhass Я отключил настройки сглаживания в панели управления NVIDIA, и после повторной генерации и анализа изображения я все еще вижу дополнительный RGB. После отключения сглаживания дополнительный триплет RGB изменился с [188,0,0] на [127,0,0]. Не знаю, что с этим делать.   -  person holli    schedule 27.11.2020


Ответы (1)


Как и предполагал @derhass, это произошло из-за сглаживания. В моем комментарии выше я не полностью отключил сглаживание и все еще видел странные результаты. После его полного отключения в растровом изображении остаются только нужные мне красный и фоновый цвета!

Итак, для любых других нубов, занимающихся созданием изображений, где вам нужно указать или прочитать точные цвета в изображении, убедитесь, что сглаживание отключено!

РЕДАКТИРОВАТЬ: К комментарию ниже, предлагающему предоставить более подробную информацию о том, как отключить сглаживание:

Я считаю, что это будет зависеть от того, какой графический процессор или графические драйверы используются. У меня есть графический процессор NVIDIA, поэтому я изменил свои настройки с помощью приложения панели управления NVIDIA. Любая функция, ссылающаяся на сглаживание, была отключена. Вот скриншот настроек моей панели управления NVIDIA (вкладка 3D-настройки) CP

person holli    schedule 28.11.2020
comment
Это был бы лучший ответ, если бы вы подробно рассказали, как окончательно отключить сглаживание. - person Mark Ransom; 28.11.2020
comment
@MarkRansom - отредактировал мой ответ - person holli; 29.11.2020