Project

General

Profile

Actions

Codes » History » Revision 30

« Previous | Revision 30/33 (diff) | Next »
Mitsuki EIKI, 01/16/2025 02:13 PM


Codes

Wiki | About_Us | Project_Overview | UML_Diagram | Codes

Config Class Code

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from config import Config
from img_processor import ImgProcessor
from display_img import DisplayImg
import cv2

class MainStitcher:
    """!
    @brief A class responsible for stitching and displaying images in a projection system.

    The class integrates configuration settings from the `Config` class and display properties
    from the `DisplayImg` class to handle the main stitching and display logic.
    """ 

    def __init__(self, dImg):
        """!
        @brief Initializes the MainStitcher with configuration and display image settings.
        @param config An instance of the Config class containing projection configuration.
        @param dImg An instance of the DisplayImg class containing display settings.
        """ 
        self.__displayImg = dImg

    #for single monitor/mirroring
    def singleDisplay(self):
        """!
        @brief use two laptops to project the final processed images.
        """ 
        img = self.__displayImg.getImg()
        side = self.__displayImg.getSide()

        # cv2.namedWindow(side, cv2.WINDOW_NORMAL)
        cv2.imshow(side, img)
        # cv2.setWindowProperty(side, cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)

    #for double extended monitor
    def doubleDisplay(self, monitorWidth):
        """!
        @brief use two laptops to project the final processed images.
        """ 
        img = self.__displayImg.getImg()
        side = self.__displayImg.getSide()

        """ 
        In moveWindow(name, x, y), we can replace x with the window size or something
        """ 
        if(side == "Left"):
            cv2.namedWindow(side, cv2.WINDOW_NORMAL)
            cv2.moveWindow(side, 0, 0)
            cv2.imshow(side, img)
            cv2.resizeWindow(side, monitorWidth, 1080)
            cv2.setWindowProperty(side, cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)

        elif(side == "Right"):
            cv2.namedWindow(side, cv2.WINDOW_NORMAL)
            cv2.moveWindow(side, monitorWidth, 0)
            cv2.imshow(side, img)
            cv2.resizeWindow(side, monitorWidth, 1080)
            cv2.setWindowProperty(side, cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)

    def save(self):
        cv2.imwrite("./img/processed/" + self.__displayImg.getSide() + "_img.png", self.__displayImg.getImg())

def main():
    config = Config.readConfigFile()

    imgProcessor = ImgProcessor(config)

    l_img, r_img = imgProcessor.cropImage()
    l_alpha_processed, r_alpha_processed = imgProcessor.alphaBlend(l_img, r_img)

    l_alpha_gamma_processed = imgProcessor.GammaCorrection(l_alpha_processed)
    r_alpha_gamma_processed = imgProcessor.GammaCorrection(r_alpha_processed)

    l_displayImg = DisplayImg(l_alpha_gamma_processed.shape[1] ,l_alpha_gamma_processed.shape[0], config.getOverlapWidth(), l_alpha_gamma_processed, "Left")
    r_displayImg = DisplayImg(r_alpha_gamma_processed.shape[1] ,r_alpha_gamma_processed.shape[0], config.getOverlapWidth(), r_alpha_gamma_processed, "Right")

    l_stitcher = MainStitcher(l_displayImg)
    r_stitcher = MainStitcher(r_displayImg)

    print(config.getIsDualMonitor())

    if config.getIsDualMonitor():
        l_stitcher.doubleDisplay(config.getMonitorWidth())
        r_stitcher.doubleDisplay(config.getMonitorWidth())
    else:
        if config.getSide().lower() == "right":
            r_stitcher.singleDisplay()
        else:
            l_stitcher.singleDisplay()

    cv2.waitKey(0)
    cv2.destroyAllWindows()

    l_stitcher.save()
    r_stitcher.save()

if __name__ == "__main__":
    main()

config.py: Configuration Class

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from distutils.util import strtobool

class Config(object):
    def __init__(self, pnd, prd, w, h, p, gamma, overlapWidth, side, isDual, monitorWidth):
        """!
        Constructor for Config class.

        @param pnd: Projection distance.
        @param prd: Projector distance.
        @param w: Image width.
        @param h: Image height.
        @param p: Path to the image.
        @param gamma: Gamma value for adjustments.
        @param overlapWidth: Width of the overlap area.
        @param side: Side of projection.
        """ 
        self.__projection_distance = pnd
        self.__projector_diatance = prd
        self.__img_width = w
        self.__img_height = h
        self.__img_path = p
        self.__gamma = gamma
        self.__overlapWidth = overlapWidth
        self.__side = side
        self.__isDualMonitor = isDual
        self.__monitorWidth = monitorWidth

    def getProjectionDistance(self):
        """!
        Retrieve the projection distance.

        @return: Projection distance as an integer.
        """ 
        return int(self.__projection_distance)

    def getProjectorDistance(self):
        """!
        Retrieve the projector distance.

        @return: Projector distance as an integer.
        """ 
        return int(self.__projector_diatance)

    def getImgWidth(self):
        """!
        Retrieve the image width.

        @return: Image width as an integer.
        """ 
        return int(self.__img_width)

    def getImgHeight(self):
        """!
        Retrieve the image height.

        @return: Image height as an integer.
        """ 
        return int(self.__img_height)

    def getImgPath(self):
        """!
        Retrieve the image path.

        @return: Image path as a string.
        """ 
        return str(self.__img_path)

    def getGamma(self):
        """!
        Retrieve the gamma value.

        @return: Gamma value as a float.
        """ 
        return float(self.__gamma)

    def getOverlapWidth(self):
        """!
        Retrieve the overlap width.

        @return: Overlap width as an integer.
        """ 
        return int(self.__overlapWidth)

    def getSide(self):
        """!
        Retrieve the side of projection.

        @return: Side as a string.
        """ 
        return str(self.__side)

    def getIsDualMonitor(self):
        return bool(strtobool(self.__isDualMonitor))

    def getMonitorWidth(self):
        return int(self.__monitorWidth)

    @staticmethod
    def readConfigFile():
        """!
        Reads the configuration from a config.ini file and returns a Config object.

        @return: Config object with settings loaded from config.ini.
        """ 
        import configparser
        config = configparser.ConfigParser()
        config.read('config.ini')

        __img_path = config["settings"]["imagePath"]
        __img_width = config["settings"]["imageWidth"]
        __img_height = config["settings"]["imageHeight"]
        __projection_distance = config["settings"]["projectionDistance"]
        __projector_diatance = config["settings"]["projectorDistance"]
        __gamma = config["settings"]["gamma"]
        __overlapWidth = config["settings"]["overlapWidth"]
        __side = config["settings"]["side"]
        __isDualMonitor = config["settings"]["isDualMonitor"]
        __monitorWidth = config["settings"]["monitorWidth"]

        return Config(__projection_distance, __projector_diatance, __img_width, __img_height, __img_path, __gamma, __overlapWidth, __side, __isDualMonitor, __monitorWidth)

config.py: Configuration Class

Updated by Mitsuki EIKI 4 months ago · 30 revisions