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)
    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")
    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)
    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')
    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
                }
            })
    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')
    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)")
Example #8
0
    def InitPrivate(self):

        file_error_handler = logging.FileHandler(
            filename='logs/camera-tools-error.log', encoding='utf-8')
        file_error_handler.setLevel(logging.ERROR)
        file_handler = logging.handlers.TimedRotatingFileHandler(
            'logs/camera-tools.log',
            when='midnight',
            backupCount=7,
            encoding='utf-8')
        file_handler.suffix = '_%Y-%m-%d.log'
        # html_handler = HtmlLogger.HTMLRotatingFileHandler('camera-tools.html')
        # html_handler.suffix = '_%Y-%m-%d_%H.html'
        # html_handler.setFormatter(HtmlLogger.HTMLFormatter())
        locale.getpreferredencoding()  #need for display emoji in terminal
        stdout_handler = logging.StreamHandler(sys.stdout)
        handlers = [file_handler, stdout_handler, file_error_handler]

        logging.basicConfig(
            format=
            '%(asctime)s|%(levelname)-.3s|%(name)s: %(message)s',  # \t####=> %(filename)s:%(lineno)d 
            level=logging.DEBUG,
            datefmt='%H:%M:%S',
            handlers=handlers)

        self.log = logging.getLogger("API")
        ApiContext.Log = self.log
        self.log.info(
            'ℹ️ |############################################################|'
        )
        self.log.info(
            f'ℹ️ |####### start API @ {str(datetime.datetime.now()) + " ":#<40}|'
        )
        self.log.info(
            'ℹ️ |############################################################|'
        )
        self.log.info("USED_SETTINGS: " + AppSettings.USED_SETTINGS)
        self.Helper.installColoredLog(self.log)

        # Some examples.
        # self.log.debug("this is a debugging message")
        # self.log.info("this is an informational message")
        # self.log.warning("this is a warning message")
        # self.log.error("this is an error message")
        # self.log.critical("this is a critical message")

        self.isSimulation = False
        self.secretConfig = SecretConfig()
        self.secretConfig.fromJsonFile()

        ApiContext.CameraArchive = CameraArchiveHelper(self.log)
        ApiContext.ElasticSearch = ElasticSearchHelper()

        self.camera = 'Foscam'
        self.shotsPipeline = ShotsPipeline(self.camera, self.log)
        self.InitShotsPipeline()
        ApiContext.ShotsPipeline = self.shotsPipeline

        self.InitDnsPipeline()
        ApiContext.DnsPipeline = self.dnsPipeline

        self.InitPhotosPipeline()
        ApiContext.PhotosSergeyPipeline = self.photosSergeyPipeline
        ApiContext.PhotosLiliaPipeline = self.photosLiliaPipeline

        self.log.info(
            f'initialization API finished @ {datetime.datetime.now()}')
Example #9
0
class ApiContext:
    # class ApiContextInstance:
    #     def __init__(self, arg):
    #         self.val = arg
    # Instance = None
    IsInitialized = False
    Log = None
    Helper = CommonHelper()
    CameraArchive: CameraArchiveHelper
    ElasticSearch: ElasticSearchHelper
    ShotsPipeline: ShotsPipeline

    def __init__(self, arg):
        if not ApiContext.IsInitialized:
            self.InitPrivate()
            ApiContext.IsInitialized = True
        # if not ApiContext.Instance:
        #     ApiContext.Instance = ApiContext.ApiContextInstance("TODO")
        # else:
        #     ApiContext.Instance.val = arg

    def InitPrivate(self):

        file_error_handler = logging.FileHandler(
            filename='logs/camera-tools-error.log', encoding='utf-8')
        file_error_handler.setLevel(logging.ERROR)
        file_handler = logging.handlers.TimedRotatingFileHandler(
            'logs/camera-tools.log',
            when='midnight',
            backupCount=7,
            encoding='utf-8')
        file_handler.suffix = '_%Y-%m-%d.log'
        # html_handler = HtmlLogger.HTMLRotatingFileHandler('camera-tools.html')
        # html_handler.suffix = '_%Y-%m-%d_%H.html'
        # html_handler.setFormatter(HtmlLogger.HTMLFormatter())
        locale.getpreferredencoding()  #need for display emoji in terminal
        stdout_handler = logging.StreamHandler(sys.stdout)
        handlers = [file_handler, stdout_handler, file_error_handler]

        logging.basicConfig(
            format=
            '%(asctime)s|%(levelname)-.3s|%(name)s: %(message)s',  # \t####=> %(filename)s:%(lineno)d 
            level=logging.DEBUG,
            datefmt='%H:%M:%S',
            handlers=handlers)

        self.log = logging.getLogger("API")
        ApiContext.Log = self.log
        self.log.info(
            'ℹ️ |############################################################|'
        )
        self.log.info(
            f'ℹ️ |####### start API @ {str(datetime.datetime.now()) + " ":#<40}|'
        )
        self.log.info(
            'ℹ️ |############################################################|'
        )
        self.log.info("USED_SETTINGS: " + AppSettings.USED_SETTINGS)
        self.Helper.installColoredLog(self.log)

        # Some examples.
        # self.log.debug("this is a debugging message")
        # self.log.info("this is an informational message")
        # self.log.warning("this is a warning message")
        # self.log.error("this is an error message")
        # self.log.critical("this is a critical message")

        self.isSimulation = False
        self.secretConfig = SecretConfig()
        self.secretConfig.fromJsonFile()

        ApiContext.CameraArchive = CameraArchiveHelper(self.log)
        ApiContext.ElasticSearch = ElasticSearchHelper()

        self.camera = 'Foscam'
        self.shotsPipeline = ShotsPipeline(self.camera, self.log)
        self.InitShotsPipeline()
        ApiContext.ShotsPipeline = self.shotsPipeline

        self.InitDnsPipeline()
        ApiContext.DnsPipeline = self.dnsPipeline

        self.InitPhotosPipeline()
        ApiContext.PhotosSergeyPipeline = self.photosSergeyPipeline
        ApiContext.PhotosLiliaPipeline = self.photosLiliaPipeline

        self.log.info(
            f'initialization API finished @ {datetime.datetime.now()}')

    def InitPhotosPipeline(self):
        self.photosSergeyPipeline = Pipeline()
        self.photosSergeyPipeline.providers.append(
            FilesWalkerProvider("../camera-OpenCV-data/Mobile", ['Lilia']))
        self.photosSergeyPipeline.processors.append(
            MediaCreationDateProcessor())
        self.photosSergeyPipeline.processors.append(
            PhotosArrangeProcessor('Mobile Sergey'))

        self.photosLiliaPipeline = Pipeline()
        self.photosLiliaPipeline.providers.append(
            FilesWalkerProvider("../camera-OpenCV-data/Mobile/Lilia"))
        self.photosLiliaPipeline.processors.append(
            MediaCreationDateProcessor())
        self.photosLiliaPipeline.processors.append(
            PhotosArrangeProcessor('Mobile Lilia'))

    def InitShotsPipeline(self):
        self.shotsPipeline.providers.clear()
        self.shotsPipeline.processors.clear()
        self.shotsPipeline.providers.append(ImapShotsProvider())
        self.shotsPipeline.providers.append(DirectoryShotsProvider())
        self.shotsPipeline.processors.append(DiffContoursProcessor())
        self.shotsPipeline.processors.append(YoloObjDetectionProcessor())
        self.shotsPipeline.processors.append(TrackingProcessor())
        self.shotsPipeline.processors.append(SaveToTempProcessor())
        self.shotsPipeline.processors.append(MailSenderProcessor())
        self.shotsPipeline.processors.append(
            HassioProcessor('temp' if self.isSimulation else None))
        self.shotsPipeline.processors.append(
            ArchiveProcessor(self.isSimulation))
        self.shotsPipeline.processors.append(
            ElasticSearchProcessor(self.isSimulation))
        self.shotsPipeline.PreLoad()

    def InitDnsPipeline(self):
        self.dnsPipeline = Pipeline(self.log)
        self.dnsPipeline.providers.append(DnsAdGuardProvider())
        self.dnsPipeline.processors.append(ElasticSearchDnsProcessor())
Example #10
0
temp = 'temp'
imap_folder = 'camera/foscam'

# # 0. Preload
# yoloData = YoloPreloader()

# # 1. Get from source
imap = ImapShotsProvider(temp)
shotsImap = imap.GetShots(imap_folder);

# directory = DirectoryShotsProvider()
# shotsDir = directory.GetShots(shotsImap)

# # 2. Create Pipeline
pipeline = ShotsPipeline()
pipeline.shots = [shotsImap[:]] # , shotsDir[:]

# # 3. Add Processors
# # proceccor : Analyse() GetJsonResult() Draw()  
diff = DiffContoursProcessor()
pipeline.processors.append(diff)

# magnify = MagnifyProcessor(diff)
# pipeline.processor.append(magnify)

# yolo = YoloObjDetectionProcessor(yoloData)
# pipeline.processors.append(yolo)

# tracking = TrackingProcessor(diff, yolo)
# pipeline.processors.append(tracking)
Example #11
0
    '|####### start API @ %s ############################################################|',
    datetime.datetime.now())
log.info(
    '|###################################################################################|'
)

app = Flask(__name__)
print('start: {}'.format(datetime.datetime.now()))
# if __name__ == "__main__":
#     print('app.run @ 5000')
#     app.run(host='localhost', port=5000)
#yolo = YoloContext('..\\camera-OpenCV-data\\weights\\yolov3-tiny')
#yolo = YoloContext('..\\camera-OpenCV-data\\weights\\yolo-coco')
lock = threading.Lock()

pipeline = ShotsPipeline(camera)
InitPipeline()

log.info('initialization API finished @ %s', datetime.datetime.now())


@app.route('/image', methods=['GET'])
def getImage():
    id = request.args.get("id")
    if not id:
        return ""
    id = helper.Decode(id)
    log.info(
        f'====== start endpoint /image ID: {id} ============================================================================'
    )
    isOriginal = True if request.args.get("original") else False