0

I am trying to patch the augmentor function from the clodsa package to read custom named .json files instead of adhering to their format, so instead of /annotations.json make new_name.json:

!pip install clodsa
??augmentor

Type:        COCOLinearInstanceSegmentationAugmentor
String form: <clodsa.augmentors.cocoLinearInstanceSegmentationAugmentor.COCOLinearInstanceSegmentationAugmentor object at 0x7fbc1f48de50>
File:        /usr/local/lib/python3.7/dist-packages/clodsa/augmentors/cocoLinearInstanceSegmentationAugmentor.py
Source:     
class COCOLinearInstanceSegmentationAugmentor(IAugmentor):

    def __init__(self, inputPath, parameters):
        IAugmentor.__init__(self)
        self.imagesPath = inputPath
        self.annotationFile = inputPath + "/annotations.json"
        # output path represents the folder where the images will be stored
        if parameters["outputPath"]:
            self.outputPath = parameters["outputPath"]
        else:
            raise ValueError("You should provide an output path in the parameters")
        
        self.ignoreClasses = parameters.get("ignoreClasses",set())



    def readImagesAndAnnotations(self):
        (self.info, self.licenses, self.categories, self.dictImages, self.dictAnnotations) \
            = readCOCOJSON(self.annotationFile)

I have tried the following to patch the self.annotationFile path:

def new_init(self, inputPath, parameters):
  IAugmentor.__init__(self)
  self.imagesPath = inputPath
  self.annotationFile = inputPath + "/new_name.json"
  # output path represents the folder where the images will be stored
  if parameters["outputPath"]:
    self.outputPath = parameters["outputPath"]
  else:
    raise ValueError("You should provide an output path in the parameters")

  self.ignoreClasses = parameters.get("ignoreClasses",set())

augmentor.__init__ = new_init

When I run the new init it does actually show the monkey patched init with ??augmentor.init

But when I run the full code it just falls back to using the old init statement:

---------------------------------------------------------------------------

FileNotFoundError                         Traceback (most recent call last)

<ipython-input-15-30ca2128bdb6> in <module>()
      1 #Perform the augmentations
----> 2 augmentor.applyAugmentation()

2 frames

/usr/local/lib/python3.7/dist-packages/clodsa/augmentors/cocoLinearInstanceSegmentationAugmentor.py in applyAugmentation(self)
     87 
     88     def applyAugmentation(self):
---> 89         self.readImagesAndAnnotations()
     90 
     91         newannotations = Parallel(n_jobs=-1)(delayed(readAndGenerateInstanceSegmentation)

/usr/local/lib/python3.7/dist-packages/clodsa/augmentors/cocoLinearInstanceSegmentationAugmentor.py in readImagesAndAnnotations(self)
     84     def readImagesAndAnnotations(self):
     85         (self.info, self.licenses, self.categories, self.dictImages, self.dictAnnotations) \
---> 86             = readCOCOJSON(self.annotationFile)
     87 
     88     def applyAugmentation(self):

/usr/local/lib/python3.7/dist-packages/clodsa/augmentors/utils/readCOCOJSON.py in readCOCOJSON(jsonPath)
      5 
      6 def readCOCOJSON(jsonPath):
----> 7     with open(jsonPath) as f:
      8         data = json.load(f)
      9 

FileNotFoundError: [Errno 2] No such file or directory: '/content/drive/annotations.json'

What am I doing wrong?

Rivered
  • 741
  • 7
  • 27

1 Answers1

1

I looked at the source code for the COCOLinearInstanceSegmentationAugmentor class (the repository for this project is a bit of a mess--they've committed the binary .pyc files and other cruft, but that's an aside...)

It looks like you should be able to do it simply by subclassing:

class MyCOCOLinearInstanceSegmentationAugmentor(COCOLinearInstanceSegmentationAugmentor):
    def __init__(self, inputPath, parameters):
        super().__init__(inputPath, parameters)
        self.annotationFile = os.path.join(inputPath, 'new_name.json')

alternatively, since self.annotationsFile is just a normal attribute, after the COCOLinearInstanceSegmentationAugmentor is instantiated, but before any methods that use this attribute are called, you could simply assign it a new value like:

augmentor.annotationFile = <whatever you want>
Iguananaut
  • 21,810
  • 5
  • 50
  • 63
  • Thank you for the help. The second solution is working, practical and elegant! – Rivered Mar 25 '21 at 09:35
  • The first solution is not working unfortunately: NameError: name 'COCOLinearDetectionAugmentor' is not defined – Rivered Mar 25 '21 at 09:35
  • 1
    It looks like I misread your original question slightly, that you wanted `COCOLinearInstanceSegmentationAugmentor` not `COCOLinearDetectionAugmentor`. Nevertheless the answer is still the same. In either case you would need to *import* the class if you want to subclass it: `from closda.augmentators import COCOLinearInstanceSegmentationAugmentor` – Iguananaut Mar 25 '21 at 09:39