Aug-28-2017, 07:28 AM
hi everybody,
i wanna pass the full directory of images to the scripts below to execute the lbp algorithm and get the all lbp images with the same name of the original image but saving into another folder. Right now i'm only be able to process one image and also the output doesn't have the same as the original image name, only can write with the "output.tif" name(i tried to use method .name to get the image file name to write the output by doesn't work).
Please see the attached code below, thanks.
Main.py
i wanna pass the full directory of images to the scripts below to execute the lbp algorithm and get the all lbp images with the same name of the original image but saving into another folder. Right now i'm only be able to process one image and also the output doesn't have the same as the original image name, only can write with the "output.tif" name(i tried to use method .name to get the image file name to write the output by doesn't work).
Please see the attached code below, thanks.
Main.py
import os.path import argparse from algorithms import * def main(): # Argument parsing parser = argparse.ArgumentParser(description='Run the local binary patterns algorithm using either a single process or multiple processes.') parser.add_argument('--input', dest='input', type=str, default='input.png', help='file name of the input image') parser.add_argument('--algorithm', dest='algorithm', type=str, default='lbp', help='algorithm to use: "lbp", "multi-lbp" or "multi-split-lbp"') parser.add_argument('--processes', dest='processes', type=int, default=1, help='number of processes to use (only relevant for multiprocessing)') parser.add_argument('--output', dest='output', action='store_true', default=False, help='whether or not an output image should be produced') arguments = parser.parse_args() algorithms = { "lbp": LBP.LBP, "multi-lbp": Multiprocessing_LBP.Multiprocessing_LBP, "multi-lbp-mpi": Multiprocessing_LBP_MPI.Multiprocessing_LBP_MPI, "multi-split-lbp": Multiprocessing_Split_LBP.Multiprocessing_Split_LBP } if arguments.algorithm not in algorithms: print("Invalid algorithm '{}'".format(arguments.algorithm)) return algorithm_class = algorithms[arguments.algorithm] if os.path.isfile(arguments.input): run = algorithm_class(arguments.input, arguments.processes, arguments.output) run.execute() else: print("File '{}' does not exist.".format(arguments.input)) if __name__ == "__main__": main()LBP.py
import numpy as np from PIL import Image from os.path import basename class LBP: def __init__(self, input, num_processes, output): # Convert the image to grayscale self.image = Image.open(input).convert("L") self.width = self.image.size[0] self.height = self.image.size[1] self.patterns = [] self.num_processes = num_processes self.output = output def execute(self): self._process() if self.output: self._output() def _process(self): pixels = list(self.image.getdata()) pixels = [pixels[i * self.width:(i + 1) * self.width] for i in xrange(self.height)] # Calculate LBP for each non-edge pixel for i in xrange(1, self.height - 1): # Cache only the rows we need (within the neighborhood) previous_row = pixels[i - 1] current_row = pixels[i] next_row = pixels[i + 1] for j in xrange(1, self.width - 1): # Compare this pixel to its neighbors, starting at the top-left pixel and moving # clockwise, and use bit operations to efficiently update the feature vector pixel = current_row[j] pattern = 0 pattern = pattern | (1 << 0) if pixel < previous_row[j-1] else pattern pattern = pattern | (1 << 1) if pixel < previous_row[j] else pattern pattern = pattern | (1 << 2) if pixel < previous_row[j+1] else pattern pattern = pattern | (1 << 3) if pixel < current_row[j+1] else pattern pattern = pattern | (1 << 4) if pixel < next_row[j+1] else pattern pattern = pattern | (1 << 5) if pixel < next_row[j] else pattern pattern = pattern | (1 << 6) if pixel < next_row[j-1] else pattern pattern = pattern | (1 << 7) if pixel < current_row[j-1] else pattern self.patterns.append(pattern) def _output(self): # Write the result to an image file result_image = Image.new(self.image.mode, (self.width - 2, self.height - 2)) result_image.putdata(self.patterns) result_image.save('output.tif')Multiprocessing_LBP.py
import numpy as np from PIL import Image from multiprocessing import Process, Queue from LBP import LBP class Multiprocessing_LBP(LBP): def __init__(self, input, num_processes, output): LBP.__init__(self, input, num_processes, output) def execute(self): self._distribute() if self.output: self._output() def _process(self, process_id, pixels, queue): # Set the left and right bounds of the segment to process segment_height = int(np.floor(self.height / self.num_processes)) left_bound = (process_id * segment_height) if process_id != 0 else 1 right_bound = (process_id * segment_height) + segment_height if process_id == (self.num_processes - 1): # The last process should also process any remaining rows right_bound = self.height - 1 # Calculate LBP for each non-edge pixel in the segment patterns = [] for i in xrange(left_bound, right_bound): # Cache only the rows we need (within the neighborhood) previous_row = pixels[i - 1] current_row = pixels[i] next_row = pixels[i + 1] for j in xrange(1, self.width - 1): # Compare this pixel to its neighbors, starting at the top-left pixel and moving # clockwise, and use bit operations to efficiently update the feature vector pixel = current_row[j] pattern = 0 pattern = pattern | (1 << 0) if pixel < previous_row[j-1] else pattern pattern = pattern | (1 << 1) if pixel < previous_row[j] else pattern pattern = pattern | (1 << 2) if pixel < previous_row[j+1] else pattern pattern = pattern | (1 << 3) if pixel < current_row[j+1] else pattern pattern = pattern | (1 << 4) if pixel < next_row[j+1] else pattern pattern = pattern | (1 << 5) if pixel < next_row[j] else pattern pattern = pattern | (1 << 6) if pixel < next_row[j-1] else pattern pattern = pattern | (1 << 7) if pixel < current_row[j-1] else pattern patterns.append(pattern) queue.put({ 'process_id': process_id, 'patterns': patterns }) def _distribute(self): pixels = np.array(self.image) # Spawn the processes processes = [] queue = Queue() for process_id in xrange(self.num_processes): process = Process(target=self._process, args=(process_id, pixels, queue)) process.start() processes.append(process) # Wait for all processes to finish results = [queue.get() for process in processes] [process.join() for process in processes] # Format the pixels correctly for the output function, # which expects a linear list of pixel values. results = sorted(results, key=lambda k: k['process_id']) for result in results: self.patterns.extend(result['patterns'])Multiprocessing_LBP_MPI.py
import time import numpy as np from PIL import Image from LBP import LBP from mpi4py import MPI class Multiprocessing_LBP_MPI(LBP): def __init__(self, input, num_processes, output): LBP.__init__(self, input, num_processes, output) self.communicator = MPI.COMM_WORLD self.process_id = self.communicator.rank self.num_processes = self.communicator.size def execute(self): if self.process_id == 0: self._run_master() if self.output: self._output() else: pixels = np.array(self.image) self._run_slave(pixels) def _run_master(self): num_processes = self.num_processes - 1 results = [0] * num_processes status = MPI.Status() # Collect results of the slave processes while 0 in results: if self.communicator.Iprobe(source=MPI.ANY_SOURCE, tag=MPI.ANY_TAG, status=status): process_id = status.Get_source() results[process_id - 1] = self.communicator.recv(source=process_id, tag=MPI.ANY_TAG) # Format the pixels correctly for the output function, # which expects a linear list of pixel values. for result in results: self.patterns.extend(result) def _run_slave(self, pixels): # Exclude the master process from the LBP work num_processes = self.num_processes - 1 process_id = self.process_id - 1 # Set the left and right bounds of the segment to process segment_height = int(np.floor(self.height / num_processes)) left_bound = (process_id * segment_height) if process_id != 0 else 1 right_bound = (process_id * segment_height) + segment_height if process_id == num_processes - 1: # The last process should also process any remaining rows right_bound = self.height - 1 # Calculate LBP for each non-edge pixel in the segment patterns = [] for i in xrange(left_bound, right_bound): # Cache only the rows we need (within the neighborhood) previous_row = pixels[i - 1] current_row = pixels[i] next_row = pixels[i + 1] for j in xrange(1, self.width - 1): # Compare this pixel to its neighbors, starting at the top-left pixel and moving # clockwise, and use bit operations to efficiently update the feature vector pixel = current_row[j] pattern = 0 pattern = pattern | (1 << 0) if pixel < previous_row[j-1] else pattern pattern = pattern | (1 << 1) if pixel < previous_row[j] else pattern pattern = pattern | (1 << 2) if pixel < previous_row[j+1] else pattern pattern = pattern | (1 << 3) if pixel < current_row[j+1] else pattern pattern = pattern | (1 << 4) if pixel < next_row[j+1] else pattern pattern = pattern | (1 << 5) if pixel < next_row[j] else pattern pattern = pattern | (1 << 6) if pixel < next_row[j-1] else pattern pattern = pattern | (1 << 7) if pixel < current_row[j-1] else pattern patterns.append(pattern) # Send the results to the master process and stop this slave process self.communicator.send(patterns, dest=0, tag=0)Multiprocessing_Split_LBP.py
import numpy as np from PIL import Image from multiprocessing import Process, Queue from Multiprocessing_LBP import Multiprocessing_LBP class Multiprocessing_Split_LBP(Multiprocessing_LBP): def __init__(self, input, num_processes, output): Multiprocessing_LBP.__init__(self, input, num_processes, output) def _process(self, process_id, pixels, queue): # Determine the bounds for processing left_bound = 0 if process_id == 0: left_bound = 1 right_bound = pixels.shape[0] - 1 if process_id == (self.num_processes - 1): right_bound -= 1 # Calculate LBP for each non-edge pixel in the segment patterns = [] for i in xrange(left_bound, right_bound): # Cache only the rows we need (within the neighborhood) previous_row = pixels[i - 1] current_row = pixels[i] next_row = pixels[i + 1] for j in xrange(1, self.width - 1): # Compare this pixel to its neighbors, starting at the top-left pixel and moving # clockwise, and use bit operations to efficiently update the feature vector pixel = current_row[j] pattern = 0 pattern = pattern | (1 << 0) if pixel < previous_row[j-1] else pattern pattern = pattern | (1 << 1) if pixel < previous_row[j] else pattern pattern = pattern | (1 << 2) if pixel < previous_row[j+1] else pattern pattern = pattern | (1 << 3) if pixel < current_row[j+1] else pattern pattern = pattern | (1 << 4) if pixel < next_row[j+1] else pattern pattern = pattern | (1 << 5) if pixel < next_row[j] else pattern pattern = pattern | (1 << 6) if pixel < next_row[j-1] else pattern pattern = pattern | (1 << 7) if pixel < current_row[j-1] else pattern patterns.append(pattern) queue.put({ 'process_id': process_id, 'patterns': patterns }) def _distribute(self): pixels = np.array(self.image) segment_height = int(np.floor(self.height / self.num_processes)) processes = [] queue = Queue() for process_id in xrange(self.num_processes): # Pass only the part of the image that the process needs to work with. # This is done in order to make the processes work independently. # Because of the neighborhood, each segment should partially overlap # with the next and/or previous segment. left_bound = process_id * segment_height right_bound = left_bound + segment_height if process_id > 0: left_bound -= 1 if process_id == (self.num_processes - 1): # The last process should also process any remaining rows right_bound = self.height # Start the process and pass only the pixels within the bounds segment_pixels = pixels[left_bound:right_bound] process = Process(target=self._process, args=(process_id, segment_pixels, queue)) process.start() processes.append(process) # Wait for all processes to finish results = [queue.get() for process in processes] [process.join() for process in processes] # Format the pixels correctly for the output function, # which expects a linear list of pixel values. results = sorted(results, key=lambda k: k['process_id']) for result in results: self.patterns.extend(result['patterns'])Thanks for the help. im really noob in python