Как мне выполнять функции в определенном порядке, когда они определены в классе?

#python #function #numpy #class

#python #функция #numpy #класс

Вопрос:

Я пытаюсь создать функцию (определенную внутри класса), которая вызывает другие функции (также определенные в классе) в определенном порядке.

Чтобы быть точным, я создал класс преобразований изображений (с использованием imgaug ), где все параметры увеличения изображения передаются в качестве аргументов в конструкторе (см. Код ниже). Затем я определил пару функций, которые принимают необработанное изображение в качестве входных данных и применяют к нему преобразования.

Что я хотел бы сделать, так это иметь возможность применять эти функции преобразования в определенном порядке. Я думаю, что я близок, но я продолжаю получать одни и те же ошибки. Я использую классы, потому что я хотел бы указать параметры только один раз, а затем использовать список или кортеж, чтобы указать порядок функций, и в конечном итоге иметь возможность сделать порядок случайным.

РЕДАКТИРОВАТЬ: чтобы добавить контекст к моему вопросу — конечной целью здесь является создание функции, которая будет случайным образом увеличивать данные изображения, используя различные методы увеличения, применяемые в случайном порядке, используя случайные параметры (из указанного диапазона).

Вот мой код:

 import numpy as np
import imgaug as ia
from imgaug import augmenters as iaa

image = my_image_to_transform

class random_augmentation:
    
    def __init__(self,rotate_range=None,e_sev=None,):
        
        if rotate_range is None:
            self.rotate_range = None
        elif (type(rotate_range) is tuple) or (type(rotate_range) is list) and len(rotate_range) == 2:
            self.rotate_range = rotate_range
        else:
            self.rotate_range = None 
            
            
        if e_sev is None:
            self.e_sev = None
        else:
            self.e_sev = e_sev
        
        
    def aug_rotate(self,img):
        if self.rotate_range is not None:
            rotate = iaa.Affine(rotate=self.rotate_range)
            rotated_img = rotate(image=img)
            return rotated_img
        else:
            pass
    

    def aug_elastic(self,img):
        if self.e_sev is not None:
            elastic = iaa.imgcorruptlike.ElasticTransform(severity=self.e_sev)
            elastic_img = elastic(image=img)
            return elastic_img
        else:
            pass
        
    f_list = [aug_rotate,aug_elastic]
    
    def random_augment(img,order):
        for i in order:
            function = f_list[i]
            outp = function(img)
            img = outp
        return outp

r_aug = random_augmentation(rotate_range=(-30,30),e_sev=3)

augmented_img = r_aug.random_augment(image,[0,1])
  

Ошибка, которую я получаю, заключается в следующем:

 ---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-49-2a880e8381b8> in <module>
----> 1 augmented_img = r_aug.random_augment(image,[0,1])

TypeError: random_augment() takes 2 positional arguments but 3 were given
  

У меня не такой опыт работы с классами, поэтому я уверен, что где-то я делаю что-то не так, но, хоть убей, я не могу этого понять!

Приветствия!

РЕДАКТИРОВАТЬ: опечатки

Комментарии:

1. Вы отсутствуете self в качестве первого аргумента для random_augment . Должно быть: def random_augment(self, img, order):

2. Спасибо за ответ! Проблема в том, что когда я добавляю self аргумент, я получаю другие ошибки: сначала я получаю NameError: name 'f_list' is not defined , а затем, если я определяю f_list внутри random_augment функции, я получаю NameError: name 'aug_rotate' is not defined . Поэтому я не уверен, где что определять…

3. Перейдите f_list в random_augment as self.f_list ... и убедитесь, что используете self.f_list везде.

4. Я тоже пробовал это, но NameError: name 'aug_rotate' is not defined , боюсь, я все еще получаю ошибку.

Ответ №1:

Попробуйте это:

 def random_augment(self, img, order):
    for i in order:
        function = [self.aug_rotate, self.aug_elastic][i]
        outp = function(img)
    return outp
  

Ответ №2:

Я прокомментировал части кода, в которые вы должны внести исправления, предложенные в комментариях:

 import numpy as np
import imgaug as ia
from imgaug import augmenters as iaa

image = my_image_to_transform


class random_augmentation:

    def __init__(self, rotate_range=None, e_sev=None, ):

        if rotate_range is None:
            self.rotate_range = None
        elif (type(rotate_range) is tuple) or (type(rotate_range) is list) and len(rotate_range) == 2:
            self.rotate_range = rotate_range
        else:
            self.rotate_range = None

        if e_sev is None:
            self.e_sev = None
        else:
            self.e_sev = e_sev

        self.f_list = [self.aug_rotate, self.aug_elastic]  # Added self.f_list
        
    def aug_rotate(self, img):
        if self.rotate_range is not None:
            rotate = iaa.Affine(rotate=self.rotate_range)
            rotated_img = rotate(image=img)
            return rotated_img
        else:
            pass

    def aug_elastic(self, img):
        if self.e_sev is not None:
            elastic = iaa.imgcorruptlike.ElasticTransform(severity=self.e_sev)
            elastic_img = elastic(image=img)
            return elastic_img
        else:
            pass

    def random_augment(self, img, order):  # Added self
        for i in order:
            function = self.f_list[i]  # Use self.f_list
            outp = function(img)
            img = outp
        return outp


r_aug = random_augmentation(rotate_range=(-30, 30), e_sev=3)

augmented_img = r_aug.random_augment(image, [0, 1])