1
|
import cv2 as cv
|
2
|
import numpy as np
|
3
|
from ConfigureReader import ConfigureReader
|
4
|
from ImageReader import ImageReader
|
5
|
|
6
|
CR = ConfigureReader()
|
7
|
IR = ImageReader()
|
8
|
|
9
|
##
|
10
|
# @brief
|
11
|
#
|
12
|
# This class calculates blended image.
|
13
|
# This class is made by Minghao, Shiva, Son, and Vaibhav, Doxygened by Rikuto Momoi
|
14
|
#
|
15
|
|
16
|
|
17
|
class CalculateDisplayImage(object):
|
18
|
|
19
|
# The constructor
|
20
|
def __init__(self):
|
21
|
projector_image_width = CR.getProjectorImageWidth()
|
22
|
projector_distance = CR.getProjectorDistance()
|
23
|
self.gamma = CR.getGamma()
|
24
|
self.method = CR.getMethod()
|
25
|
self.np_left = IR.getImage()[0]
|
26
|
self.np_right = IR.getImage()[1]
|
27
|
self.overlap_pixels = round(
|
28
|
self.np_left.shape[1]*(projector_image_width - projector_distance)/projector_image_width)
|
29
|
|
30
|
##
|
31
|
# @brief
|
32
|
# Get the blended image
|
33
|
# @param corrected_tuple contains the gamma corrected image left and right
|
34
|
# @return RGB formatted blended images
|
35
|
def getDisplayImage(self, corrected_tuple):
|
36
|
corrected_left, corrected_right = corrected_tuple
|
37
|
# to RGB
|
38
|
blended_left = np.rint(corrected_left*255).astype(np.uint8)
|
39
|
blended_right = np.rint(corrected_right*255).astype(np.uint8)
|
40
|
# save images
|
41
|
cv.imwrite('src/blended_left.jpg', blended_left)
|
42
|
cv.imwrite('src/blended_right.jpg', blended_right)
|
43
|
return blended_left, blended_right
|
44
|
|
45
|
##
|
46
|
# @brief
|
47
|
# Control the texture of the mask
|
48
|
# @param distance is the distance from the start point of the target overlap region
|
49
|
# @param monotonicity is the monotonicity of the intensity function
|
50
|
# @return Intensity control value
|
51
|
def intensityController(self, distance, monotonicity):
|
52
|
|
53
|
if monotonicity == 'linearly_increase':
|
54
|
return -distance/self.overlap_pixels + 1
|
55
|
elif monotonicity == 'linearly_decrease':
|
56
|
return distance/self.overlap_pixels
|
57
|
elif monotonicity == 'nonlinearly_increase':
|
58
|
return -np.power(distance/self.overlap_pixels, 2) + 1
|
59
|
elif monotonicity == 'nonlinearly_decrease':
|
60
|
return np.power(distance/self.overlap_pixels, 2)
|
61
|
|
62
|
##
|
63
|
# @brief
|
64
|
# Generates masks
|
65
|
# @param mask is a white mask with the same size of the image
|
66
|
# @param direction is the direction of the mask
|
67
|
# @return gradient masks (in linear case)
|
68
|
def maskGenerator(self, mask, direction):
|
69
|
|
70
|
for columns in range(mask.shape[1]-self.overlap_pixels-1, mask.shape[1]):
|
71
|
mask[0, columns, :] *= self.intensityController(
|
72
|
columns-(mask.shape[1]-self.overlap_pixels-1), monotonicity=self.method+'ly_increase')
|
73
|
# replacement is more efficient than multiplication
|
74
|
for rows in range(1, mask.shape[0]):
|
75
|
mask[rows, :, :] = mask[0, :, :]
|
76
|
|
77
|
if direction == 'left':
|
78
|
return mask
|
79
|
elif direction == 'right':
|
80
|
# flip direction of mask to right
|
81
|
return np.flip(mask, axis=1)
|
82
|
|
83
|
##
|
84
|
# @brief
|
85
|
# Get gamma corrected image
|
86
|
# @param img is the image blended with masks
|
87
|
# @param direction is the direction of the image
|
88
|
# @param gamma is the gamma value
|
89
|
# @return gamma corrected numpy array
|
90
|
def gammaCorrection(self, img, direction, gamma):
|
91
|
|
92
|
if direction == 'left':
|
93
|
for rows in range(img.shape[0]):
|
94
|
for columns in range(img.shape[1]-self.overlap_pixels-1, img.shape[1]):
|
95
|
img[rows][columns][:] *= np.power(self.intensityController(
|
96
|
columns-(img.shape[1]-self.overlap_pixels-1), monotonicity=self.method + 'ly_increase'), gamma)
|
97
|
return img
|
98
|
|
99
|
elif direction == 'right':
|
100
|
for rows in range(img.shape[0]):
|
101
|
for columns in range(self.overlap_pixels-1):
|
102
|
img[rows][columns][:] *= np.power(
|
103
|
self.intensityController(columns, monotonicity=self.method + 'ly_decrease'), gamma)
|
104
|
return img
|
105
|
|
106
|
##
|
107
|
# @brief
|
108
|
# Calculate the image to display
|
109
|
# @return final blended image left and right
|
110
|
def calculate(self):
|
111
|
# generate masks
|
112
|
mask_left = self.maskGenerator(
|
113
|
np.ones(self.np_left.shape), direction='left')
|
114
|
mask_right = self.maskGenerator(
|
115
|
np.ones(self.np_right.shape), direction='right')
|
116
|
# blend images with masks
|
117
|
with_mask_left = np.multiply(self.np_left, mask_left)
|
118
|
with_mask_right = np.multiply(self.np_right, mask_right)
|
119
|
# apply gamma correction
|
120
|
corrected_left = self.gammaCorrection(
|
121
|
with_mask_left, direction='left', gamma=self.gamma)
|
122
|
corrected_right = self.gammaCorrection(
|
123
|
with_mask_right, direction='right', gamma=self.gamma)
|
124
|
return corrected_left, corrected_right
|