1
\$\begingroup\$

Follow up question Image processing using Python OOP library

I want to use multiprocessing to analyze several images in parallel:

class SegmentationType(object):
    DISPLAY_NAME = "invalid"

    def __init__(self, filename, path):
        self.filename = filename
        self.path = path
        self.input_data = None
        self.output_data = None


    def read_image(self):
        self.input_data =  cv2.imread(self.path + self.filename)[1]

    def write_image(self):
        cv2.imwrite(self.path + self.filename.split('.')[0] + '_' + self.DISPLAY_NAME + '.png', self.output_data)

    def process(self):
        # override in derived classes to perform an actual segmentation
        pass

    def start_pipeline(self):
        self.read_image()
        self.process()
        self.write_image()

class HSV_Segmenter(SegmentationType):
    DISPLAY_NAME = 'HSV'

    def process(self):
        source = rgb_to_hsv(self.input_data)
        self.output_data = treshold_otsu(source)


class LabSegmenter(SegmentationType):
    DISPLAY_NAME = 'LAB'

    def process(self):
        source = rgb_to_lab(self.input_data)
        self.output_data = global_threshold(source)


segmenter_class = {
'hsv': HSV_Segmentation,
'lab': LAB_Segmenter
}.get(procedure)

if not segmenter_class:
    raise ArgumentError("Invalid segmentation method '{}'".format(procedure))

for img in images:
    os.chdir(img_dir)
    processor =  = segmenter_class(img, img_dir, procedure)
    processor.start_pipeline()

What I tried so far:

image_lst = os.listdir(my_image_path)

# We split the list into sublist with 5 elements because of 512 GB RAM limitation
if len(image_lst) > 4:
    nr_of_sublists = (int(len(image_lst)/2.5))
    image_sub_lst  =(np.array_split(image_lst, nr_of_sublists))
else:
    image_sub_lst = [image_lst]

# We do the analysis for each sublist
for sub_lst in image_sub_lst:
    print (sub_lst)
    pool = multiprocessing.Pool(8)
    
    # Call the processor 
    processor =  = segmenter_class(img, img_dir, procedure)
    processor.start_pipeline()
    # How to call map???
    pool.map(?, sub_lst)
    pool.terminate()
    
\$\endgroup\$
  • 1
    \$\begingroup\$ Hello, I saw you used opencv tag and image processing in your previous post's title, these could be useful in this post too to increment odds of receiving detailed answers. \$\endgroup\$ – dariosicily Jul 3 at 7:51
  • 1
    \$\begingroup\$ What I tried so far - to be clear: from what you've tried so far, is the output correct? \$\endgroup\$ – Reinderien Jul 5 at 18:33
  • 1
    \$\begingroup\$ Also, is this Python 2 or 3? \$\endgroup\$ – Reinderien Jul 5 at 18:44
  • \$\begingroup\$ Hi snowflake. Unfortunately your question is currently off-topic. Questions must include a description of what the code does. Once you have fixed the issues with your post we'll be happy to review your code. \$\endgroup\$ – Peilonrayz Jul 10 at 19:35
2
\$\begingroup\$

A warning on version

Many of the following suggestions assume that you are using Python 3.

Bare inheritance

class SegmentationType(object):

can be

class SegmentationType:

Abstract statics

DISPLAY_NAME = "invalid"

should not really assign a value. Instead,

DISPLAY_NAME: str

Unpacking imread

The documentation is deeply unhelpful: it says that imread returns "retval". Given your usage it's obvious that reality is more complicated, because you're indexing into it. Try to unpack instead:

_, self.input_data = cv2.imread(self.path + self.filename)

Abstract methods

process should raise NotImplementedError in the base.

Factory

You have a factory dictionary that should be turned into a method, something like

def get_segmenter(name: str) -> Type[SegmentationType]:
    return {
        t.DISPLAY_NAME: t
        for t in (HSVSegmenter, LABSegmenter)
    }[name]

Outer parentheses

Neither of these:

nr_of_sublists = (int(len(image_lst)/2.5))
image_sub_lst  =(np.array_split(image_lst, nr_of_sublists))

needs outer parentheses.

Syntax

Surely this is a typo? This will not run:

processor =  = segmenter_class(img, img_dir, procedure)

nor will this:

pool.map(?, sub_lst)
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Thank you very much for your suggestions and improvements. For the last two lines, I don't know how to call the segmenter_class in a multiprocessing way. \$\endgroup\$ – snowflake Jul 6 at 6:30
  • \$\begingroup\$ That part of the question is off-topic. CodeReview only covers code that is complete and working. \$\endgroup\$ – Reinderien Jul 6 at 12:51
  • \$\begingroup\$ Ok I will ask at SO \$\endgroup\$ – snowflake Jul 8 at 8:24

Not the answer you're looking for? Browse other questions tagged or ask your own question.