Project

General

Profile

Codes » History » Revision 5

Revision 4 (Anonymous, 01/12/2022 05:59 PM) → Revision 5/6 (Anonymous, 01/12/2022 06:04 PM)

h1. Codes 

 h2. MainDisplay.py : To calculate display blended image  

 images 

 <pre><code class="python"> 
 import cv2 as cv 
 from CalculateDisplayImage import CalculateDisplayImage 

 CDI = CalculateDisplayImage() 

 ## 
 # @brief 
 # 
 # This class displays blended images. 
 # This class is made by Vaibhav, Doxygened by Xu Minghao. 
 # 


 class MainDisplay(object): 

     ## 
     # @brief 
     # Display the blended images. 
     # @param img is the image blended with masks. 
     def display(img): 
         cv.imshow('img', img) 
         cv.waitKey(0) 
         cv.destroyAllWindows() 

     # The constructor. 
     def __init__(self): 
         pass 

     ## A class variable. 
     # To store the blended images. 
     res = CDI.getDisplayImage(CDI.calculate()) 

     display(res[0]) 
     # display(res[1]) 

 </code></pre> 


 h2. CalculateDisplayImage.py : To calculate blended image  

 <pre><code class="python"> 
 import cv2 as cv 
 import numpy as np 
 from ConfigureReader import ConfigureReader 
 from ImageReader import ImageReader 

 CR = ConfigureReader() 
 IR = ImageReader() 

 ## 
 # @brief 
 # 
 # This class calculates blended image. 
 # This class is made by Minghao, Shiva, Son, and Vaibhav, Doxygened by Rikuto Momoi. 
 # 


 class CalculateDisplayImage(object): 

     # The constructor 
     def __init__(self): 
         projector_image_width = CR.getProjectorImageWidth() 
         projector_distance = CR.getProjectorDistance() 
         self.image_width = CR.getImageWidth() 
         self.image_height = CR.getImageHeight() 
         self.gamma = CR.getGamma() 
         self.method = CR.getMethod() 
         self.np_left = IR.getImage()[0] 
         self.np_right = IR.getImage()[1] 
         self.overlap_pixels = round( 
             self.image_width*(projector_image_width - projector_distance)/projector_image_width) 

     ## 
     # @brief 
     # Get the blended image. 
     # @param corrected_tuple contains the gamma corrected image left and right. 
     # @return RGB formatted blended images. 
     def getDisplayImage(self, corrected_tuple): 
         corrected_left, corrected_right = corrected_tuple 
         # to RGB 
         blended_left = np.rint(corrected_left*255).astype(np.uint8) 
         blended_right = np.rint(corrected_right*255).astype(np.uint8) 
         # save images 
         cv.imwrite('src/blended_left.jpg', blended_left) 
         cv.imwrite('src/blended_right.jpg', blended_right) 
         return blended_left, blended_right 

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

         if monotonicity == 'linearly_increase': 
             return -distance/self.overlap_pixels + 1 
         elif monotonicity == 'linearly_decrease': 
             return distance/self.overlap_pixels 
         elif monotonicity == 'nonlinearly_increase': 
             return -np.power(distance/self.overlap_pixels, 2) + 1 
         elif monotonicity == 'nonlinearly_decrease': 
             return np.power(distance/self.overlap_pixels, 2) 

     ## 
     # @brief 
     # Generates masks. 
     # @param direction is the direction of the mask. 
     # @return Gradient masks (in linear case). 
     def maskGenerator(self, direction): 
        
         # assume images have the same size 
         mask = np.ones(self.np_left.shape) 
         for columns in range(self.image_width-self.overlap_pixels-1, self.image_width): 
             mask[0, columns, :] *= self.intensityController( 
                 columns-(self.image_width-self.overlap_pixels-1), monotonicity=self.method+'ly_increase') 
         # replacement is more efficient than multiplication 
         for rows in range(1, self.image_height): 
             mask[rows, :, :] = mask[0, :, :] 

         if direction == 'left': 
             return mask 
         elif direction == 'right': 
             # flip direction of mask to right 
             return np.flip(mask, axis=1) 

     ## 
     # @brief 
     # Get gamma corrected image. 
     # @param img is the image blended with masks. 
     # @param direction is the direction of the image. 
     # @param gamma is the gamma value. 
     # @return Gamma corrected numpy array. 
     def gammaCorrection(self, img, direction, gamma): 

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

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

     ## 
     # @brief 
     # Calculate the image to display. 
     # @return final blended image left and right. 
     def calculate(self): 
         # generate masks 
         mask_left = self.maskGenerator( 
             direction='left') 
         mask_right = self.maskGenerator( 
             direction='right') 
         # blend images with masks 
         with_mask_left = np.multiply(self.np_left, mask_left) 
         with_mask_right = np.multiply(self.np_right, mask_right) 
         # apply gamma correction 
         corrected_left = self.gammaCorrection( 
             with_mask_left, direction='left', gamma=self.gamma) 
         corrected_right = self.gammaCorrection( 
             with_mask_right, direction='right', gamma=self.gamma) 
         return corrected_left, corrected_right 

     ## @var gamma 
     # Gamma value. 
     ## @var method 
     # Method of intensity control. 
     ## @var np_left 
     # Normalized Numpy array of left image. 
     ## @var np_right 
     # Normalized Numpy array of right image. 
     ## @var overlap_pixels 
     # Overlap region width. 
     ## @var image_height 
     # Image height. 
     ## @var image_width 
     # Image width. 

 </code></pre> 

 h2. ConfigureReader : Initialize the values to process the edge-blending 

 <pre><code class="python"> 
 from configparser import ConfigParser 

 ## 
 # @brief 
 # 
 # This class reads initial values that will be needed to process the edge-blending. 
 # This class is made by Son and Minghao, Doxygened by Konatsu. 
 # 


 class ConfigureReader(object): 

     # The constructor. 
     def __init__(self): 
         self.config = ConfigParser() 
         self.config.read('config.ini') 

     ## 
     # @brief 
     # Get split image height. 
     # @return image height in int. 
     def getImageWidth(self): 
         return int(self.config['DEFAULT']['ImageWidth']) 

     ## 
     # @brief 
     # Get split image width. 
     # @return image width in int. 
     def getImageHeight(self): 
         return int(self.config['DEFAULT']['ImageHeight']) 

     ## 
     # @brief 
     # Get distance between two projectors. 
     # @return projector distance in float. 
     def getProjectorDistance(self): 
         return float(self.config['DEFAULT']['projector_distance']) 

     ## 
     # @brief 
     # Get projected image width. 
     # @return image width in float. 
     def getProjectorImageWidth(self): 
         return float(self.config['DEFAULT']['projector_image_width']) 

     ## 
     # @brief 
     # Get gamma value. 
     # @return gamma value in float. 
     def getGamma(self): 
         return float(self.config['DEFAULT']['gamma']) 

     ## 
     # @brief 
     # Get edge-blending method. 
     # @return method in string. 
     def getMethod(self): 
         return str(self.config['DEFAULT']['method']) 

     ## 
     # @brief 
     # Get image path (image should be put inside src). 
     # @return image path in string. 
     def getImagePath(self): 
         return 'src/' + str(self.config['DEFAULT']['ImageNameLeft']), 'src/' + str(self.config['DEFAULT']['ImageNameRight']) 

     # @var config 
     # The configuration file. 

 </code></pre> 

 h2. ImageReader.py : To read image and normalize them into numpy array tuple. 

 <pre><code class="python"> 
 import cv2 as cv 
 import numpy as np 
 from ConfigureReader import ConfigureReader 

 CR = ConfigureReader() 

 ## 
 # @brief 
 # 
 # This class reads images and normalize them into numpy array tuple. 
 # This class is made by Shiva, Doxygened by Rikuto Momoi 
 # 


 class ImageReader(object): 

     # The constructer 
     def __init__(self): 
         pass 

     ## 
     # @brief  
     # Get image in a normalized numpy array 
     # @return normalized numpy array 
     def getImage(self): 
         return np.array(cv.imread(CR.getImagePath()[0]))/255, np.array(cv.imread(CR.getImagePath()[1]))/255 

 </code></pre>