コード例 #1
0
    def test_SaveToTemp(self):
        # python -m unittest tests.test_pipeline.TestPipeline.test_SaveToTemp
        folder = '../camera-OpenCV-data/Camera/Foscam/Day_Lilia_Gate'

        pipeline = ShotsPipeline('Foscam', self.log)
        pipeline.providers.append(DirectoryShotsProvider(folder))
        pipeline.processors.append(DiffContoursProcessor())
        pipeline.processors.append(SaveToTempProcessor(True))
        pipeline.PreLoad()

        shots = pipeline.GetShots()
        result = pipeline.Process(shots)

        self.assertEqual(result[0].Shot.fullname,
                         "temp\\20190206_090254_Foscam_cv.jpeg")
        self.assertEqual(result[0].OriginalShot.fullname,
                         "temp\\20190206_090254_Foscam.jpg")
        self.assertTrue(os.path.isfile(result[0].Shot.fullname))
        self.assertTrue(os.path.isfile(result[0].OriginalShot.fullname))
        self.assertEqual(result[1].Shot.fullname,
                         "temp\\20190206_090255_Foscam_cv.jpeg")
        self.assertEqual(result[1].OriginalShot.fullname,
                         "temp\\20190206_090255_Foscam.jpg")
        self.assertEqual(result[2].Shot.fullname,
                         "temp\\20190206_090256_Foscam_cv.jpeg")
        self.assertEqual(result[2].OriginalShot.fullname,
                         "temp\\20190206_090256_Foscam.jpg")
コード例 #2
0
    def test_TrackingProcessor(self):
        # python -m unittest tests.test_pipeline.TestPipeline.test_TrackingProcessor
        folder = '../camera-OpenCV-data/Camera/Foscam/Day_Sergey_and_Olivia_tracking'
        yolo = YoloObjDetectionProcessor()
        yolo.PreLoad()
        target = TrackingProcessor(isDebug=True)
        pipelineShots = DirectoryShotsProvider.FromDir(None, folder)
        yolo.Process({'items': pipelineShots})
        target.Process({'items': pipelineShots})
        meta = pipelineShots[1].Metadata["TRAC"]
        pp.pprint(meta, indent=2)
        #pipelineShots[0].Shot.Show()
        #pipelineShots[1].Shot.Show()
        boxesById = {b['id']: b for b in meta['boxes']}
        self.assertEqual(15, boxesById['372x122']['angle'])
        self.assertEqual(138, boxesById['372x122']['distance'])
        self.assertEqual("372x122", boxesById['372x122']['center'])
        self.assertEqual(16, boxesById['230x146']['angle'])
        self.assertEqual(90, boxesById['230x146']['distance'])
        self.assertEqual("230x146", boxesById['230x146']['center'])

        meta = pipelineShots[2].Metadata["TRAC"]
        pp.pprint(meta, indent=2)
        #pipelineShots[2].Shot.Show()
        boxesById = {b['id']: b for b in meta['boxes']}
        self.assertEqual(10, boxesById["323x129"]['angle'])
        self.assertEqual(94, boxesById["323x129"]['distance'])
        self.assertEqual("323x129", boxesById["323x129"]['center'])
        self.assertEqual(28, boxesById["432x89"]['angle'])
        self.assertEqual(68, boxesById["432x89"]['distance'])
        self.assertEqual("432x89", boxesById["432x89"]['center'])
コード例 #3
0
    def test_YoloObjDetectionProcessor_noObjects(self):
        # python -m unittest tests.test_pipeline.TestPipeline.test_YoloObjDetectionProcessor_noObjects
        # INIT
        folder = '../camera-OpenCV-data/Camera/Foscam/Day_No_Objects'
        pipeline = ShotsPipeline('Foscam', self.log)
        pipeline.providers.append(DirectoryShotsProvider(folder))
        pipeline.processors.append(
            TestProcessor({'YOLO': {
                'labels': 'person:2 car bird'
            }}))
        pipeline.processors.append(YoloObjDetectionProcessor())
        pipeline.PreLoad()

        # TEST
        shots = pipeline.GetShots()
        shots = pipeline.Process(shots)

        # ASSERT
        self.assertEqual(5, len(shots))
        self.assertEqual(shots[0].Shot.GetDatetime(),
                         datetime.datetime(2019, 10, 16, 14, 21, 48))
        self.assertEqual(shots[1].Shot.GetDatetime(),
                         datetime.datetime(2019, 10, 16, 14, 21, 50))
        self.assertEqual(shots[2].Shot.GetDatetime(),
                         datetime.datetime(2019, 10, 16, 14, 21, 52))
        self.assertEqual(shots[3].Shot.GetDatetime(),
                         datetime.datetime(2019, 10, 16, 14, 21, 53))
        self.assertEqual(shots[4].Shot.GetDatetime(),
                         datetime.datetime(2019, 10, 16, 14, 21, 58))
        self.assertFalse('YOLO' in shots[0].Metadata)
        self.assertFalse('YOLO' in shots[1].Metadata)
        self.assertFalse('YOLO' in shots[2].Metadata)
コード例 #4
0
 def test_DirectoryShotsProvider(self):
     # python -m unittest tests.test_pipeline.TestPipeline.test_DirectoryShotsProvider
     folder = '../camera-OpenCV-data/Camera/Foscam/Day_Lilia_Gate'
     shots = DirectoryShotsProvider.FromDir(None, folder)
     self.assertEqual(3, len(shots))
     self.assertIsNotNone(shots[0].Shot.filename)
     self.assertIsNotNone(shots[0].Shot.fullname)
     self.assertIsNotNone(shots[0].Shot.Exist())
コード例 #5
0
    def test_ElasticSearchProcessor(self):
        # python -m unittest tests.test_pipeline.TestPipeline.test_ElasticSearchProcessor
        folder = '../camera-OpenCV-data/Camera/Foscam/Day_Lilia_Gate'
        CommonHelper.networkConfig = {}

        pipeline = ShotsPipeline('Foscam', self.log)
        pipeline.providers.append(DirectoryShotsProvider(folder))
        pipeline.processors.append(DiffContoursProcessor())
        pipeline.processors.append(ArchiveProcessor(True))
        pipeline.processors.append(ElasticSearchProcessor(True))
        #pipeline.processors.append(SaveToTempProcessor())
        pipeline.PreLoad()

        shots = pipeline.GetShots()
        result = pipeline.Process(shots)

        els = result[0].Metadata["ELSE"]
        self.assertIsNotNone(els['JSON'])
        #print(els['JSON'])
        dictEls = json.loads(els['JSON'])
        analyse = dictEls['Analyse']
        del dictEls['Analyse']

        archive = AppSettings.CAMERA_ARCHIVE_PATH.replace('\\', '/')
        expected = {
            "@timestamp": "2019-02-06T08:02:54.000Z",
            "camera": "Foscam",
            "doc": "event",
            "ext": "jpg",
            "path": archive +
            "/CameraArchive/Foscam/2019-02/06/20190206_090254_Foscam.jpg",
            "position": {
                "detail": "under the roof",
                "floor": -1,
                "room": "FrontWall"
            },
            "sensor": {
                "device": "Foscam FI9805W",
                "display": "Foscam(.) FrontWall",
                "id": "FoscamCameraArchiveFI9805W_C4D6553DECE1",
                "is_external": True,
                "type": "CameraArchive",
                "unit": "bytes"
            },
            "tags": ["synology_cameraarchive", "camera_tools"],
            "value": 69623,
            "volume": "/volume2"
        }

        for key in expected:
            self.assertEqual(dictEls[key], expected[key])

        self.assertAlmostEqual(
            analyse['DIFF']['boxes'][0]['profile_proportion'],
            1.77,
            delta=0.01)
コード例 #6
0
    def test_DirectoryShotsProvider_SearchByDate(self):
        # python -m unittest tests.test_pipeline.TestPipeline.test_DirectoryShotsProvider_SearchByDate
        folder = '../camera-OpenCV-data/Camera/Foscam/Day_Lilia_Gate'
        pShots = DirectoryShotsProvider.FromDir(None, folder)

        # Create base Shot
        for pShot in pShots:
            pShot.Metadata['PROV:IMAP'] = {}
            pShot.Metadata['PROV:IMAP']['start'] = self.helper.ToTimeStampStr(
                pShot.Shot.GetDatetime())

        target = DirectoryShotsProvider()
        target.config = self.archiver.load_configs('configs', ['Foscam'])[0]
        target.config.path_from = 'Foscam\\2019-02'
        pShots = target.GetShots(pShots)

        # search in C:\Src\camera-OpenCV-data\Camera\Foscam\2019-02\06
        self.assertEqual('Snap_20190206-090254-0.jpg', pShots[0].Shot.filename)
        self.assertEqual('Snap_20190206-090254-1.jpg', pShots[1].Shot.filename)
        self.assertEqual('Snap_20190206-090254-2.jpg', pShots[2].Shot.filename)
        self.assertEqual('MDAlarm_20190206-090259.jpg',
                         pShots[3].Shot.filename)
        self.assertEqual('MDAlarm_20190206-090304.jpg',
                         pShots[4].Shot.filename)
コード例 #7
0
def InitPipeline():
    pipeline.providers.clear()
    pipeline.processors.clear()
    pipeline.providers.append(ImapShotsProvider())
    pipeline.providers.append(DirectoryShotsProvider())
    pipeline.processors.append(DiffContoursProcessor())
    pipeline.processors.append(YoloObjDetectionProcessor())
    pipeline.processors.append(TrackingProcessor())
    pipeline.processors.append(SaveToTempProcessor())
    pipeline.processors.append(MailSenderProcessor())
    pipeline.processors.append(
        HassioProcessor('temp' if isSimulation else None))
    pipeline.processors.append(ArchiveProcessor(isSimulation))
    pipeline.processors.append(ElasticSearchProcessor(isSimulation))
    pipeline.PreLoad()
コード例 #8
0
 def test_TrackingProcessor_Day_3Person_2person_same_color(self):
     # python -m unittest tests.test_pipeline.TestPipeline.test_TrackingProcessor_Day_3Person_2person_same_color
     folder = '../camera-OpenCV-data/Camera/Foscam/Day_3Person_2person_same_color'
     yolo = YoloObjDetectionProcessor()
     yolo.PreLoad()
     target = TrackingProcessor(isDebug=True)
     pipelineShots = DirectoryShotsProvider.FromDir(None, folder)
     yolo.Process({'items': pipelineShots})
     target.Process({'items': pipelineShots})
     # pipelineShots[0].Shot.Show()
     metadata0 = pipelineShots[0].Metadata["TRAC"]['boxes']
     pp.pprint(metadata0, indent=2)
     self.assertListEqual([{
         'id': '293x148',
         'object_id': 1
     }, {
         'id': '350x151',
         'object_id': 2
     }, {
         'id': '379x103',
         'object_id': 3
     }], metadata0)
     #pipelineShots[1].Shot.Show()
     metadata1 = pipelineShots[1].Metadata["TRAC"]['boxes']
     pp.pprint(metadata1, indent=2)
     self.assertListEqual([{
         'id': '290x153',
         'angle': -178,
         'center': '290x153',
         'distance': 60,
         'object_id': 2
     }, {
         'id': '349x101',
         'angle': 176,
         'center': '349x101',
         'distance': 30,
         'object_id': 3
     }, {
         'id': '218x168',
         'angle': -165,
         'center': '218x168',
         'distance': 77,
         'object_id': 1
     }], metadata1)
     #pipelineShots[2].Shot.Show()
     metadata2 = pipelineShots[2].Metadata["TRAC"]
     pp.pprint(metadata2, indent=2)
コード例 #9
0
 def test_YoloObjDetectionProcessor(self):
     # python -m unittest tests.test_pipeline.TestPipeline.test_YoloObjDetectionProcessor
     folder = '../camera-OpenCV-data/Camera/Foscam/Day_Lilia_Gate'
     target = YoloObjDetectionProcessor()
     target.PreLoad()
     shots = DirectoryShotsProvider.FromDir(None, folder)
     target.Process({'items': shots})
     metadata0 = shots[0].Metadata['YOLO']
     metadata1 = shots[1].Metadata['YOLO']
     metadata2 = shots[2].Metadata['YOLO']
     pp.pprint(metadata0, indent=2)
     self.assertEqual(len(metadata0['areas']), 1)
     self.assertEqual(len(metadata1['areas']), 1)
     self.assertEqual(len(metadata2['areas']), 1)
     self.assertEqual(metadata0['areas'][0]['label'], 'person')
     self.assertEqual(metadata1['areas'][0]['label'], 'person')
     self.assertEqual(metadata2['areas'][0]['label'], 'person')
     self.assertEqual(metadata0['labels'], 'person')
     self.assertEqual(metadata1['labels'], 'person')
     self.assertEqual(metadata2['labels'], 'person')
コード例 #10
0
    def test_DiffContoursProcessor(self):
        # python -m unittest tests.test_pipeline.TestPipeline.test_DiffContoursProcessor
        folder = '../camera-OpenCV-data/Camera/Foscam/Day_Lilia_Gate'
        target = DiffContoursProcessor()
        pipelineShots = DirectoryShotsProvider.FromDir(None, folder)

        target.Process({'items': pipelineShots})
        # pp.pprint(pipelineShots[0].Metadata, indent=2)
        # pp.pprint(pipelineShots[1].Metadata, indent=2)
        # pp.pprint(pipelineShots[2].Metadata, indent=2)
        # result[0].Shot.Show()
        # result[1].Shot.Show()
        # result[2].Shot.Show()
        metadata = pipelineShots[0].Metadata['DIFF']
        self.assertGreater(metadata['Diff']['TotalArea'], 5000)
        self.assertLess(metadata['Diff']['TotalArea'], 6000)
        self.assertEqual(metadata['Diff']['Count'], 3)
        self.assertEqual(len(metadata['boxes']), 3)
        self.assertGreater(metadata['boxes'][0]['area'], 5000)
        self.assertLess(metadata['boxes'][0]['area'], 6000)
コード例 #11
0
    def test_ArchiveProcessor(self):
        # python -m unittest tests.test_pipeline.TestPipeline.test_ArchiveProcessor
        folder = '../camera-OpenCV-data/Camera/Foscam/Day_Lilia_Gate'

        pipeline = ShotsPipeline('Foscam', self.log)
        pipeline.providers.append(DirectoryShotsProvider(folder))
        pipeline.processors.append(ArchiveProcessor(True))
        pipeline.PreLoad()

        shots = pipeline.GetShots()
        result = pipeline.Process(shots)

        archMD = result[0].Metadata['ARCH']
        self.assertEqual(
            archMD['archive_destination'], AppSettings.CAMERA_ARCHIVE_PATH +
            '\\CameraArchive\\Foscam\\2019-02\\06\\20190206_090254_Foscam_cv.jpeg'
        )
        self.assertEqual(
            archMD['archive_destination_orig'],
            AppSettings.CAMERA_ARCHIVE_PATH +
            '\\CameraArchive\\Foscam\\2019-02\\06\\20190206_090254_Foscam.jpg')
コード例 #12
0
    def test_TrackingProcessor2(self):
        # python -m unittest tests.test_pipeline.TestPipeline.test_TrackingProcessor2
        folder = '../camera-OpenCV-data/Camera/Foscam/Day_Lilia_Gate'
        pipeline = ShotsPipeline('Foscam', self.log)
        pipeline.providers.append(DirectoryShotsProvider(folder))
        pipeline.processors.append(YoloObjDetectionProcessor())
        pipeline.processors.append(TrackingProcessor(isDebug=True))
        pipeline.PreLoad()
        shots = pipeline.GetShots()
        result = pipeline.Process(shots)

        meta = result[1].Metadata["TRAC"]
        pp.pprint(meta, indent=2)
        #result[1].Shot.Show()
        boxesById = {b['id']: b for b in meta['boxes']}
        self.assertDictEqual(
            boxesById, {
                '289x101': {
                    'angle': 25,
                    'center': '289x101',
                    'distance': 94,
                    'id': '289x101',
                    'object_id': 1
                }
            })

        meta = result[2].Metadata["TRAC"]
        pp.pprint(meta, indent=2)
        boxesById = {b['id']: b for b in meta['boxes']}
        #result[2].Shot.Show()
        self.assertDictEqual(
            boxesById, {
                '377x84': {
                    'angle': 10,
                    'center': '377x84',
                    'distance': 89,
                    'id': '377x84',
                    'object_id': 1
                }
            })
コード例 #13
0
 def test_TrackingProcessor_SizeError(self):
     # python -m unittest tests.test_pipeline.TestPipeline.test_TrackingProcessor_SizeError
     folder = '../camera-OpenCV-data/Camera/Foscam/Morning_Sergey_Tracking_Error'
     yolo = YoloObjDetectionProcessor()
     yolo.PreLoad()
     target = TrackingProcessor(isDebug=True)
     pipelineShots = DirectoryShotsProvider.FromDir(None, folder)
     yolo.Process({'items': pipelineShots})
     target.Process({'items': pipelineShots})
     metadata1 = pipelineShots[1].Metadata["TRAC"]
     pp.pprint(metadata1, indent=2)
     # pipelineShots[1].Shot.Show()
     boxesById = {b['id']: b for b in metadata1['boxes']}
     self.assertDictEqual(
         boxesById, {
             '436x69': {
                 'angle': 27,
                 'center': '436x69',
                 'distance': 83,
                 'id': '436x69',
                 'object_id': 1
             }
         })
コード例 #14
0
    def test_MailSend(self):
        # python -m unittest tests.test_pipeline.TestPipeline.test_MailSend
        folder = '../camera-OpenCV-data/Camera/Foscam/Day_Lilia_Gate'
        pipeline = ShotsPipeline('Foscam', self.log)
        pipeline.providers.append(DirectoryShotsProvider(folder))
        pipeline.processors.append(
            TestProcessor({'YOLO': {
                'labels': 'person:2 car bird'
            }}))
        pipeline.processors.append(DiffContoursProcessor())
        pipeline.processors.append(MailSenderProcessor(True))
        pipeline.PreLoad()
        shots = pipeline.GetShots()
        shots[0].Metadata['YOLO'] = {}
        shots[1].Metadata['YOLO'] = {}
        shots[2].Metadata['YOLO'] = {}
        shots[0].Metadata['YOLO']['labels'] = "person:2 car"
        shots[1].Metadata['YOLO']['labels'] = "person bird car"
        shots[2].Metadata['YOLO']['labels'] = ""
        shots[0].Metadata['YOLO']['areas'] = [
            self.getYoloArea('person'),
            self.getYoloArea('person'),
            self.getYoloArea('car')
        ]
        shots[1].Metadata['YOLO']['areas'] = [
            self.getYoloArea('person'),
            self.getYoloArea('bird'),
            self.getYoloArea('car')
        ]
        shots[2].Metadata['YOLO']['areas'] = []

        result = pipeline.Process(shots)

        sendMeta = result[0].Metadata['SMTP']
        self.assertEqual(sendMeta["Subject"],
                         "Foscam @09:02:54 person:2 car bird (06.02.2019)")
        self.assertEqual(sendMeta["id"], 'Foscam@2019-02-06T09:02:56.000Z')
コード例 #15
0
    def test_WholePipeline(self):
        # python -m unittest tests.test_pipeline.TestPipeline.test_WholePipeline
        CommonHelper.networkConfig = {}
        folder = '../camera-OpenCV-data/Camera/Foscam/Day_Sergey_and_Olivia_tracking'
        hassioDir = "temp"
        if not os.path.exists(hassioDir):
            os.mkdir(hassioDir)

        ## INIT
        pipeline = ShotsPipeline('Foscam', self.log)
        pipeline.providers.append(DirectoryShotsProvider(folder))
        # # proceccor : Analyse() GetJsonResult() Draw()
        #pipeline.processors.append(ZonesProcessor())
        pipeline.processors.append(DiffContoursProcessor())
        #pipeline.processors.append(MagnifyProcessor())
        pipeline.processors.append(YoloObjDetectionProcessor())
        pipeline.processors.append(TrackingProcessor())
        # #post processors:

        ########################################################################
        # Save analysed files to temp
        # original: temp\20190203_085908_{camera}.jpg
        # analysed: temp\20190203_085908_{camera}_cv.jpeg
        pipeline.processors.append(SaveToTempProcessor(True))

        ########################################################################
        # mail analysed files to gmail
        # attached: {ARCHIVE}\2019\02\03\cv_20190203-085908-{n}-{camera}_cv.(jpeg|png)
        # attached: info.json
        # body    : Analysis Log
        # Subject : {HH:MM} {detected objects} {total_area_countours}
        pipeline.processors.append(MailSenderProcessor(True))

        ########################################################################
        # update files in hassio server
        pipeline.processors.append(HassioProcessor(hassioDir))

        ########################################################################
        # save original files and analysed to archive directory by date
        # move from local archive to distant server (windows => diskstation)
        # original: {ARCHIVE}\2019\02\03\20190203-085908-{n}-{camera}.jpg
        # analysed: {ARCHIVE}\2019\02\03\20190203-085908-{n}-{camera}_cv.(jpeg|png)
        pipeline.processors.append(ArchiveProcessor(True))

        ########################################################################
        # add to ES info about files + analysed info
        pipeline.processors.append(ElasticSearchProcessor(True))

        pipeline.PreLoad()

        ## Procerss on shots comming
        shots = pipeline.GetShots()
        result = pipeline.Process(shots)
        # analyseResult[0].Shot.Show()
        # analyseResult[1].Shot.Show()
        # analyseResult[2].Shot.Show()
        self.assertTrue("TRAC" in result[1].Metadata)
        self.assertTrue("YOLO" in result[1].Metadata)
        self.assertTrue("DIFF" in result[1].Metadata)
        self.assertTrue("TRAC" in result[2].Metadata)
        self.assertTrue("YOLO" in result[2].Metadata)
        self.assertTrue("DIFF" in result[2].Metadata)
        self.assertTrue("TEMP" in result[2].Metadata)
        self.assertTrue("HASS" in result[2].Metadata)
        self.assertTrue("ELSE" in result[2].Metadata)

        tempMD = result[0].Metadata['TEMP']
        self.assertEqual(tempMD['fullname'],
                         "temp\\20190328_080122_Foscam_cv.jpeg")
        #self.assertEqual(tempMD['original_fullname'], "temp\\20190328_080122_Foscam.jpg")
        tempMD = result[1].Metadata['TEMP']
        self.assertEqual(tempMD['fullname'],
                         "temp\\20190328_080123_Foscam_cv.jpeg")
        #self.assertEqual(tempMD['original_fullname'], "temp\\20190328_080123_Foscam.jpg")

        mailMD = result[0].Metadata['SMTP']
        self.assertEqual(mailMD["Subject"],
                         "Foscam @08:01:22 person:2 (28.03.2019)")
        #self.assertEqual(mailMD["Body"], "/** Processing LOG **/")
        #self.assertGreater(mailMD["MessageSize"], 200000)

        hassMD = result[0].Metadata['HASS']
        self.assertEqual(hassMD['hassio_location'], 'temp\\cv_Foscam_0.jpg')

        archMD = result[0].Metadata['ARCH']
        self.assertEqual(
            archMD['archive_destination'], AppSettings.CAMERA_ARCHIVE_PATH +
            '\\CameraArchive\\Foscam\\2019-03\\28\\20190328_080122_Foscam_cv.jpeg'
        )
        self.assertEqual(
            archMD['archive_destination_orig'],
            AppSettings.CAMERA_ARCHIVE_PATH +
            '\\CameraArchive\\Foscam\\2019-03\\28\\20190328_080122_Foscam.jpg')

        els = result[0].Metadata["ELSE"]
        self.assertIsNotNone(els['JSON'])
        dictEls = json.loads(els['JSON'])
        print(els['JSON'])
        self.assertIsNotNone(dictEls['Analyse'])
        self.assertEqual(dictEls['Analyse']['YOLO']['areas'][0]['label'],
                         "person")
        self.assertEqual(dictEls['Analyse']['YOLO']['labels'], "person:2")
        self.assertEqual(dictEls['Analyse']['SMTP']['Subject'],
                         "Foscam @08:01:22 person:2 (28.03.2019)")
コード例 #16
0
    def test_TrackingProcessor_Day_3Person_2stay(self):
        # python -m unittest tests.test_pipeline.TestPipeline.test_TrackingProcessor_Day_3Person_2stay
        folder = '../camera-OpenCV-data/Camera/Foscam/Day_3Person_2stay'
        yolo = YoloObjDetectionProcessor()
        yolo.PreLoad()
        target = TrackingProcessor(isDebug=True)
        pipelineShots = DirectoryShotsProvider.FromDir(None, folder)
        yolo.Process({'items': pipelineShots})
        target.Process({'items': pipelineShots})
        for i, pShot in enumerate(pipelineShots):
            meta = pShot.Metadata["TRAC"]['boxes']
            title = ""
            for box in meta:
                title += f" B:{box['id']}-ID{box['object_id']}"
            print(f"Shot #{i}: {pShot.Shot.filename}")
            pp.pprint(meta, indent=2)
            #pShot.Shot.Show(title)

        # ID1 : Oli, ID2 : Fra
        meta = pipelineShots[0].Metadata["TRAC"]
        boxesById = {b['id']: b for b in meta['boxes']}
        self.assertDictEqual(
            boxesById, {
                '201x281': {
                    'id': '201x281',
                    'object_id': 2
                },
                '240x373': {
                    'id': '240x373',
                    'object_id': 1
                }
            })

        meta = pipelineShots[1].Metadata["TRAC"]
        boxesById = {b['id']: b for b in meta['boxes']}
        self.assertDictEqual(
            boxesById, {
                '183x288': {
                    'angle': -158,
                    'center': '183x288',
                    'distance': 19,
                    'id': '183x288',
                    'object_id': 2
                },
                '277x315': {
                    'angle': 57,
                    'center': '277x315',
                    'distance': 68,
                    'id': '277x315',
                    'object_id': 1
                }
            })

        meta = pipelineShots[2].Metadata["TRAC"]
        boxesById = {b['id']: b for b in meta['boxes']}
        self.assertDictEqual(
            boxesById,
            {
                '177x299': {
                    'angle': -118,
                    'center': '177x299',
                    'distance': 12,
                    'id': '177x299',
                    'object_id': 2
                },
                '189x247': {
                    'id': '189x247',
                    'object_id': 3
                },  # Papa
                '289x305': {
                    'angle': 39,
                    'center': '289x305',
                    'distance': 15,
                    'id': '289x305',
                    'object_id': 1
                }
            })

        meta = pipelineShots[3].Metadata["TRAC"]
        boxesById = {b['id']: b for b in meta['boxes']}
        self.assertDictEqual(
            boxesById['162x285'], {
                'angle': 136,
                'center': '162x285',
                'distance': 20,
                'id': '162x285',
                'object_id': 2
            })