2012-08-06 47 views
7

Tôi cần tạo một vài hình ảnh thử nghiệm cho ứng dụng hình ảnh. Những nội dung này phải chứa các đối tượng đơn giản (đĩa, hình chữ nhật, v.v.) với vị trí rất chính xác.Hiển thị pixel phụ trong OpenGL - vấn đề về độ chính xác

Xem xét hình ảnh thang độ xám 8 bit của hình chữ nhật màu đen trên nền trắng, chuyển vị quan sát nhỏ nhất (sau khi nội suy) phải là 1/256 pixel, vì có 256 mức cường độ có thể có của mỗi pixel.

tôi quyết định sử dụng OpenGL (với python + pyglet) để render hình ảnh như vậy, như sau này tôi sẽ phải làm phức tạp hơn (cảnh 3d, cặp ảnh stereo)

Thật không may, độ chính xác tốt nhất mà tôi đã đạt được khoảng pixel/10, độ sâu cường độ đầy đủ không được sử dụng.

Có thể làm tốt hơn, lý tưởng - đạt được độ chính xác 1/256 pixel đầy đủ không? Bất kỳ gợi ý về cách làm điều đó, xin vui lòng?

mẫu mã, tạo ra hình ảnh của một đĩa cục bộ, di chuyển 0,01 điểm ảnh nhiều hơn trong mỗi khung

#-*- 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() 

(mã trên được sử dụng gluPartialDisk, nhưng tôi đã thử nghiệm vấn đề này cũng sử dụng tứ, chính xác kết quả đã làm không khác nhau)

+0

Bạn đã thử sử dụng độ sâu màu 32 bit chưa? Lý do tôi nói điều này là các đường dẫn 32 bit là các đường dẫn mã được sử dụng nhiều nhất và do đó được duy trì nhiều nhất trong các trình điều khiển đồ họa hiện nay. Nếu công trình này hoạt động, sau đó bạn có thể thực hiện rescale độ sâu màu chất lượng cao sau đó. – Ani

+0

đã thử điều đó, nhưng không thay đổi kết quả ... vẫn còn, cảm ơn bạn – Pietro

Trả lời

4

Cách đơn giản để thực hiện việc này là chia tỷ lệ hình ảnh theo hệ số. Nếu bạn chia tỷ lệ hình ảnh lên 4.0, thì 16 pixel gốc sẽ được hợp nhất thành một pixel mục tiêu cung cấp cho bạn 16 sắc thái xám khi thu phóng hình ảnh B & W thuần túy.

Nhưng có một sự kiện có thể giải thích được vấn đề của bạn. Nếu bạn có điều này:

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

(bên trái: trắng, phải: hình chữ nhật đầy màu đen), sau đó bạn có 12 pixel trắng và 4 pixel đóng góp vào một pixel đầu ra. Để nhận được 1 pixel màu đen, đầu vào sẽ cần phải là:

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

See? Mặc dù hộp đen chỉ rò rỉ một pixel vào không gian màu trắng, nó làm như vậy bốn lần. Vì vậy, để đảm bảo mã kết xuất subpixel của bạn hoạt động, bạn cần phải xem các pixel hoặc góc đơn lẻ, không phải ở các cạnh.

+0

Hiển thị hình ảnh lớn hơn sẽ là một giải pháp, nhưng tôi nghĩ kích thước của màn hình là một giới hạn? Vì vậy, nó sẽ không giúp ích nhiều cho Về phần khác của câu trả lời, tôi không chắc liệu tôi có hiểu chính xác hay không ... nếu hình ảnh được chia tỷ lệ 4x (theo mỗi hướng). cạnh (và 16 khi quan sát một điểm) nhưng vẫn có thể bằng cách nào đó để tạo ra một cạnh được định vị với độ chính xác đầy đủ – Pietro

+0

Làm thế nào? cạnh chỉ có bốn vị trí khác nhau, vì vậy bạn chỉ có thể nhận được 4 trong 16 màu. –

+0

hãy sửa tôi nếu tôi vẫn sai Giả sử hình ảnh đã được thu nhỏ theo 256 yếu tố. Một cạnh sẽ có 256 vị trí và một điểm: 256^2 (được làm tròn) Tôi không biết, nếu điều đó có thể thực hiện trong OpenGL (trong trường hợp này không phải là vấn đề), nhưng tôi nghĩ rằng hình ảnh đáp ứng các yêu cầu này thường có thể tạo ra. Câu hỏi của tôi chỉ là: làm thế nào để làm điều đó .. – Pietro

1

Mặc dù bạn đang sử dụng phép chiếu trực giao, GL_PERSPECTIVE_CORRECTION_HINT có thể có tác động đến độ chính xác hiển thị. Ít nhất tôi mơ hồ nhớ glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); sửa một số khoảng trống trên cảnh chiếu trực giao của tôi cách đây nhiều năm.

+0

Cảm ơn bạn, đã thêm rằng, không thay đổi kết quả vào lúc này, nhưng có thể sẽ cần thiết trong chế độ 3d trong tương lai – Pietro

Các vấn đề liên quan