Skip to content

Commit

Permalink
feature: custom creation date
Browse files Browse the repository at this point in the history
Allow to set custom creation date everywhere
  • Loading branch information
denniswittich committed Nov 8, 2024
1 parent 0091ac2 commit 58b39ed
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 15 deletions.
2 changes: 1 addition & 1 deletion learning_loop_node/detector/detector_logic.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def load_model(self):
def init(self):
"""Called when a (new) model was loaded. Initialize the model. Model information available via `self.model_info`"""

def evaluate_with_all_info(self, image: np.ndarray, tags: List[str], source: Optional[str] = None) -> ImageMetadata: # pylint: disable=unused-argument
def evaluate_with_all_info(self, image: np.ndarray, tags: List[str], source: Optional[str] = None, creation_date: Optional[str] = None) -> ImageMetadata: # pylint: disable=unused-argument
"""Called by the detector node when an image should be evaluated (REST or SocketIO).
Tags, source come from the caller and may be used in this function.
By default, this function simply calls `evaluate`"""
Expand Down
16 changes: 9 additions & 7 deletions learning_loop_node/detector/detector_node.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,10 +186,11 @@ async def upload(sid, data: Dict) -> Optional[Dict]:
tags.append('picked_by_system')

source = data.get('source', None)
creation_date = data.get('creation_date', None)

loop = asyncio.get_event_loop()
try:
await loop.run_in_executor(None, self.outbox.save, data['image'], detections, tags, source)
await loop.run_in_executor(None, self.outbox.save, data['image'], detections, tags, source, creation_date)
except Exception as e:
self.log.exception('could not upload via socketio')
return {'error': str(e)}
Expand Down Expand Up @@ -343,15 +344,16 @@ async def get_detections(self,
camera_id: Optional[str],
tags: List[str],
source: Optional[str] = None,
autoupload: Optional[str] = None) -> ImageMetadata:
autoupload: Optional[str] = None,
creation_date: Optional[str] = None) -> ImageMetadata:
""" Main processing function for the detector node when an image is received via REST or SocketIO.
This function infers the detections from the image, cares about uploading to the loop and returns the detections as a dictionary.
Note: raw_image is a numpy array of type uint8, but not in the correct shape!
It can be converted e.g. using cv2.imdecode(raw_image, cv2.IMREAD_COLOR)"""

await self.detection_lock.acquire()
loop = asyncio.get_event_loop()
detections = await loop.run_in_executor(None, self.detector_logic.evaluate_with_all_info, raw_image, tags, source)
detections = await loop.run_in_executor(None, self.detector_logic.evaluate_with_all_info, raw_image, tags, source, creation_date)
self.detection_lock.release()

fix_shape_detections(detections)
Expand All @@ -361,19 +363,19 @@ async def get_detections(self,

if autoupload is None or autoupload == 'filtered': # NOTE default is filtered
Thread(target=self.relevance_filter.may_upload_detections,
args=(detections, camera_id, raw_image, tags, source)).start()
args=(detections, camera_id, raw_image, tags, source, creation_date)).start()
elif autoupload == 'all':
Thread(target=self.outbox.save, args=(raw_image, detections, tags, source)).start()
Thread(target=self.outbox.save, args=(raw_image, detections, tags, source, creation_date)).start()
elif autoupload == 'disabled':
pass
else:
self.log.error('unknown autoupload value %s', autoupload)
return detections

async def upload_images(self, images: List[bytes]):
async def upload_images(self, images: List[bytes], source: Optional[str], creation_date: Optional[str]):
loop = asyncio.get_event_loop()
for image in images:
await loop.run_in_executor(None, self.outbox.save, image, ImageMetadata(), ['picked_by_system'])
await loop.run_in_executor(None, self.outbox.save, image, ImageMetadata(), ['picked_by_system'], source, creation_date)

def add_category_id_to_detections(self, model_info: ModelInformation, detections: ImageMetadata):
def find_category_id_by_name(categories: List[Category], category_name: str):
Expand Down
5 changes: 3 additions & 2 deletions learning_loop_node/detector/inbox_filter/relevance_filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ def may_upload_detections(self,
cam_id: str,
raw_image: bytes,
tags: List[str],
source: Optional[str] = None
source: Optional[str] = None,
creation_date: Optional[str] = None
) -> List[str]:
for group in self.cam_histories.values():
group.forget_old_detections()
Expand All @@ -29,5 +30,5 @@ def may_upload_detections(self,
if len(causes) > 0:
tags = tags if tags is not None else []
tags.extend(causes)
self.outbox.save(raw_image, dets, tags, source)
self.outbox.save(raw_image, dets, tags, source, creation_date)
return causes
18 changes: 13 additions & 5 deletions learning_loop_node/detector/rest/upload.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from typing import TYPE_CHECKING, List
from typing import TYPE_CHECKING, List, Optional

from fastapi import APIRouter, File, Request, UploadFile
from fastapi import APIRouter, File, Query, Request, UploadFile

if TYPE_CHECKING:
from ..detector_node import DetectorNode
Expand All @@ -9,13 +9,21 @@


@router.post("/upload")
async def upload_image(request: Request, files: List[UploadFile] = File(...)):
async def upload_image(request: Request,
files: List[UploadFile] = File(...),
source: Optional[str] = Query(None, description='Source of the image'),
creation_date: Optional[str] = Query(None, description='Creation date of the image')):
"""
Upload an image or multiple images to the learning loop.
The image source and the image creation date are optional query parameters.
Images are automatically tagged with 'picked_by_system'.
Example Usage
curl -X POST -F '[email protected]' "http://localhost:/upload"
curl -X POST -F '[email protected]' "http://localhost:/upload?source=test&creation_date=2024-01-01T00:00:00"
"""
raw_files = [await file.read() for file in files]
node: DetectorNode = request.app
await node.upload_images(raw_files)
await node.upload_images(raw_files, source, creation_date)
return 200, "OK"

0 comments on commit 58b39ed

Please sign in to comment.