This repository has been archived by the owner on Jan 4, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathprojector.py
118 lines (96 loc) · 4.11 KB
/
projector.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
'''Module for Projector class'''
from __future__ import annotations
import cv2
import numpy as np
import config
class Projector():
'''
Class to control projector during experiment
'''
def __init__(self, width: int, height: int, min_brightness: float = 0, max_brightness: float = 255):
self.width = width
self.height = height
self.__min_image_brightness = min_brightness
self.__max_image_brightness = max_brightness
self.window_exist: bool = False
def set_up_window(self) -> None:
'''
Open new window thru OpenCV GUI and show it on second extended screen
'''
cv2.namedWindow('Projector window', cv2.WND_PROP_FULLSCREEN)
cv2.setWindowProperty('Projector window', cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)
# TODO: remove magic number 1920 with screen resolution for multimonitor case
# https://stackoverflow.com/questions/3129322/how-do-i-get-monitor-resolution-in-python
cv2.moveWindow('Projector window', config.PROJECTOR_WINDOW_SHIFT, 0)
self.window_exist = True
def project_pattern(self, pattern: np.ndarray, correction: bool = True) -> None:
'''
Project pattern thru OpenCV GUI window, before projection pattern is intensity corrected
Args:
pattern (numpy array): image to project with OpenCV imshow method
correction (bool): do intensity correction before project pattern
'''
# Open OpenCV GUI window, if it is has not been already opened
if not self.window_exist:
self.set_up_window()
# Correct image with calibration coefficients
if correction:
self._corrected_pattern = self.image_brightness_rescale_factor * ((pattern / config.PROJECTOR_GAMMA_A) ** (1 / config.PROJECTOR_GAMMA_B)) + self.min_image_brightness
else:
self._corrected_pattern = pattern
# Show image at OpenCV GUI window
cv2.imshow('Projector window', self._corrected_pattern)
def project_black_background(self) -> None:
'''
Project black pattern thru OpenCV GUI window for projector off emulation
'''
# Open OpenCV GUI window, if it is has not been already opened
if not self.window_exist:
self.set_up_window()
# Create black bakground image
background = np.zeros((self.height, self.width))
# Show image at OpenCV GUI window
cv2.imshow('Projector window', background)
cv2.waitKey(200)
def project_white_background(self) -> None:
'''
Project white pattern thru OpenCV GUI window for using projector as light source
'''
# Open OpenCV GUI window, if it is has not been already opened
if not self.window_exist:
self.set_up_window()
# Create black bakground image
background = np.ones((self.height, self.width)) * 255
# Show image at OpenCV GUI window
cv2.imshow('Projector window', background)
cv2.waitKey(200)
def close_window(self) -> None:
'''
Close opened OpenCV GUI window on second extended screen
'''
cv2.destroyWindow('Projector window')
self.window_exist = False
@property
def corrected_pattern(self) -> np.ndarray:
'''
Return last projected corrected pattern as numpy array
'''
return self._corrected_pattern
@property
def resolution(self) -> tuple[int, int]:
return self.width, self.height
@property
def min_image_brightness(self) -> float:
return self.__min_image_brightness
@min_image_brightness.setter
def min_image_brightness(self, value: float):
self.__min_image_brightness = value
@property
def max_image_brightness(self) -> float:
return self.__max_image_brightness
@max_image_brightness.setter
def max_image_brightness(self, value: float):
self.__max_image_brightness = value
@property
def image_brightness_rescale_factor(self) -> float:
return (self.max_image_brightness - self.min_image_brightness)