Python Forum
Execute script through full directory and change output name result
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Execute script through full directory and change output name result
#1
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

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
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  How to change working directory in Jupyter Notebook? rajeev1729 2 21,090 Aug-25-2019, 07:25 PM
Last Post: perfringo
  Python not saving output file from script shaanali 1 2,712 Jun-13-2018, 07:39 PM
Last Post: shaanali

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020