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)")
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()}')
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())
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)
'|####### 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