Пример #1
0
 def __init__(self):
     """
         Change the tensor as the gray scale
         The function will turn the BCHW tensor into B1HW gray-scaled tensor
     """
     INFO("Applied << %15s >>" % self.__class__.__name__)
     INFO("* Notice: the rank format of input tensor should be 'BCHW'")
Пример #2
0
 def print(self):
     """
         Print the information for each image domain
     """
     INFO()
     for domain in range(len(self.root)):
         INFO("domain index: %d \timage number: %d" %
              (domain, len(self.files[domain])))
     INFO()
Пример #3
0
    def __init__(self, direction=BHW2BHWC):
        """
            Stack the gray-scale image for 3 times to become RGB image
            If the input is already RGB image, this function do nothing

            Arg:    direction   - The stack direction you want to conduct
        """
        INFO("Applied << %15s >>" % self.__class__.__name__)
        INFO("* Notice: the rank format of input tensor should be 'BHWC'")
        self.direction = direction
Пример #4
0
    def __init__(self, output_size):
        """
            Resize the tensor to the desired size
            This function only support for nearest-neighbor interpolation
            Since this mechanism can also deal with categorical data

            Arg:    output_size - The tuple (H, W)
        """
        self.output_size = output_size
        INFO("Applied << %15s >>" % self.__class__.__name__)
        INFO("* Notice: the rank format of input tensor should be 'BHWC'")
Пример #5
0
    def __init__(self, p=0.5):
        """
            Flip the tensor toward horizontal direction randomly

            Arg:    p   - The random probability to filp the tensor
        """
        INFO("Applied << %15s >>" % self.__class__.__name__)
        INFO("* Notice: the rank format of input tensor should be 'BCHW'")
        if p < 0.0 or p > 1.0:
            raise Exception(
                "The parameter 'p' should in (0, 1], but get {}".format(p))
        self.p = p
Пример #6
0
 def print(self):
     """
         Print the information for each image domain
     """
     INFO()
     for domain in range(len(self.root)):
         total_frame = 0
         for video in self.files[domain]:
             total_frame += len(video)
         INFO("domain index: %d \tvideo number: %d\tframe total: %d" %
              (domain, len(self.root[domain]), total_frame))
     INFO()
Пример #7
0
    def __init__(self, direction = BHWC2BCHW):
        """
            Transfer the rank of tensor into target one

            Arg:    direction   - The direction you want to do the transpose
        """        
        self.direction = direction
        if self.direction == BHWC2BCHW:
            INFO("Applied << %15s >>, The rank format is BCHW" % self.__class__.__name__)
        elif self.direction == BCHW2BHWC:
            INFO("Applied << %15s >>, The rank format is BHWC" % self.__class__.__name__)
        else:
            raise Exception("Unknown direction symbol: {}".format(self.direction))
Пример #8
0
    def __init__(self, mean = [0.485, 0.456, 0.406], std = [0.229, 0.224, 0.225]):
        """
            Unnormalize the tensor with given mean and standard deviation
            * Notice: If you didn't give mean and std, the function will assume that the original distribution locates in [-1, 1]

            Args:
                mean    - The mean of the result tensor
                std     - The standard deviation
        """
        self.mean = mean
        self.std = std
        INFO("Applied << %15s >>" % self.__class__.__name__)
        INFO("* Notice: the rank format of input tensor should be 'BCHW'")
        if self.mean == [0.485, 0.456, 0.406] and self.std == [0.229, 0.224, 0.225]:
            INFO("* Notice: The function assume that the normalize method is the same as VGG preprocessing")
Пример #9
0
    def __init__(self, mean = [127.5, 127.5, 127.5], std = [127.5, 127.5, 127.5]):
        """
            Unnormalize the tensor with given mean and standard deviation
            * Notice: If you didn't give mean and std, the function will assume that the original distribution locates in [-1, 1]

            Args:
                mean    - The mean of the result tensor
                std     - The standard deviation
        """
        self.mean = mean
        self.std = std
        INFO("Applied << %15s >>" % self.__class__.__name__)
        INFO("* Notice: the rank format of input tensor should be 'BCHW'")
        if self.mean == [127.5, 127.5, 127.5] and self.std == [127.5, 127.5, 127.5]:
            INFO("* Notice: The function assume that the input range is [-1, 1]")
Пример #10
0
def getCategoricalMapping(loader=None,
                          path='torchvision_sunner_categories_pallete.json'):
    """
        This function can statistic the different category with color
        And return the list of the mapping OrderedDict object

        Arg:    loader  - The ImageLoader object
                path    - The path of pallete file
        Ret:    The list of OrderDict object (palletes object)
    """
    INFO("Applied << %15s >>" % getCategoricalMapping.__name__)
    INFO("* Notice: the rank format of input tensor should be 'BHWC'")
    INFO("* Notice: The range of tensor should be in [0, 255]")
    if os.path.exists(path):
        palletes = load_pallete(path)
    else:
        INFO(">> Load from scratch, please wait...")

        # Get the number of folder
        folder_num = 0
        for img_list in loader:
            folder_num = len(img_list)
            break

        # Initialize the pallete list
        palletes = [OrderedDict()] * folder_num
        color_sets = [set()] * folder_num

        # Work
        for img_list in tqdm(loader):
            for folder_idx in range(folder_num):
                img = img_list[folder_idx]
                if torch.max(img) > 255 or torch.min(img) < 0:
                    raise Exception(
                        'tensor value out of range...\t range is [' +
                        str(torch.min(img)) + ' ~ ' + str(torch.max(img)))
                img = img.cpu().data.numpy().astype(np.uint8)
                img = np.reshape(img, [-1, 3])
                color_sets[folder_idx] |= set([tuple(_) for _ in img])

        # Merge the color
        for i in range(folder_num):
            for color in color_sets[i]:
                if color not in palletes[i].keys():
                    palletes[i][color] = len(palletes[i])
        save_pallete(palletes, path)

    return palletes
Пример #11
0
    def getFiles(self):
        """
            Construct the files object for the assigned root
            We accept the user to mix folder with image
            This function can extract whole image in the folder
            
            However, unlike the setting in ImageDataset, we store the video result in root obj.
            Also, the 'images' name will be store in files obj

            The following list the progress of this function:
                1. check if we need to decode again
                2. decode if needed
                3. form the files obj
        """
        if not self.files:
            # Check if the decode process should be conducted again
            should_decode = not os.path.exists(self.decode_root)
            if not should_decode:
                for domain_idx, domain in enumerate(self.root):
                    for video in domain:
                        if not os.path.exists(
                                os.path.join(self.decode_root, str(domain_idx),
                                             self.to_folder(video))):
                            should_decode = True
                            break

            # Decode the video if needed
            if should_decode:
                INFO("Decode from scratch...")
                if os.path.exists(self.decode_root):
                    subprocess.call(['rm', '-rf', self.decode_root])
                os.mkdir(self.decode_root)
                self.decodeVideo()
            else:
                INFO("Skip the decode process!")

            # Form the files object
            self.files = {}
            for domain_idx, domain in enumerate(os.listdir(self.decode_root)):
                self.files[domain_idx] = []
                for video in os.listdir(os.path.join(self.decode_root,
                                                     domain)):
                    self.files[domain_idx] += [
                        sorted(
                            glob(
                                os.path.join(self.decode_root, domain, video,
                                             "*")))
                    ]
Пример #12
0
    def save(self, remain_file_name, split_ratio, split_file_name = ".split.pkl", save_type = 'image'):
        """
            Save the information into record file

            Arg:    remain_file_name    - The path of record file which store the information of remain data
                    split_ratio         - Float. The proportion to split the data. Usually used to split the testing data
                    split_file_name     - The path of record file which store the information of split data
                    save_type           - Str. The type of the record file you want to save
        """
        if self.save_file:
            if not os.path.exists(remain_file_name):
                with open(remain_file_name, 'wb') as f:
                    pickle.dump({
                        'type': save_type,
                        'root': self.root,
                        'files': self.files
                    }, f)
            if split_ratio:
                INFO("Split the dataset, and save as {}".format(split_file_name))
                with open(split_file_name, 'wb') as f:
                    pickle.dump({
                        'type': save_type,
                        'root': self.root,
                        'files': self.split_files
                    }, f) 
Пример #13
0
 def __init__(self, pallete=None, direction=COLOR2INDEX, index_default=0):
     """
         Transform the tensor into the particular format
         We support for 3 different kinds of format:
             1. one hot image
             2. index image
             3. color
         
         Arg:    pallete         - The pallete object (default is None)
                 direction       - The direction you want to change
                 index_default   - The default index if the color cannot be found in the pallete
     """
     self.pallete = pallete
     self.direction = direction
     self.index_default = index_default
     INFO("Applied << %15s >> , direction: %s" %
          (self.__class__.__name__, self.direction))
     INFO("* Notice: The range of tensor should be in [-1, 1]")
     INFO("* Notice: the rank format of input tensor should be 'BCHW'")
Пример #14
0
    def __init__(self):
        """
            Change the tensor into torch.Tensor type
            However, if the input is PIL image, then the original ToTensor will be used

            For the range of output tensor:
                1. [0~255] => [0~1] if the image is PIL object
                2. otherwise the value range doesn't change
        """
        INFO("Applied << %15s >>" % self.__class__.__name__)
        self.official_op_obj = transforms.ToTensor()
Пример #15
0
    def __init__(self,
                 root=None,
                 file_name='.remain.pkl',
                 sample_method=UNDER_SAMPLING,
                 transforms=None,
                 split_ratio=0.0,
                 save_file=False):
        """
            The constructor of ImageDataset

            Arg:    root            - The list object. The image set
                    file_name       - The str. The name of record file. 
                    sample_method   - sunnerData.UNDER_SAMPLING or sunnerData.OVER_SAMPLING. Use down sampling or over sampling to deal with data unbalance problem.
                                      (default is sunnerData.OVER_SAMPLING)
                    transform       - transform.Compose object. You can declare some pre-process toward the image
                    split_ratio     - Float. The proportion to split the data. Usually used to split the testing data
                    save_file       - Bool. If storing the record file or not. Default is False
        """
        super().__init__()
        # Record the parameter
        self.root = root
        self.file_name = file_name
        self.sample_method = sample_method
        self.transforms = transforms
        self.split_ratio = split_ratio
        self.save_file = save_file
        self.img_num = -1
        INFO()

        # Substitude the contain of record file if the record file is exist
        if os.path.exists(file_name) and self.loadFromFile(file_name):
            self.getImgNum()
        elif not os.path.exists(file_name) and root is None:
            raise Exception(
                "Record file {} not found. You should assign 'root' parameter!"
                .format(file_name))
        else:
            # Extend the images of folder into domain list
            self.getFiles()

            # Change root obj as the index format
            self.root = range(len(self.root))

            # Adjust the image number
            self.getImgNum()

            # Split the files if split_ratio is more than 0.0
            self.split()

            # Save the split information
            self.save()

        # Print the domain information
        self.print()
Пример #16
0
    def loadFromFile(self, file_name, check_type = 'image'):
        """
            Load the root and files information from .pkl record file
            This function will return False if the record file format is invalid

            Arg:    file_name   - The name of record file
                    check_type  - Str. The type of the record file you want to check
            Ret:    If the loading procedure are successful or not
        """
        with open(file_name, 'rb') as f:
            obj = pickle.load(f)
            self.type  = obj['type']
            if self.type == check_type:
                INFO("Load from file: {}".format(file_name))
                self.root  = obj['root']
                self.files = obj['files']
                return True
            else:
                INFO("Record file type: {}\tFail to load...".format(self.type))
                INFO("Form the contain from scratch...")
                return False
Пример #17
0
    def __init__(self, mean = [127.5, 127.5, 127.5], std = [127.5, 127.5, 127.5]):
        """
            Normalize the tensor with given mean and standard deviation
            * Notice: If you didn't give mean and std, the result will locate in [-1, 1]

            Args:
                mean        - The mean of the result tensor
                std         - The standard deviation
        """
        self.mean = mean
        self.std  = std
        INFO("Applied << %15s >>" % self.__class__.__name__)
        INFO("* Notice: the rank format of input tensor should be 'BCHW'")
        INFO("*****************************************************************")
        INFO("* Notice: You should must call 'ToFloat' before normalization")
        INFO("*****************************************************************")
        if self.mean == [127.5, 127.5, 127.5] and self.std == [127.5, 127.5, 127.5]:
            INFO("* Notice: The result will locate in [-1, 1]")
Пример #18
0
    def __init__(self, mean = [0.485, 0.456, 0.406], std = [0.229, 0.224, 0.225]):
        """
            Normalize the tensor with given mean and standard deviation
            We recommand you to set mean as [0.5, 0.5, 0.5], and std as [0.5, 0.5, 0.5]
            Then the range will locate in [-1, 1]
            * Notice: If you didn't give mean and std, then we will follow the preprocessing of VGG
                      However, The range is NOT located in [-1, 1]

            Args:
                mean        - The mean of the result tensor
                std         - The standard deviation
        """
        self.mean = mean
        self.std  = std
        INFO("Applied << %15s >>" % self.__class__.__name__)
        INFO("* Notice: the rank format of input tensor should be 'BCHW'")
        INFO("*****************************************************************")
        INFO("* Notice: You should must call 'ToFloat' before normalization")
        INFO("*****************************************************************")
        if self.mean == [0.485, 0.456, 0.406] and self.std == [0.229, 0.224, 0.225]:
            INFO("* Notice: The result will NOT locate in [-1, 1]")
Пример #19
0
 def __init__(self):
     """
         Change the tensor into torch.FloatTensor
     """
     INFO("Applied << %15s >>" % self.__class__.__name__)
Пример #20
0
    def __init__(self,
                 root=None,
                 file_name='.remain.pkl',
                 T=10,
                 sample_method=UNDER_SAMPLING,
                 transforms=None,
                 split_ratio=0.0,
                 decode_root='./.decode',
                 save_file=False):
        """
            The constructor of VideoDataset

            Arg:    root            - The list object. The image set
                    file_name       - Str. The name of record file.
                    T               - Int. The maximun length of small video sequence
                    sample_method   - sunnerData.UNDER_SAMPLING or sunnerData.OVER_SAMPLING. Use down sampling or over sampling to deal with data unbalance problem.
                                      (default is sunnerData.OVER_SAMPLING)
                    transform       - transform.Compose object. You can declare some pre-process toward the image
                    split_ratio     - Float. The proportion to split the data. Usually used to split the testing data
                    decode_root     - Str. The path to store the ffmpeg decode result. 
                    save_file       - Bool. If storing the record file or not. Default is False
        """
        super().__init__()

        # Record the parameter
        self.root = root
        self.file_name = file_name
        self.T = T
        self.sample_method = sample_method
        self.transforms = transforms
        self.split_ratio = split_ratio
        self.decode_root = decode_root
        self.video_num = -1
        self.split_root = None
        INFO()

        # Substitude the contain of record file if the record file is exist
        if not os.path.exists(file_name) and root is None:
            raise Exception(
                "Record file {} not found. You should assign 'root' parameter!"
                .format(file_name))
        elif os.path.exists(file_name):
            INFO("Load from file: {}".format(file_name))
            self.loadFromFile(file_name)

        # Extend the images of folder into domain list
        self.extendFolder()

        # Split the image
        self.split()

        # Form the files obj
        self.getFiles()

        # Adjust the image number
        self.getVideoNum()

        # Save the split information
        self.save()

        # Print the domain information
        self.print()