Подпиксельная рендеринг в OpenGL – проблема точности

Мне нужно создать несколько серий тестовых изображений для фотограмметрического приложения. Они должны содержать простые объекты (диски, прямоугольники и т. Д.) С очень точно известным положением.

Учитывая 8-битное изображение в оттенках серого черного прямоугольника на белом фоне, минимальное наблюдаемое смещение (после интерполяции) должно быть 1/256 пикселя, так как имеется 256 возможных уровней интенсивности каждого пикселя.

Я решил использовать OpenGL (с питоном + pyglet) для рендеринга таких изображений, так как позже мне придется делать более сложные (3d-сцены, пары стереоизображений)

К сожалению, лучшая точность, которую я достиг, составляет около пикселя / 10, глубина полной интенсивности не используется.

Можно ли сделать лучше, в идеале – достижение полной 1/256-пиксельной точности? Любые подсказки о том, как это сделать, пожалуйста?

образец кода, генерирующий изображения частичного диска, перемещался на 0,01 пикселя больше в каждом кадре

#-*- coding: utf-8 -*- import pyglet from pyglet.gl import * from PIL import Image, ImageGrab config = pyglet.gl.Config(width = 800, height = 600, sample_buffers=1, samples=16) window = pyglet.window.Window(config=config, resizable=True) window.set_size(800, 600) printScreenNr = 0 @window.event def on_draw(): global printScreenNr window.clear() glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glLoadIdentity() glEnable(GL_LINE_SMOOTH) glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); glTranslated(200, 200,0) circleQuad = gluNewQuadric() glTranslated(200+(printScreenNr*0.01), 0, 0) gluPartialDisk(circleQuad, 0, 50, 500, 500, 0, 180) @window.event def on_resize(width, height): glViewport(0, 0, width, height) glMatrixMode(GL_PROJECTION) glLoadIdentity() glOrtho (0, width, height, 0, 0, 1); glMatrixMode(GL_MODELVIEW) return pyglet.event.EVENT_HANDLED @window.event def on_text(text): global printScreenNr if(text == "p"): pyglet.image.get_buffer_manager().get_color_buffer().save('photo'+str(printScreenNr)+'.tiff') printScreenNr += 1 pyglet.app.run() 

(в приведенном выше коде используется gluPartialDisk, но я проверял проблему также с использованием четырехугольников, точность результатов не отличалась)

2 Solutions collect form web for “Подпиксельная рендеринг в OpenGL – проблема точности”

Простой способ сделать это – увеличить масштаб изображения. Если вы масштабируете изображение на 4.0, тогда 16 исходных пикселей будут объединены в один целевой пиксель, который даст вам 16 оттенков серого при масштабировании чистого черно-белого изображения.

Но есть уловка, которая, вероятно, объясняет вашу проблему. Если у вас есть это:

  ...##### ...##### ...##### ...##### 

(слева: белый, правый: черный заполненный прямоугольник), тогда у вас есть 12 белых и 4 чёрных пикселя, которые вносят вклад в один выходной пиксель. Чтобы получить 1 черный пиксель, вход должен быть следующим:

  ....#### ....#### ....#### ...##### 

Видеть? Несмотря на то, что черный ящик пропускает только один пиксель в белое пространство, он делает это четыре раза. Поэтому, чтобы убедиться, что ваш код подпиксельной рендеринга работает, вам нужно посмотреть на отдельные пиксели или углы, а не на края.

Даже если вы используете ортогональную проекцию, GL_PERSPECTIVE_CORRECTION_HINT может повлиять на точность рендеринга. По крайней мере, я смутно помню glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); исправляя некоторые пробелы на моей ортогонально спроектированной сцене много лет назад.

  • Ошибка с PyOpenGL
  • Текстура PyOpenGL numpy отображается как сплошной цвет
  • matplotlib: отображение в буфер / данные пикселя доступа
  • OpenGL говорит, что «from_param получил несмежный массив»
  • Как показать полупрозрачное окно над всеми окнами?
  • Kivy не обнаруживает OpenGL 2.0
  • Ищете простой пример OpenGL (3.2+) Python, который использует GLFW
  • three.js to webGL to OpenGL
  •  
    Interesting Posts for Van-Lav
    Python - лучший язык программирования в мире.