Project

General

Profile

Codes » CalculateDisplayImage.py

Anonymous, 01/12/2022 05:49 PM

 
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.image_width = CR.getImageWidth()
24
        self.image_height = CR.getImageHeight()
25
        self.gamma = CR.getGamma()
26
        self.method = CR.getMethod()
27
        self.np_left = IR.getImage()[0]
28
        self.np_right = IR.getImage()[1]
29
        self.overlap_pixels = round(
30
            self.image_width*(projector_image_width - projector_distance)/projector_image_width)
31

    
32
    ##
33
    # @brief
34
    # Get the blended image.
35
    # @param corrected_tuple contains the gamma corrected image left and right.
36
    # @return RGB formatted blended images.
37
    def getDisplayImage(self, corrected_tuple):
38
        corrected_left, corrected_right = corrected_tuple
39
        # to RGB
40
        blended_left = np.rint(corrected_left*255).astype(np.uint8)
41
        blended_right = np.rint(corrected_right*255).astype(np.uint8)
42
        # save images
43
        cv.imwrite('src/blended_left.jpg', blended_left)
44
        cv.imwrite('src/blended_right.jpg', blended_right)
45
        return blended_left, blended_right
46

    
47
    ##
48
    # @brief
49
    # Control the texture of the mask.
50
    # @param distance is the distance from the start point of the target overlap region.
51
    # @param monotonicity is the monotonicity of the intensity function.
52
    # @return Intensity control value.
53
    def intensityController(self, distance, monotonicity):
54

    
55
        if monotonicity == 'linearly_increase':
56
            return -distance/self.overlap_pixels + 1
57
        elif monotonicity == 'linearly_decrease':
58
            return distance/self.overlap_pixels
59
        elif monotonicity == 'nonlinearly_increase':
60
            return -np.power(distance/self.overlap_pixels, 2) + 1
61
        elif monotonicity == 'nonlinearly_decrease':
62
            return np.power(distance/self.overlap_pixels, 2)
63

    
64
    ##
65
    # @brief
66
    # Generates masks.
67
    # @param direction is the direction of the mask.
68
    # @return Gradient masks (in linear case).
69
    def maskGenerator(self, direction):
70
        
71
        # assume images have the same size
72
        mask = np.ones(self.np_left.shape)
73
        for columns in range(self.image_width-self.overlap_pixels-1, self.image_width):
74
            mask[0, columns, :] *= self.intensityController(
75
                columns-(self.image_width-self.overlap_pixels-1), monotonicity=self.method+'ly_increase')
76
        # replacement is more efficient than multiplication
77
        for rows in range(1, self.image_height):
78
            mask[rows, :, :] = mask[0, :, :]
79

    
80
        if direction == 'left':
81
            return mask
82
        elif direction == 'right':
83
            # flip direction of mask to right
84
            return np.flip(mask, axis=1)
85

    
86
    ##
87
    # @brief
88
    # Get gamma corrected image.
89
    # @param img is the image blended with masks.
90
    # @param direction is the direction of the image.
91
    # @param gamma is the gamma value.
92
    # @return Gamma corrected numpy array.
93
    def gammaCorrection(self, img, direction, gamma):
94

    
95
        if direction == 'left':
96
            for rows in range(self.image_height):
97
                for columns in range(self.image_width-self.overlap_pixels-1, self.image_width):
98
                    img[rows][columns][:] *= np.power(self.intensityController(
99
                        columns-(self.image_width-self.overlap_pixels-1), monotonicity=self.method + 'ly_increase'), gamma)
100
            return img
101

    
102
        elif direction == 'right':
103
            for rows in range(self.image_height):
104
                for columns in range(self.overlap_pixels-1):
105
                    img[rows][columns][:] *= np.power(
106
                        self.intensityController(columns, monotonicity=self.method + 'ly_decrease'), gamma)
107
            return img
108

    
109
    ##
110
    # @brief
111
    # Calculate the image to display.
112
    # @return final blended image left and right.
113
    def calculate(self):
114
        # generate masks
115
        mask_left = self.maskGenerator(
116
            direction='left')
117
        mask_right = self.maskGenerator(
118
            direction='right')
119
        # blend images with masks
120
        with_mask_left = np.multiply(self.np_left, mask_left)
121
        with_mask_right = np.multiply(self.np_right, mask_right)
122
        # apply gamma correction
123
        corrected_left = self.gammaCorrection(
124
            with_mask_left, direction='left', gamma=self.gamma)
125
        corrected_right = self.gammaCorrection(
126
            with_mask_right, direction='right', gamma=self.gamma)
127
        return corrected_left, corrected_right
128

    
129
    ## @var gamma
130
    # Gamma value.
131
    ## @var method
132
    # Method of intensity control.
133
    ## @var np_left
134
    # Normalized Numpy array of left image.
135
    ## @var np_right
136
    # Normalized Numpy array of right image.
137
    ## @var overlap_pixels
138
    # Overlap region width.
139
    ## @var image_height
140
    # Image height.
141
    ## @var image_width
142
    # Image width.
(1-1/4)