Quiz/KlausurSS23

Revision as of 14:30, 19 August 2023 by Leonie (talk | contribs) (Created page + added first 3 questions)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

The SS23 exam with solutions. Try to solve it by yourself before checking the solution.

NOTE: All questions and answers are provided in german, as they appeared in the exam.

LINK!!

Grundwissen (12P.)

Aussagen

Bitte geben Sie für jede der folgenden Aussagen an, ob sie wahr oder falsch ist, indem Sie "W" oder "F" davorschreiben. Für falsche Antworten gibt es Punktabzug.

Der Bresenham-Algorithmus dient dazu, Kanten in Bildern zu finden.
Falsch. Der Bresenham-Algorithmus dient dazu, Linien zu zeichnen.


Der OpenGL Immediate Mode ist effizienter als Shader-basierte Alternativen.
TODO


OpenCV bietet Funktionen, um ein GUI zu implementieren.
TODO


Der Painter's Algorithm zeichnet jeden Pixel genau einmal.
TODO


Bezier-Kurven können mit dem De-Hondt-Verfahren berechnet werden.
TODO


Wenn man einen Weichzeichnungs-Filter auf ein Bild anwendet, bleibt die durchschnittliche Helligkeit aller Pixel im Bild gleich.
{{{answer}}}


Außenseiter

In jeder Zeile gehört ein Begriff nicht zu den anderen. Markiern Sie diesen fett.

  1. GLSL - GLEW - GLUT - GIMP
  2. Translucent - Ambient - Specular - Diffuse
  3. NeRF - SDF - Mesh - Graph
  4. Faltung - Rotation - Translation - Skalierung
  5. Vertex - Voxel - Vektor - Voltage
  6. ORB - ATOL - SURF - SIFT
Lösung
1: GIMP



Bildbearbeitung (30 P.)

Laden Sie das Bild "images/objects.jpg" (5 P.) und verbessern Sie es mittels OpenCV-Funktionen wie folgt:

  • der Kontrast soll maximiert werden (d.h. der hellste Pixel im Bild soll weiß werden, der dunkelste Pixel im Bild soll schwarz werden) (5 P.)
  • das Bild soll stark weichgezeichnet werden (5 P.)
  • über das Bild soll - halbtransparent und bildfüllend - der Schriftzug "CGBV" als Wasserzeichen gelegt werden (15 P.)

Verwenden Sie nur Numpy-/OpenCV-Funktionen.

Zeigen Sie das Bild im Notebook an (es muss nicht gespeichert werden)

img = None
# Hier könnte Ihre Lösung stehen!
show(img)



Lösung
# add Musterlösung


2D/3D-Grafik (39 P.)

ntenstehender Code soll einen sich drehenden, pulsierenden 3D-Würfel zeigen, dessen Farbe sich kontinuierlich ändert. Leider sind einige Bugs im Code. Beheben Sie diese:

  • drei Syntaxfehler (9 P.)
  • irgendwie ist der Würfel defekt. Korrigieren Sie seine Definition (5 P.)
  • die orthogonale Projektion sieht nicht schön aus. Verwenden Sie die perspektivische Projektion (5 P.)

Außerdem fehlt noch etwas Code. Ergänzen Sie diesen:

  • kontinuierliche Farbänderung - volle Punktzahl für loopenden Farbwechsel *(Tipp 1: HSV macht das einfacher. Tipp 2: wenn Sie fremden Code verwenden, achten Sie darauf, welchen Wertebereich die zurückgegebenen Werte haben. Tipp 3: Sie können die Werte in einem Numpy-Array einfach skalieren, indem Sie dieses mit einer Zahl multiplizieren)* (15 P.)
  • Lassen Sie den Würfel pulsieren, indem Sie seine Größe ändern (5 P.)
Code
# Define our simple 3D cube

#    1 - - - - - 7
#    - \         - \
#    -   3 - - - - - 5
#    -   -       -   -
#    -   -       -   -
#    -   -       -   -
#    0 - - - - - 6   -
#      \ -         \ -
#        2 - - - - - 4

cube_corners=[[-0.5, -0.5, -0.5],  # 0
              [-0.5, -0.5, 0.5],    # 1
              [-0.5, 0.5, -0.5],   # 2
              [-0.5, 0.5, 0.5],     # 3
              [0.5, 0.5, -0.5],    # 4
              [0.5, 0.5, 0.5],      # 5
              [0.5, -0.5, -0.5],   # 6
              [0.5, -0.5, 0.5]]     # 7

cube_edges = [(0, 2), (2, 4), (4, 6), (6, 0),
              (1, 3), (3, 5), (5, 7), (6, 1)
              (0, 1), (2, 3), (4, 5), (6, 2)]


def transform(points, angle=45):
    T = M([[1, 0, 0, 0],
           [0, 1, 0, 0],
           [0, 0, 1, 5],
           [0, 0, 0, 1]])
    
    cosa = cos(pi*angle/180)
    sina = sin(pi*angle/180)
    R = M([[cosa, 0, sina, 0],
           [0, 1, 0, 0],
           [-sina, 0, cosa, 0],
           [0, 0, 0, 1]])
 
    transformed_points = []
    for p in points:
        p_hom = p + [1]
        p_new = T @ R @ p_hom
        transformed_points.append(p_new)
    return transformed_points
        
def project(points, width=200, height=200, camera_distance = 2):
    P = M([[1, 0, 0, 0],
           [0, 1, 0, 0],
           [0, 0, 0, 0],
           [0, 0, 0, 1]])
    projected_points = []
    for p in points:
        p_new = P @ np.transpose(p)
        # assume points between -0.5 and 0.5
        x = int((float(p_new[0]/p_new[3]) + 0.5) * width)
        y = int((float(p_new[1]/p_new[3]) + 0.5) * width)
        projected_points.append((x,y))
    return projected_points

def cube(rotation=0, color=(255,255,255))
    projected_points = project(transform(cube_corners, rotation))
    cube_preview = np.zeros((200,200,3), np.unit8)
    for edge in cube_edges:
        p1 = projected_points[edge[0]]
        p2 = projected_points[edge[1]]
        cv2.line(cube_preview, p1, p2, color, 2)
    cube_preview = cv2.cvtColor(cube_preview, cv2.COLOR_BGR2RGB) # Converting BGR to RGB
    return(Image.fromarray(cube_preview))


from IPython.display import DisplayHandle
from time import sleep
d = DisplayHandle()
d.display(cube())


angle = 0
color = (255,255,0)
while True:
    angle += 5
    if angle > 360:
        angle = 0
    d.update(cube(angle, color))
    sleep(0.016)


Achtung: Hier muss man ggf. auf den "Interrupt Kernel"-Button klicken bzw. zweimal die Taste "I" drücken, um den Loop abzubrechen

Lösung
# add Musterlösung



Bildverarbeitung (35 P.)