Commit 13b75cd2 authored by Jithu Tagore's avatar Jithu Tagore

new commit

parent 51e5e165
File added
FROM nvcr.io/nvidia/l4t-pytorch:r32.5.0-pth1.7-py3
RUN apt-get update
RUN apt install tzdata ffmpeg libsm6 libxext6 -y
RUN python3 -m pip install --upgrade pip
RUN python3 -m pip install scipy==1.5.4
ADD . /app
WORKDIR /app
RUN python3 -m pip install -r requirements.txt
CMD ["python3","app.py"]
# jithu_acc
# Instructions
Create if not exists the folder in jetson: /home/ilens/container_weights
jithu is a ai_developer_nerd!!
\ No newline at end of file
Put the weights in that directory
| Item | Required file name |
|-------------------|--------------------|
| engine file name | yolov5.engine |
| libmyplugins name | libmyplugins.so |
| classes name | classes.json |
Make sure these 3 files are there in that directory
\ No newline at end of file
import os
# os.environ["config"]="{\"TZ\": \"Asia/Kolkata\", \"MONGO_URI\": \"mongodb://svc-ilens:svc2345@192.168.3.220:21017\", \"MONGO_DATABASE\": \"ilens_wps\", \"MONGO_COLLECTION\": \"janusDeployment\", \"MONGO_KEY\": \"deploymentId\", \"MONGO_VALUE\": \"_acc_test_7b5692781\", \"MONGO_COLL\": \"serviceConfiguration\", \"MONGO_DB\": \"ilens_wps\"}"
from edge_engine.edge_processor import ExecutePipeline
from edge_engine.edge_processor import Pubs
from scripts import CementBagCounter
from edge_engine.common.config import EDGE_CONFIG
if __name__ == '__main__':
pubs = Pubs()
mod = CementBagCounter(config=EDGE_CONFIG,
model_config=EDGE_CONFIG["modelConfig"],
pubs=pubs,
device_id=EDGE_CONFIG['deviceId'])
ex = ExecutePipeline(mod)
ex.run_model()
source /opt/intel/openvino/bin/setupvars.sh
python3 app.py
\ No newline at end of file
File added
File added
File added
version: "3"
services:
auto-loader:
image: autoloader:v1.7
build:
context: .
dockerfile: Dockerfile
restart: unless-stopped
# environment:
# - config=${config}
# - .env
volumes:
- ./data_mnt:/home/svc-ilens/vid/micro-nvr/iLensEdgeCameraRecordings
- ./archive:/app/archive
from edge_engine.ai.model.modelwraper import ModelWrapper
from abc import ABC, abstractmethod
class ModelWrapper(ABC):
def __init__(self, path=None):
"""Implement code to load mask_model here"""
pass
def _pre_process(self, x):
"""Implement code to process raw input into format required for mask_model inference here"""
return x
def _post_process(self, x):
"""Implement any code to post-process mask_model inference response here"""
return x
@abstractmethod
def _predict(self, x):
"""Implement core mask_model inference code here"""
pass
def predict(self, x):
pre_x = self._pre_process(x)
prediction = self._predict(pre_x)
result = self._post_process(prediction)
return result
# import the necessary packages
import cv2
import numpy as np
class GammaPreprocessor:
def __init__(self, gamma=1.0):
# creating Gamma table
self.invGamma = 1.0 / gamma
self.table = np.array([((i / 255.0) ** self.invGamma) * 255
for i in np.arange(0, 256)]).astype("uint8")
def preprocess(self, image):
return cv2.LUT(image, self.table)
# import the necessary packages
from keras.preprocessing.image import img_to_array
class ImageToArrayPreprocessor:
def __init__(self, dataFormat=None):
# store the image data format
self.dataFormat = dataFormat
def preprocess(self, image):
# apply the Keras utility function that correctly rearranges
# the dimensions of the image
return img_to_array(image, data_format=self.dataFormat)
# import the necessary packages
import cv2
class SimpleHistogramPreprocessor:
def __init__(self):
pass
def preprocess(self, image):
# Run Histogram simple Equalization
return cv2.equalizeHist(image)
# import the necessary packages
import cv2
class SimplePreprocessor:
def __init__(self, width, height, inter=cv2.INTER_AREA):
# store the target image width, height, and interpolation
# method used when resizing
self.width = width
self.height = height
self.inter = inter
def preprocess(self, image):
# resize the image to a fixed size, ignoring the aspect
# ratio
return cv2.resize(image, (self.width, self.height),
interpolation=self.inter)
import os
import sys
from edge_engine.common.constants import LicenseModule
from dateutil import parser
from datetime import datetime
from pymongo import MongoClient
from copy import deepcopy
import json
def licence_validator(payload):
try:
dt = parser.parse(payload['valid_till'])
now = datetime.now()
if (now > dt):
sys.stdout.write("Licence Expired \n".format())
sys.stdout.flush()
return False
return True
except KeyError as e:
sys.stderr.write("Error loading licence")
return False
def get_config_from_mongo(mongo_uri, dbname, basecollection,
key, value):
mongo = MongoClient(mongo_uri)
db = mongo[dbname]
config = db[basecollection].find_one({key: value}, {"_id": False})
return config
def load_conf(config,mongo_uri, dbname):
mongo = MongoClient(mongo_uri)
db = mongo[dbname]
pub_configs = []
for conf in config['pubConfigs']:
if conf["type"].lower() in ["mqtt","mongo",]:
key= conf["key"]
value=conf["value"]
collection = conf["conectionCollection"]
pub_conf = db[collection].find_one({key: value}, {"_id": False})
pub_conf.update(conf)
pub_configs.append(pub_conf)
else :
pub_configs.append(conf)
config['pubConfigs'] = pub_configs
return config
# """
# {
# "MONGO_URI": "mongodb://192.168.3.220:21017",
# "MONGO_DATABASE": "ilens_thermal_app",
# "MONGO_COLLECTION": "janus_deployment_details",
# "MONGO_KEY": "deploymentId",
# "MONGO_VALUE": "ddd"
# }
# """
LOG_LEVEL = os.environ.get("LOG_LEVEL", default="INFO").upper()
LOG_HANDLER_NAME = os.environ.get("LOG_HANDLER_NAME", default="ilens-edge_engine")
BASE_LOG_PATH = os.environ.get('BASE_LOG_PATH',
default=os.path.join(os.getcwd(), "logs".format()))
if not os.path.isdir(BASE_LOG_PATH):
os.mkdir(BASE_LOG_PATH)
CONFIG_ENV = json.loads(os.environ.get('config', default=None))
sys.stdout.write("config->{} \n".format(json.dumps(CONFIG_ENV)))
MONGO_URI = CONFIG_ENV.get('MONGO_URI', None)
MONGO_DATABASE = CONFIG_ENV.get('MONGO_DATABASE', None)
MONGO_COLLECTION = CONFIG_ENV.get('MONGO_COLLECTION', None)
MONGO_KEY = CONFIG_ENV.get('MONGO_KEY', None)
MONGO_VALUE = CONFIG_ENV.get('MONGO_VALUE',None)
if MONGO_URI == None \
or MONGO_DATABASE is None \
or MONGO_COLLECTION is None \
or MONGO_KEY is None \
or MONGO_VALUE is None:
sys.stderr.write("invalid mongo config \n")
sys.exit(1)
EDGE_CONFIG = get_config_from_mongo(
mongo_uri=MONGO_URI,
dbname=MONGO_DATABASE, basecollection=MONGO_COLLECTION,
key=MONGO_KEY, value=MONGO_VALUE
)
DEVICE_ID = EDGE_CONFIG["deviceId"]
if EDGE_CONFIG is None:
sys.stderr.write("invalid EDGE_CONFIG config \n")
sys.exit(1)
EDGE_CONFIG=load_conf(EDGE_CONFIG, mongo_uri=MONGO_URI,
dbname=MONGO_DATABASE)
DATA_PATH = EDGE_CONFIG["inputConf"].get('dataPath',os.path.join(os.getcwd(), "data".format()))
sys.stderr.write("Loading data from {} \n".format(DATA_PATH))
\ No newline at end of file
This diff is collapsed.
class LicenseModule:
private_key = "3139343831323738414d47454e3936363538373136"
encoding_algorithm = "HS256"
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from edge_engine.common.config import LOG_LEVEL, LOG_HANDLER_NAME, BASE_LOG_PATH
import logging
from logging.handlers import RotatingFileHandler
from logging import WARNING,INFO,DEBUG,ERROR
import os
DEFAULT_FORMAT = '%(asctime)s %(levelname)5s %(name)s %(message)s'
DEBUG_FORMAT = '%(asctime)s %(levelname)5s %(name)s [%(threadName)5s:%(filename)5s:%(funcName)5s():%(lineno)s] %(message)s'
EXTRA = {}
FORMATTER = DEFAULT_FORMAT
if LOG_LEVEL.strip() == "DEBUG":
FORMATTER = DEBUG_FORMAT
def get_logger(log_handler_name, extra=EXTRA):
"""
Purpose : To create logger .
:param log_handler_name: Name of the log handler.
:param extra: extra args for the logger
:return: logger object.
"""
log_path = os.path.join(BASE_LOG_PATH, log_handler_name + ".log")
logstash_temp = os.path.join(BASE_LOG_PATH, log_handler_name + ".db")
logger = logging.getLogger(log_handler_name)
logger.setLevel(LOG_LEVEL.strip().upper())
log_handler = logging.StreamHandler()
log_handler.setLevel(LOG_LEVEL)
formatter = logging.Formatter(FORMATTER)
log_handler.setFormatter(formatter)
handler = RotatingFileHandler(log_path, maxBytes=10485760,
backupCount=5)
handler.setFormatter(formatter)
logger.addHandler(log_handler)
logger.addHandler(handler)
logger = logging.LoggerAdapter(logger, extra)
return logger
logger = get_logger(LOG_HANDLER_NAME)
import os, time
from minio import Minio
from edge_engine.common.logsetup import logger
class MinioClient:
def __init__(self ,SECRET_KEY, ACCESS_KEY, BUCKET_NAME, LOCAL_DATA_PATH, MINIO_IP):
logger.info("Initalizing minioclient !!")
self.SECRET_KEY = SECRET_KEY
self.ACCESS_KEY = ACCESS_KEY
self.BUCKET_NAME = BUCKET_NAME
self.LOCAL_DATA_PATH = LOCAL_DATA_PATH
self.MINIO_IP = MINIO_IP
self.logfile = "./logs/videowrite.log"
self.minioClient = self.connect_to_minio()
self.create_bucket(self.BUCKET_NAME)
def connect_to_minio(self):
if self.SECRET_KEY is not None and self.ACCESS_KEY is not None:
logger.info("Connecting to Minio Service... !!! ")
minio_client = Minio(self.MINIO_IP, access_key = self.ACCESS_KEY, secret_key = self.SECRET_KEY,
region='us-east-1', secure=False)
return minio_client
else:
logger.info('Access Key and Secret Key String cannot be null')
raise Exception('Access Key and Secret Key String cannot be null')
def create_bucket(self, bucket_name):
try:
if bucket_name not in self.list_buckets():
logger.info("Creating bucket {}...".format(bucket_name))
self.minioClient.make_bucket(bucket_name, location="us-east-1")
else:
logger.info("Bucket already exists....")
except Exception as err:
logger.error(err)
def save_to_bucket(self, bucket_name, data_obj):
try:
with open(data_obj, 'rb') as file:
file_stat = os.stat(data_obj)
self.minioClient.put_object(bucket_name, data_obj.split(self.LOCAL_DATA_PATH)[1],
file, file_stat.st_size)
except Exception as err:
logger.error(err)
def list_buckets(self):
bucketobjects = self.minioClient.list_buckets()
bucketlist = []
for eachbucket in bucketobjects:
bucketlist.append(eachbucket.name)
return bucketlist
def read_write_logs(self):
try:
f = open(self.logfile)
except Exception as err:
print(err)
with open(self.logfile, "a") as startfile:
startfile.write("")
f = open(self.logfile)
return [line.split('\n')[0] for line in f]
def write_write_logs(self, log_str):
with open(self.logfile, "a") as my_file:
my_file.write(log_str + "\n")
def upload(self):
if self.LOCAL_DATA_PATH[-1]!='/':
self.LOCAL_DATA_PATH = self.LOCAL_DATA_PATH+"/"
while True:
listoffiles = [os.path.join(path, name) for path, subdirs, files in os.walk(self.LOCAL_DATA_PATH) for name in files]
listofwrittenfiles = self.read_write_logs()
listofnewfiles = list(set(listoffiles) - set(listofwrittenfiles))
for fileName in listofnewfiles:
try:
logger.info("Uploading {}..".format(fileName.split(self.LOCAL_DATA_PATH)[1]))
self.save_to_bucket(self.BUCKET_NAME, fileName)
self.write_write_logs(fileName)
except Exception as e:
logger.error(e)
time.sleep(5)
# if __name__=='__main__':
# SECRET_KEY = 'minioadmin'
# ACCESS_KEY = 'minioadmin'
# BUCKET_NAME = 'videobucket'
# MINIO_IP = '192.168.3.220:29000'
# LOCAL_DATA_PATH = "F:/GDrive Data/Downloads"
# obj = MinioClient(SECRET_KEY, ACCESS_KEY, BUCKET_NAME, LOCAL_DATA_PATH, MINIO_IP)
# obj.upload()
from edge_engine.common.logsetup import logger
from edge_engine.common.config import EDGE_CONFIG
from edge_engine.streamio.datastream import MQTT
from edge_engine.streamio.datastream import VideoOutputStream
from edge_engine.streamio.datastream import FrameOutputStream
from edge_engine.streamio.datastream import FFMPEGOutputStream
from edge_engine.streamio.datastream import MongoDataStreamOut
from edge_engine.streamio.videostream import ThreadedVideoStream
from edge_engine.streamio.videostream import FileVideoStream
from edge_engine.streamio.frameProcessor import FrameProcessor, FrameProcessorv2
from edge_engine.common.minio_server import MinioClient
import json
from threading import Thread
import time
import os
from edge_engine.streamio.videostream.filepathvideostream import FilePathVideoStream
class Pubs():
def __init__(self):
self.mqtt_pub = None
self.frame_write = None
self.video_write = None
self.mongo_write = None
self.rtp_write = None
self.build_pubs()
if 'minioConfig' in EDGE_CONFIG.keys() and \
isinstance(EDGE_CONFIG["minioConfig"],dict):
self.minio_thread = self.start_minio(EDGE_CONFIG["minioConfig"])
@staticmethod
def start_minio(minio_conf):
obj = MinioClient(minio_conf['secretKey'], minio_conf['accessKey'],
minio_conf['bucketName'], minio_conf['localDataPath'],
minio_conf['ip'])
t = Thread(target=obj.upload)
t.start()
return t
def build_pubs(self):
logger.info("building publishers ")
for conf in EDGE_CONFIG["pubConfigs"]:
if conf["type"].upper() == "MQTT":
self.mqtt_pub = MQTT(broker=conf["broker"], topic=conf["topic"], port=conf["port"]
, publish_hook=json.dumps)
elif conf["type"].upper() == "FRAMEWRITE":
self.frame_write = FrameOutputStream(
basepath=conf["basepath"],
iformat=conf["iformat"],
filenameFormat=conf["filenameFormat"],
publish_hook=None)
elif conf["type"].upper() == "VIDEOWRITE":
self.video_write = VideoOutputStream(basepath=conf["basepath"],
dims=conf["dims"],
filenameFormat=conf["filenameFormat"],
fps=conf["fps"], publish_hook=None)
elif conf["type"].upper() == "MONGO":
self.mongo_write = MongoDataStreamOut(host=conf["host"],
port=conf["port"],
dbname=conf["dbname"],
collection=conf["collection"],
keys=conf["keys"],
authsource=conf["authSource"],
username=conf["username"],
password=conf["password"],
publish_hook=None)
elif conf["type"].upper() == "RTP":
self.rtp_write = FFMPEGOutputStream(conf["ffmpegCmd"], conf["RTPEndpoint"]
, publish_hook=None)
else:
logger.error("Unsupported publisher {}".format(conf["type"]))
class ExecutePipeline:
def __init__(self, model):
self.model = model
def run_model(self):
if EDGE_CONFIG["inputConf"]["sourceType"].lower() in ["rtsp", "usbcam"]:
logger.info("Selected input stream as Direct cv input")
self.threadedVideoStream = ThreadedVideoStream(stream_config=EDGE_CONFIG["inputConf"])
self.threadedVideoStream.start()
self.frameProcessor = FrameProcessor(stream=self.threadedVideoStream,
model=self.model)
elif EDGE_CONFIG["inputConf"]["sourceType"].lower() == "videofile":
self.fileVideoStream = FileVideoStream(stream_config=EDGE_CONFIG["inputConf"])
self.fileVideoStream.start()
self.frameProcessor = FrameProcessor(stream=self.fileVideoStream, model=self.model)
elif EDGE_CONFIG["inputConf"]["sourceType"].lower() == "videopath":
processed_videos = []
videopath = EDGE_CONFIG["inputConf"].get('uri',"")
while True:
time1= time.time()
video_files = os.listdir(videopath)
if not video_files:
time.sleep(0.01)
continue
video_files.sort()
for video in video_files:
if video in processed_videos:
continue
if not video.endswith(".mp4"):
processed_videos.append(video)
continue
processed_videos.append(video)
EDGE_CONFIG["inputConf"]['uri'] = os.path.join(videopath, video)
self.fileVideoStream = FilePathVideoStream(EDGE_CONFIG["inputConf"]['uri'])
self.fileVideoStream.start()
self.frameProcessor = FrameProcessorv2(stream=self.fileVideoStream, model=self.model)
self.start_model()
logger.info("---------------")
logger.info(time.time()-time1)
# logger.info(int(time.time())-time2)
# logger.info(int(time.time())-time3)
logger.info("---------------")
else:
raise ValueError("unsupported source {}".format(EDGE_CONFIG["inputConf"]["sourceType"]))
self.start_model()
def start_model(self):
self.thread = Thread(target=self.frameProcessor.run_model(), args=())
self.thread.daemon = True
self.thread.start()
from edge_engine.streamio.frameProcessor import FrameProcessor
from .datastreamprocessor import DataStreamProcessor
from edge_engine.streamio.datastream.datastreamwrapper import DataStreamWrapper
from edge_engine.streamio.datastream.mongodatastreamout import MongoDataStreamOut
from edge_engine.streamio.datastream.frameoutputstream import FrameOutputStream
from edge_engine.streamio.datastream.videooutputstream import VideoOutputStream
from edge_engine.streamio.datastream.mqttstream import MQTT
from edge_engine.streamio.datastream.ffmpegdata_streamout import FFMPEGOutputStream
\ No newline at end of file
from abc import ABC, abstractmethod
class DataStreamWrapper(ABC):
def __init__(self):
"""Implement code to load mask_model here"""
pass
def publish(self, x):
"""Implement code to publish"""
return x
def subscribe(self,hook):
"""Implement code to subscribe"""
return None
\ No newline at end of file
from edge_engine.streamio.datastream.datastreamwrapper import DataStreamWrapper
import subprocess as sp
class FFMPEGOutputStream(DataStreamWrapper):
def __init__(self, ffmpeg_cmd, rtp_endpoint, publish_hook=None):
super().__init__()
self.ffmpeg_cmd = ffmpeg_cmd
self.rtp_endpoint = rtp_endpoint
self.ffmpeg_cmd.append(self.rtp_endpoint[0])
self.proc = sp.Popen(self.ffmpeg_cmd, stdin=sp.PIPE, shell=False)
self.publish_hook = publish_hook
def publish(self, x):
if self.publish_hook is not None:
x = self.publish_hook(x)
frame = x["frame"]
self.proc.stdin.write(frame.tostring())
self.proc.stdin.flush()
from edge_engine.streamio.datastream.datastreamwrapper import DataStreamWrapper
import cv2
import base64
import numpy as np
import os
from edge_engine.common.logsetup import logger
from datetime import datetime
class FrameOutputStream(DataStreamWrapper):
def __init__(self, basepath, iformat="jpg", filenameFormat="{deviceId}_{frameId}_{timestamp}", publish_hook=None):
super().__init__()
self.basepath = basepath
self.iformat = iformat
self.filenameFormat = filenameFormat
self.publish_hook = publish_hook
def publish(self, x):
if self.publish_hook is not None:
x= self.publish_hook(x)
frame = x["frame"]
frame = base64.b64decode(frame.split("data:image/jpeg;base64,")[1])
frame = np.fromstring(frame, np.uint8)
frame = cv2.imdecode(frame, cv2.IMREAD_COLOR)
path = os.path.join(self.basepath, datetime.now().date().isoformat())
if not os.path.isdir(path):
logger.info("Creating {} \n".format(path))
os.mkdir(path)
cv2.imwrite("{path}.{iformat}".format(path=os.path.join(path, self.filenameFormat.format(**x)),
iformat=self.iformat), frame)
return True
def subscribe(self, hook):
super().subscribe(hook)
from edge_engine.streamio.datastream.datastreamwrapper import DataStreamWrapper
from pymongo import MongoClient
class MongoDataStreamOut(DataStreamWrapper):
def __init__(self, host, port, dbname, collection, keys, authsource,username=None,password=None, publish_hook=None):
super().__init__()
self.host = host
self.port = port
self.dbname = dbname
self.username = username
self.password = password
self.collection = collection
self.publish_hook = publish_hook
self.mongo = MongoClient(host=host,
port=int(port),username=self.username,password=self.password)
self.db = self.mongo[dbname]
self.keys = keys
self.authsource = authsource
def subscribe(self, hook=None):
pass
def publish(self, data):
if self.publish_hook is not None:
data = self.publish_hook(data)
fin_dat = {}
for k, v in data.items():
if k in self.keys:
fin_dat[k] = v
self.db[self.collection].insert(fin_dat)
import paho.mqtt.client as paho
from edge_engine.streamio.datastream.datastreamwrapper import DataStreamWrapper
from edge_engine.common.logsetup import logger
from uuid import uuid4
import traceback
class MQTT(DataStreamWrapper):
@staticmethod
def on_connect(client, userdata, flags, rc):
logger.info("Connection returned with result code:" + str(rc))
@staticmethod
def on_disconnect(client, userdata, rc):
logger.info("Disconnection returned result:" + str(rc))
@staticmethod
def on_subscribe(client, userdata, mid, granted_qos):
logger.debug("Subscribing MQTT {} {} {} {}".format(client, userdata, mid, granted_qos))
def on_message(self, client, userdata, msg):
logger.debug("Received message, topic:" + msg.topic + "payload:" + str(msg.payload))
if self.subscribe_hook is not None:
self.subscribe_hook(msg.payload.decode())
def __init__(self, broker, port, topic, qos=2, subscribe_hook=None, publish_hook=None):
super().__init__()
self.broker = broker
self.port = int(port)
self.topic = topic
self.client_name = "{}".format(uuid4())
self.client = paho.Client(self.client_name)
self.client.on_connect = self.on_connect
self.client.on_disconnect = self.on_disconnect
self.client.on_subscribe = self.on_subscribe
self.client.on_message = self.on_message
self.client.connect(host=self.broker, port=self.port)
self.subscribe_hook = subscribe_hook
self.publish_hook = publish_hook
self.qos = qos
def subscribe(self, hook=None):
if hook is not None:
self.subscribe_hook =hook
self.client.subscribe((self.topic, self.qos))
self.client.loop_forever()
def publish(self, data):
try:
if self.publish_hook is not None:
data = self.publish_hook(data)
self.client.publish(self.topic, data)
except Exception as e:
logger.error(e)
logger.error(traceback.format_exc())
from edge_engine.streamio.datastream.datastreamwrapper import DataStreamWrapper
import cv2
import base64
import numpy as np
import os
from edge_engine.common.logsetup import logger
from datetime import datetime
class VideoOutputStream(DataStreamWrapper):
def __init__(self, basepath, dims, filenameFormat="{deviceId}_{timestamp}", fps=30, publish_hook=None):
super().__init__()
self.basepath = basepath
self.dims = (int(dims[0]),int(dims[1]))
self.fps = float(fps)
self.filenameFormat = filenameFormat
self.publish_hook = publish_hook
self.four_cc = cv2.VideoWriter_fourcc(*'mp4v')
self.out = None
def publish(self, x):
if self.publish_hook is not None:
x = self.publish_hook(x)
if len(x["metric"]) > 0:
if self.out is None:
path = os.path.join(self.basepath, datetime.now().date().isoformat())
if not os.path.isdir(path):
logger.info("Creating {} \n".format(path))
os.mkdir(path)
self.out = cv2.VideoWriter("{}.mp4".format(os.path.join(path, self.filenameFormat.format(**x))),
self.four_cc, self.fps, self.dims)
frame = x["frame"]
frame = base64.b64decode(frame.split("data:image/jpeg;base64,")[1])
frame = np.fromstring(frame, np.uint8)
frame = cv2.imdecode(frame, cv2.IMREAD_COLOR)
self.out.write(frame)
else:
if self.out is not None:
self.out.release()
self.out = None
return True
def subscribe(self, hook):
super().subscribe(hook)
from edge_engine.common.logsetup import logger
class DataStreamProcessor:
def __init__(self, model, subsciber, publishers=list()):
self.model = model
self.subsciber = subsciber
self.publishers = publishers
logger.info("Setting up frame processor !!")
def processstream(self, msg):
print(msg)
def run_model(self):
self.subsciber.subscribe(hook=self.processstream)
import time
from edge_engine.common.logsetup import logger
from edge_engine.common.config import DEVICE_ID
from uuid import uuid4
import traceback
class FrameProcessor:
def __init__(self, stream, model):
self.model = model
self.stream = stream
logger.info("Setting up frame processor !!")
self.count = 0
self.skip_frame_every = 1 # 1 does not skip any frame (n-1 frames get skipped)
def run_model(self):
while self.stream.stream.isOpened():
try:
logger.debug("Getting frame mask_model")
frame = self.stream.read()
logger.debug("Running mask_model")
self.count += 1
if frame is not None and self.count % self.skip_frame_every == 0:
fid = uuid4()
data = {
"frame": frame,
"frameId": "{}".format(fid),
"deviceId": "{}".format(DEVICE_ID),
}
self.model.predict(data)
time.sleep(0.01)
except Exception as e:
logger.error(e)
logger.error(traceback.format_exc())
class FrameProcessorv2:
def __init__(self, stream, model):
self.model = model
self.stream = stream
self.count = 0
self.skip_frame_every = 3 # 1 does not skip any frame (n-1 frames get skipped)
def run_model(self):
while self.stream.running():
try:
frame = self.stream.read()
self.count += 1
if frame is not None and self.count % self.skip_frame_every == 0:
fid = uuid4()
data = {
"frame": frame,
"frameId": "{}".format(fid),
"deviceId": "{}".format(DEVICE_ID),
}
self.model.predict(data)
except Exception as e:
logger.error(e)
logger.error(traceback.format_exc())
self.model.running = False
from edge_engine.streamio.videostream.fps import FPS
from edge_engine.streamio.videostream.nvgstreamer import NVGstreamer
from edge_engine.streamio.videostream.simplevideostream import SimpleVideoStream
from edge_engine.streamio.videostream.threadedvideostream import ThreadedVideoStream
from edge_engine.streamio.videostream.filevideostream import FileVideoStream
\ No newline at end of file
# import the necessary packages
from threading import Thread
import sys
import cv2
import time
import os
import shutil
import imutils
# import the Queue class from Python 3
if sys.version_info >= (3, 0):
from queue import Queue
# otherwise, import the Queue class for Python 2.7
else:
from Queue import Queue
def frame_transform(frame):
frame = imutils.resize(frame, width=416, height=416)
return frame
class FilePathVideoStream:
def __init__(self, path, transform=None, queue_size=256):
# initialize the file video stream along with the boolean
# used to indicate if the thread should be stopped or not
self.path=path
while True:
self.stream = cv2.VideoCapture(path)
if not self.stream.isOpened():
time.sleep(0.01)
continue
break
self.stopped = False
self.transform = transform
# initialize the queue used to store frames read from
# the video file
self.Q = Queue(maxsize=queue_size)
# intialize thread
self.thread = Thread(target=self.update, args=())
self.thread.daemon = True
def start(self):
# start a thread to read frames from the file video stream
self.thread.start()
return self
def update(self):
# keep looping infinitely
while True:
# if the thread indicator variable is set, stop the
# thread
if self.stopped:
break
# otherwise, ensure the queue has room in it
if not self.Q.full():
# read the next frame from the file
(grabbed, frame) = self.stream.read()
# if the `grabbed` boolean is `False`, then we have
# reached the end of the video file
if not grabbed:
self.stopped = True
# if there are transforms to be done, might as well
# do them on producer thread before handing back to
# consumer thread. ie. Usually the producer is so far
# ahead of consumer that we have time to spare.
#
# Python is not parallel but the transform operations
# are usually OpenCV native so release the GIL.
#
# Really just trying to avoid spinning up additional
# native threads and overheads of additional
# producer/consumer queues since this one was generally
# idle grabbing frames.
if self.transform:
frame = self.transform(frame)
# add the frame to the queue
self.Q.put(frame)
else:
time.sleep(0.1) # Rest for 10ms, we have a full queue
self.stream.release()
def read(self):
# return next frame in the queue
return self.Q.get()
# Insufficient to have consumer use while(more()) which does
# not take into account if the producer has reached end of
# file stream.
def running(self):
# custom addition to this func
cond = self.more() or not self.stopped
if not cond:
self.move_file()
return cond
def more(self):
# return True if there are still frames in the queue. If stream is not stopped, try to wait a moment
tries = 0
while self.Q.qsize() == 0 and not self.stopped and tries < 5:
time.sleep(0.1)
tries += 1
return self.Q.qsize() > 0
def stop(self):
# indicate that the thread should be stopped
self.stopped = True
# wait until stream resources are released (producer thread might be still grabbing frame)
self.thread.join()
def move_file(self):
src_path = self.path
dest_path = "archive"
root_path = os.path.dirname(os.path.abspath(__file__))
src = os.path.join(root_path, src_path)
if not os.path.exists(dest_path):
os.mkdir(dest_path)
shutil.move(src, dest_path)
# import the necessary packages
from threading import Thread
import sys
import cv2
import time
# import the Queue class from Python 3
if sys.version_info >= (3, 0):
from queue import Queue
# otherwise, import the Queue class for Python 2.7
else:
from Queue import Queue
class FileVideoStream:
def __init__(self,stream_config, transform=None):
# initialize the file video stream along with the boolean
# used to indicate if the thread should be stopped or not
self.transform = transform
self.stream_config =stream_config
# initialize the queue used to store frames read from
# the video file
self.build_pipeline()
def start(self):
# start a thread to read frames from the file video stream
self.thread.start()
return self
def build_cv_obj(self):
self.stream = cv2.VideoCapture(self.stream_config["uri"])
self.stopped = False
def build_pipeline(self):
self.build_cv_obj()
if "queueSize" not in self.stream_config:
self.stream_config["queueSize"] =128
self.Q = Queue(maxsize=int(self.stream_config["queueSize"]))
# intialize thread
self.thread = Thread(target=self.update, args=())
self.thread.daemon = True
def is_opened(self):
return self.stream.isOpened()
def update(self):
# keep looping infinitely
while True:
# if the thread indicator variable is set, stop the
# thread
if self.stopped:
break
# otherwise, ensure the queue has room in it
if not self.Q.full():
# read the next frame from the file
(grabbed, frame) = self.stream.read()
# if the `grabbed` boolean is `False`, then we have
# reached the end of the video file
if grabbed is False or frame is None:
#self.stopped = True
self.build_cv_obj()
continue
# if there are transforms to be done, might as well
# do them on producer thread before handing back to
# consumer thread. ie. Usually the producer is so far
# ahead of consumer that we have time to spare.
#
# Python is not parallel but the transform operations
# are usually OpenCV native so release the GIL.
#
# Really just trying to avoid spinning up additional
# native threads and overheads of additional
# producer/consumer queues since this one was generally
# idle grabbing frames.
if self.transform:
frame = self.transform(frame)
# add the frame to the queue
self.Q.put(frame)
else:
time.sleep(0.1) # Rest for 10ms, we have a full queue
self.stream.release()
def read(self):
# return next frame in the queue
return self.Q.get()
# Insufficient to have consumer use while(more()) which does
# not take into account if the producer has reached end of
# file stream.
def running(self):
return self.more() or not self.stopped
def more(self):
# return True if there are still frames in the queue. If stream is not stopped, try to wait a moment
tries = 0
while self.Q.qsize() == 0 and not self.stopped and tries < 5:
time.sleep(0.1)
tries += 1
return self.Q.qsize() > 0
def stop(self):
# indicate that the thread should be stopped
self.stopped = True
# wait until stream resources are released (producer thread might be still grabbing frame)
self.thread.join()
\ No newline at end of file
# import the necessary packages
import datetime
class FPS:
def __init__(self):
# store the start time, end time, and total number of frames
# that were examined between the start and end intervals
self._start = None
self._end = None
self._numFrames = 0
def start(self):
# start the timer
self._start = datetime.datetime.now()
return self
def stop(self):
# stop the timer
self._end = datetime.datetime.now()
def update(self):
# increment the total number of frames examined during the
# start and end intervals
self._numFrames += 1
def elapsed(self):
# return the total number of seconds between the start and
# end interval
return (self._end - self._start).total_seconds()
def fps(self):
# compute the (approximate) frames per second
return self._numFrames / self.elapsed()
import cv2
class NVGstreamer:
def __init__(self, buildconfig):
self.width = 480
self.height = 640
self.latency = 0
self.framerate = "10/1"
self.fformat = "BGRx"
self.BUILD_CONFIG = {
"width": self.width,
"height": self.height,
"latency": self.latency,
"framerate": self.framerate,
"format": self.fformat,
"gstreamer": True
}
self.BUILD_CONFIG.update(buildconfig)
def open_cam_rtsp(self):
gst_str = ('rtspsrc location={uri} latency={latency} ! '
'rtph264depay ! h264parse ! omxh264dec ! '
'nvvidconv ! videorate ! '
'video/x-raw, width=(int){width}, height=(int){height}, '
'format=(string){format}, framerate=(fraction){framerate} ! '
'videoconvert ! appsink').format(**self.BUILD_CONFIG)
print(gst_str)
return cv2.VideoCapture(gst_str, cv2.CAP_GSTREAMER)
def open_cam_usb(self):
# We want to set width and height here, otherwise we could just do:
# return cv2.VideoCapture(dev)
gst_str = ('v4l2src device=/dev/video{uri} ! '
'video/x-raw, width=(int){width}, height=(int){height}, '
'format=(string){format}, framerate=(fraction){framerate} ! '
'videoconvert ! appsink').format(**self.BUILD_CONFIG)
print(gst_str)
return cv2.VideoCapture(gst_str, cv2.CAP_GSTREAMER)
def open_cam_onboard(self):
# On versions of L4T prior to 28.1, add 'flip-method=2' into gst_str
gst_str = ('nvcamerasrc ! '
'video/x-raw(memory:NVMM), '
'width=(int)2592, height=(int)1458, '
'format=(string)I420 ! '
'nvvidconv ! videorate ! '
'video/x-raw, width=(int){width}, height=(int){height}, '
'format=(string){format}, framerate=(fraction){framerate} !'
'videoconvert ! appsink').format(**self.BUILD_CONFIG)
print(gst_str)
return cv2.VideoCapture(gst_str, cv2.CAP_GSTREAMER)
def custom_pipeline(self):
gst_str = "{customGstPipelineString}".format(**self.BUILD_CONFIG)
print(gst_str)
return cv2.VideoCapture(gst_str, cv2.CAP_GSTREAMER)
def build_pipeline(self):
if self.BUILD_CONFIG["gStreamer"]!=True:
if self.BUILD_CONFIG["sourceType"] == "usbcam":
self.cap = cv2.VideoCapture(int(self.BUILD_CONFIG["uri"]))
else:
self.cap = cv2.VideoCapture(self.BUILD_CONFIG["uri"])
elif self.BUILD_CONFIG["sourceType"] == "rtsp":
self.cap = self.open_cam_rtsp()
elif self.BUILD_CONFIG["sourceType"] == "usbcam":
self.cap = self.open_cam_usb()
elif self.BUILD_CONFIG["sourceType"] == "onboard":
self.cap = self.open_cam_onboard()
elif self.BUILD_CONFIG["sourceType"] == "customPipeline":
self.cap = self.custom_pipeline()
else:
raise ValueError("unimplemented source {}".format(self.BUILD_CONFIG["sourceType"]))
def get_stream(self):
return self.cap
from edge_engine.common.logsetup import logger
from edge_engine.streamio.videostream import NVGstreamer
class SimpleVideoStream:
def __init__(self, stream_config, name="SimpleVideoStream"):
self.stream_config = stream_config
self.build_pipeline()
(self.grabbed, self.frame) = self.stream.read()
self.name = name
def build_pipeline(self):
self.gstreamer = NVGstreamer(self.stream_config)
self.gstreamer.build_pipeline()
self.stream = self.gstreamer.get_stream()
def start(self):
logger.info("Starting video stream ")
if self.stream.isOpened():
self.grabbed, self.frame = self.stream.read()
if self.grabbed is False:
logger.error("Empty Frame !!!! ")
logger.error("Error opening Capture !!!! ")
self.build_pipeline()
return self
else:
logger.error("Error opening Capture !!!! ")
self.build_pipeline()
def is_opened(self):
return self.stream.isOpened()
def read(self):
# return the frame most recently read
if self.stream.isOpened():
self.grabbed, self.frame = self.stream.read()
if self.grabbed is False:
logger.error("Empty Frame !!!! ")
raise ValueError("Empty Frame !!!! ")
return self.frame
else:
logger.error("Error opening Capture !!!! ")
raise ValueError("Error opening Capture !!!! ")
def stop(self):
if self.stream.isOpened():
self.stream.release()
# import the necessary packages
from threading import Thread
import time
from edge_engine.streamio.videostream import NVGstreamer
from edge_engine.common.logsetup import logger
class ThreadedVideoStream:
def __init__(self, stream_config, name="ThreadedVideoStream"):
# initialize the video camera stream and read the first frame
# from the stream
self.stream_config = stream_config
self.build_pipeline()
# self.stream = stream
(self.grabbed, self.frame) = self.stream.read()
# initialize the thread name
self.name = name
# initialize the variable used to indicate if the thread should
# be stopped
self.stopped = False
def build_pipeline(self):
self.gstreamer = NVGstreamer(self.stream_config)
self.gstreamer.build_pipeline()
self.stream = self.gstreamer.get_stream()
def start(self):
# start the thread to read frames from the video stream
t = Thread(target=self.update, name=self.name, args=())
t.daemon = True
t.start()
return self
def update(self):
# keep looping infinitely until the thread is stopped
while True:
# if the thread indicator variable is set, stop the thread
if self.stopped:
return
# otherwise, read the next frame from the stream
(self.grabbed, self.frame) = self.stream.read()
if self.grabbed is False or self.frame is None:
logger.error("Empty Frame !!!! ")
logger.error("Error opening Capture !!!! ")
self.build_pipeline()
def read(self):
# return the frame most recently read
return self.frame
def stop(self):
# indicate that the thread should be stopped
self.stopped = True
time.sleep(0.2)
self.stream.release()
# Copyright 2019 KnowledgeLens pvt Ltd.
VERSION = '0.0.1.alpha'
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
opencv-python==4.5.5.62
pycuda==2020.1
numpy==1.19.4
requests>=2.23.0
expiringdict==1.2.1
minio==7.1.3
cachetools==4.2.4
pymongo==4.0.1
Cython==0.29.21
paho-mqtt==1.5.0
scikit-learn==0.22.2.post1
python-dateutil==2.8.2
imutils==0.5.4
\ No newline at end of file
from.cement_counter import CementBagCounter
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
import os
import sys
import json
from pymongo import MongoClient
MAIN_OS_VARIABLE = json.loads(os.environ.get('config'))
if MAIN_OS_VARIABLE is None:
sys.stderr.write("Configuration not found...")
sys.stderr.write("Exiting....")
sys.exit(1)
MONGO_URI = MAIN_OS_VARIABLE.get('MONGO_URI')
MONGO_SERVICE_DB = MAIN_OS_VARIABLE.get('MONGO_DB')
MONGO_SERVICE_COLL = MAIN_OS_VARIABLE.get('MONGO_COLL')
PASS_KEY = MAIN_OS_VARIABLE.get('PASS_KEY')
MONGO_DB_OBJ = MongoClient(MONGO_URI)[MONGO_SERVICE_DB]
HOST_CONFIG = MONGO_DB_OBJ[MONGO_SERVICE_COLL].find_one({'configId': 'hostConfig'}).get('config')
APP_MONGO_COLLECTION = MONGO_DB_OBJ[MONGO_SERVICE_COLL].find_one({'configId': 'appMongoConfig'}).get('config')
class JanusDeploymentConstants:
JANUS_DEPLOYMENT_COLLECTION = "janusDeploymentConfigurations"
DEPLOYMENT_ID = 'deploymentId'
EXTRA_FIELDS_KEY = 'extra_fields'
LINE_COORDINATES = ['x1', 'y1', 'x2', 'y2']
COUNT_BAGS_FLAG = 'count_bags'
ALIGNMENT_KEY = 'alignment'
VERTICAL = 'vertical'
HORIZONTAL = 'horizontal'
MODEL_KEY = 'model'
DIRECTION_KEY = 'direction'
MRP_DETECT_KEY = 'mrp_detect'
class CameraConstants:
videortpmap="VP8/90000"
videopt=96
threads=3
gStreamer = False
eventType = 'deploy'
created_by = 'user_6501'
event_status = 'pending'
deploymentTypeCreate = 'upgrade_and_deploy'
deploymentTypeRemove = 'remove'
pipeline_internal = {}
pipeline_category = "ai"
thread = 1
job_id = "pipeline_129"
deployment_key = 'deploymentId'
pipeline_deployment_type = 'docker'
docker_deployment_type = 'single'
command_eventtype = 'command'
command_type = 'docker'
restart_command = "restart_container"
stop_command = "stop_container"
start_command = "start_container"
from edge_engine.ai.model.modelwraper import ModelWrapper
import cv2
import base64
class LoopBackModel(ModelWrapper):
def __init__(self, pubs, path=None, ):
super().__init__(path)
self.mqtt = pubs.mqtt_pub
def _pre_process(self, x):
return x
def _post_process(self, x):
image = cv2.imencode('.jpg', x['frame'])[1].tostring()
image = 'data:image/jpeg;base64,' + base64.b64encode(image).decode("utf-8")
x['frame'] = image
self.mqtt.publish(x)
return x
def _predict(self, x):
return x
def predict(self, x):
return super().predict(x)
# import the necessary packages
from scipy.spatial import distance as dist
from collections import OrderedDict
import numpy as np
from edge_engine.common.logsetup import logger
class CentroidTracker():
def __init__(self, maxDisappeared=50):
# initialize the next unique object ID along with two ordered
# dictionaries used to keep track of mapping a given object
# ID to its centroid and number of consecutive frames it has
# been marked as "disappeared", respectively
self.nextObjectID = 0
self.objects = OrderedDict()
self.disappeared = OrderedDict()
# store the number of maximum consecutive frames a given
# object is allowed to be marked as "disappeared" until we
# need to deregister the object from tracking
self.maxDisappeared = maxDisappeared
def register(self, centroid):
# when registering an object we use the next available object
# ID to store the centroid
self.objects[self.nextObjectID] = {'has_print': False, 'centroid': centroid}
self.disappeared[self.nextObjectID] = 0
self.nextObjectID += 1
def deregister(self, objectID):
# to deregister an object ID we delete the object ID from
# both of our respective dictionaries
del self.objects[objectID]
del self.disappeared[objectID]
def update(self, rects):
# check to see if the list of input bounding box rectangles
# is empty
if len(rects) == 0:
# loop over any existing tracked objects and mark them
# as disappeared
for objectID in list(self.disappeared.keys()):
self.disappeared[objectID] += 1
# if we have reached a maximum number of consecutive
# frames where a given object has been marked as
# missing, deregister it
if self.disappeared[objectID] > self.maxDisappeared:
self.deregister(objectID)
# return early as there are no centroids or tracking info
# to update
return self.objects
# initialize an array of input centroids for the current frame
inputCentroids = np.zeros((len(rects), 2), dtype="int")
# loop over the bounding box rectangles
for (i, (startX, startY, endX, endY)) in enumerate(rects):
# use the bounding box coordinates to derive the centroid
cX = int((startX + endX) / 2.0)
cY = int((startY + endY) / 2.0)
inputCentroids[i] = (cX, cY)
# if we are currently not tracking any objects take the input
# centroids and register each of them
if len(self.objects) == 0:
for i in range(0, len(inputCentroids)):
self.register(inputCentroids[i])
# otherwise, are are currently tracking objects so we need to
# try to match the input centroids to existing object
# centroids
else:
# grab the set of object IDs and corresponding centroids
objectIDs = list(self.objects.keys())
objectCentroids = [e['centroid'] for e in self.objects.values()]
# compute the distance between each pair of object
# centroids and input centroids, respectively -- our
# goal will be to match an input centroid to an existing
# object centroid
# logger.info(f"OBC --> {objectCentroids}")
try:
D = dist.cdist(np.array(objectCentroids), inputCentroids)
except Exception as e:
logger.info(f"objectCentroids --> {objectCentroids}")
logger.info(f"inputCentroids --> {inputCentroids}")
logger.exception(e)
# in order to perform this matching we must (1) find the
# smallest value in each row and then (2) sort the row
# indexes based on their minimum values so that the row
# with the smallest value as at the *front* of the index
# list
rows = D.min(axis=1).argsort()
# next, we perform a similar process on the columns by
# finding the smallest value in each column and then
# sorting using the previously computed row index list
cols = D.argmin(axis=1)[rows]
# in order to determine if we need to update, register,
# or deregister an object we need to keep track of which
# of the rows and column indexes we have already examined
usedRows = set()
usedCols = set()
# loop over the combination of the (row, column) index
# tuples
for (row, col) in zip(rows, cols):
# if we have already examined either the row or
# column value before, ignore it
# val
if row in usedRows or col in usedCols:
continue
# otherwise, grab the object ID for the current row,
# set its new centroid, and reset the disappeared
# counter
objectID = objectIDs[row]
self.objects[objectID]['centroid'] = inputCentroids[col]
self.disappeared[objectID] = 0
# indicate that we have examined each of the row and
# column indexes, respectively
usedRows.add(row)
usedCols.add(col)
# compute both the row and column index we have NOT yet
# examined
unusedRows = set(range(0, D.shape[0])).difference(usedRows)
unusedCols = set(range(0, D.shape[1])).difference(usedCols)
# in the event that the number of object centroids is
# equal or greater than the number of input centroids
# we need to check and see if some of these objects have
# potentially disappeared
if D.shape[0] >= D.shape[1]:
# loop over the unused row indexes
for row in unusedRows:
# grab the object ID for the corresponding row
# index and increment the disappeared counter
objectID = objectIDs[row]
self.disappeared[objectID] += 1
# check to see if the number of consecutive
# frames the object has been marked "disappeared"
# for warrants deregistering the object
if self.disappeared[objectID] > self.maxDisappeared:
self.deregister(objectID)
# otherwise, if the number of input centroids is greater
# than the number of existing object centroids we need to
# register each new input centroid as a trackable object
else:
for col in unusedCols:
self.register(inputCentroids[col])
# return the set of trackable objects
return self.objects
from scripts.common.constants import JanusDeploymentConstants
from scripts.common.config import MONGO_DB_OBJ, APP_MONGO_COLLECTION
import cv2
from edge_engine.common.logsetup import logger
#from scripts.common.config import MONGO_DB_OBJ, APP_MONGO_COLLECTION
#from scripts.common.constants import JanusDeploymentConstants
class Utilities:
@classmethod
def get_extra_fields(
cls,
device_id,
):
_janus_deployment = MONGO_DB_OBJ[
APP_MONGO_COLLECTION.get(JanusDeploymentConstants.JANUS_DEPLOYMENT_COLLECTION)].find_one(
{JanusDeploymentConstants.DEPLOYMENT_ID: device_id}).get(
JanusDeploymentConstants.EXTRA_FIELDS_KEY)
if _janus_deployment is None:
raise ValueError("Janus deployment configuration is not found/corrupted")
_key_dictionary = dict()
for each_field in _janus_deployment:
_key_dictionary[each_field['key']] = each_field['value']
return _key_dictionary
@classmethod
def get_direction(
cls,
device_id,
):
logger.debug("Getting the direction from DB")
return MONGO_DB_OBJ[APP_MONGO_COLLECTION.get(JanusDeploymentConstants.JANUS_DEPLOYMENT_COLLECTION)].find_one(
{JanusDeploymentConstants.DEPLOYMENT_ID: device_id}).get(
JanusDeploymentConstants.DIRECTION_KEY)
@classmethod
def set_direction(
cls,
device_id: str,
direction: bool,
):
logger.debug("Updating the direction in DB")
updated_values = {"$set": {JanusDeploymentConstants.DIRECTION_KEY: direction}}
MONGO_DB_OBJ[APP_MONGO_COLLECTION.get(JanusDeploymentConstants.JANUS_DEPLOYMENT_COLLECTION)].update_one(
{JanusDeploymentConstants.DEPLOYMENT_ID: device_id}, updated_values)
@classmethod
def draw_circles_on_frame(
cls,
frame,
point,
radius=3,
color=(255, 255, 255),
thickness=1,
):
"""
draw circle on the objects
:param radius: radius of the circle
:param frame: frame to draw on
:param point: co-ordinate to draw on
:param color: color of the circle
:param thickness: thickness of the circle
:return: frame
"""
return cv2.circle(frame, tuple(point), radius, color, thickness)
@classmethod
def resize_to_64_64(
cls,
frame,
):
"""
resize the from
:param frame: frame
:return: frame
"""
return cv2.resize(frame, (64, 64))
def get_extra_fields(device_id):
# _janus_deployment = [
# {
# "type": "number",
# "key": "x1",
# "value": 1000
# },
# {
# "type": "number",
# "key": "y1",
# "value": 0
# },
# {
# "type": "number",
# "key": "x2",
# "value": 1001
# },
# {
# "type": "number",
# "key": "y2",
# "value": 720
# },
# {
# "type": "dropdown",
# "key": "alignment",
# "value": "vertical"
# }
# ]
_janus_deployment = MONGO_DB_OBJ[APP_MONGO_COLLECTION.get(JanusDeploymentConstants.JANUS_DEPLOYMENT_COLLECTION)]. \
find_one({JanusDeploymentConstants.DEPLOYMENT_ID: device_id}).get(JanusDeploymentConstants.EXTRA_FIELDS_KEY)
if _janus_deployment is None:
raise ValueError("Janus deployment configuration is not found/corrupted")
_key_dictionary = dict()
for each_field in _janus_deployment:
_key_dictionary[each_field['key']] = each_field['value']
return _key_dictionary
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
Created on Tue Jun 20 14:51:33 2017
@author: kyleguan
"""
import numpy as np
import cv2
class Box:
def __init__(self):
self.x, self.y = float(), float()
self.w, self.h = float(), float()
self.c = float()
self.prob = float()
def overlap(x1, w1, x2, w2):
l1 = x1 - w1 / 2.;
l2 = x2 - w2 / 2.;
left = max(l1, l2)
r1 = x1 + w1 / 2.;
r2 = x2 + w2 / 2.;
right = min(r1, r2)
return right - left;
def box_intersection(a, b):
w = overlap(a.x, a.w, b.x, b.w);
h = overlap(a.y, a.h, b.y, b.h);
if w < 0 or h < 0: return 0;
area = w * h;
return area;
def box_union(a, b):
i = box_intersection(a, b);
u = a.w * a.h + b.w * b.h - i;
return u;
def box_iou(a, b):
return box_intersection(a, b) / box_union(a, b);
def box_iou2(a, b):
'''
Helper funciton to calculate the ratio between intersection and the union of
two boxes a and b
a[0], a[1], a[2], a[3] <-> left, up, right, bottom
'''
w_intsec = np.maximum(0, (np.minimum(a[2], b[2]) - np.maximum(a[0], b[0])))
h_intsec = np.maximum(0, (np.minimum(a[3], b[3]) - np.maximum(a[1], b[1])))
s_intsec = w_intsec * h_intsec
s_a = (a[2] - a[0]) * (a[3] - a[1])
s_b = (b[2] - b[0]) * (b[3] - b[1])
return float(s_intsec) / (s_a + s_b - s_intsec)
def convert_to_pixel(box_yolo, img, crop_range):
'''
Helper function to convert (scaled) coordinates of a bounding box
to pixel coordinates.
Example (0.89361443264143803, 0.4880486045564924, 0.23544462956491041,
0.36866588651069609)
crop_range: specifies the part of image to be cropped
'''
box = box_yolo
imgcv = img
[xmin, xmax] = crop_range[0]
[ymin, ymax] = crop_range[1]
h, w, _ = imgcv.shape
# Calculate left, top, width, and height of the bounding box
left = int((box.x - box.w / 2.) * (xmax - xmin) + xmin)
top = int((box.y - box.h / 2.) * (ymax - ymin) + ymin)
width = int(box.w * (xmax - xmin))
height = int(box.h * (ymax - ymin))
# Deal with corner cases
if left < 0: left = 0
if top < 0: top = 0
# Return the coordinates (in the unit of the pixels)
box_pixel = np.array([left, top, width, height])
return box_pixel
def convert_to_cv2bbox(bbox, img_dim=(1280, 720)):
'''
Helper fucntion for converting bbox to bbox_cv2
bbox = [left, top, width, height]
bbox_cv2 = [left, top, right, bottom]
img_dim: dimension of the image, img_dim[0]<-> x
img_dim[1]<-> y
'''
left = np.maximum(0, bbox[0])
top = np.maximum(0, bbox[1])
right = np.minimum(img_dim[0], bbox[0] + bbox[2])
bottom = np.minimum(img_dim[1], bbox[1] + bbox[3])
return (left, top, right, bottom)
def draw_box_label(id, img, bbox_cv2, box_color=(0, 255, 255), show_label=True):
'''
Helper funciton for drawing the bounding boxes and the labels
bbox_cv2 = [left, top, right, bottom]
'''
# box_color= (0, 255, 255)
font = cv2.FONT_HERSHEY_SIMPLEX
font_size = 0.7
font_color = (0, 0, 0)
left, top, right, bottom = bbox_cv2[1], bbox_cv2[0], bbox_cv2[3], bbox_cv2[2]
# Draw the bounding box
cv2.rectangle(img, (left, top), (right, bottom), box_color, 4)
# centroid = [int(left+((right - left)/2)), int(top+((bottom - top)/2))]
if show_label:
# Draw a filled box on top of the bounding box (as the background for the labels)
cv2.rectangle(img, (left - 2, top - 45), (right + 2, top), box_color, -1, 1)
# Output the labels that show the x and y coordinates of the bounding box center.
text_x = 'id=' + str(id)
cv2.putText(img, text_x, (left, top - 25), font, font_size, font_color, 1, cv2.LINE_AA)
text_y = 'y=' + str((top + bottom) / 2)
# cv2.putText(img, text_y, (left, top - 5), font, font_size, font_color, 1, cv2.LINE_AA)
return img
import os
import requests
GENERATED_TOKEN_KEY = "model_container_pregenerated_token"
LOGIN_TOKEN_KEY = "login-token"
def delete(**kwargs):
if os.environ.get(GENERATED_TOKEN_KEY):
cookies = headers = {LOGIN_TOKEN_KEY: os.environ.get(GENERATED_TOKEN_KEY)}
kwargs.update(dict(cookies=cookies, headers=headers))
return requests.delete(**kwargs)
def get(**kwargs):
if os.environ.get(GENERATED_TOKEN_KEY):
cookies = headers = {LOGIN_TOKEN_KEY: os.environ.get(GENERATED_TOKEN_KEY)}
kwargs.update(dict(cookies=cookies, headers=headers))
return requests.get(**kwargs)
def head(**kwargs):
if os.environ.get(GENERATED_TOKEN_KEY):
cookies = headers = {LOGIN_TOKEN_KEY: os.environ.get(GENERATED_TOKEN_KEY)}
kwargs.update(dict(cookies=cookies, headers=headers))
return requests.head(**kwargs)
def patch(**kwargs):
if os.environ.get(GENERATED_TOKEN_KEY):
cookies = headers = {LOGIN_TOKEN_KEY: os.environ.get(GENERATED_TOKEN_KEY)}
kwargs.update(dict(cookies=cookies, headers=headers))
return requests.patch(**kwargs)
def post(**kwargs):
if os.environ.get(GENERATED_TOKEN_KEY):
cookies = headers = {LOGIN_TOKEN_KEY: os.environ.get(GENERATED_TOKEN_KEY)}
kwargs.update(dict(cookies=cookies, headers=headers))
return requests.post(**kwargs)
def put(**kwargs):
if os.environ.get(GENERATED_TOKEN_KEY):
cookies = headers = {LOGIN_TOKEN_KEY: os.environ.get(GENERATED_TOKEN_KEY)}
kwargs.update(dict(cookies=cookies, headers=headers))
return requests.put(**kwargs)
from edge_engine.common.logsetup import logger
import cv2
def draw_circles_on_frame(frame, point, radius=3, color=(255, 255, 255), thickness=1):
"""
draw circle on the objects
:param radius: radius of the circle
:param frame: frame to draw on
:param point: co-ordinate to draw on
:param color: color of the circle
:param thickness: thickness of the circle
:return: frame
"""
logger.debug("Drawing circle centroid on the frame")
return cv2.circle(frame, tuple(point), radius, color, thickness)
def resize_to_64_64(frame):
"""
resize the from
:param frame: frame
:return: frame
"""
logger.debug("Resizing the frame to 64 x 64")
return cv2.resize(frame, (64, 64))
\ No newline at end of file
import os
from datetime import datetime
# Security changes start
# from requests import post
from scripts.utils.ilens_request_handler import post
# Security changes stop
from uuid import uuid1
from urllib.parse import urljoin
from edge_engine.common.logsetup import logger
from scripts.common.config import MONGO_DB_OBJ, APP_MONGO_COLLECTION
class MongoLogger:
def __init__(self):
self.attendance_event_collection = MONGO_DB_OBJ[APP_MONGO_COLLECTION.get('eventLogCollection')]
self.camera_configuration = MONGO_DB_OBJ[APP_MONGO_COLLECTION.get('cameraConfigurationCollection')]
self.camera_mapping_json = self.get_all_cameras()
def get_all_cameras(self):
camera_mapping_json = self.camera_configuration.find({'decommissioned': False}, {"_id": 0})
camera_json = {}
for each in camera_mapping_json:
camera_json[each['cameraId']] = each['cameraName']
return camera_json
@staticmethod
def update_count_api(bag_type):
asset_id = os.environ.get('asset_id')
asset_hierarchy = os.environ.get('asset_hierarchy')
count_update_endpoint = os.environ.get('count_update_endpoint')
logger.debug("count_update_endpoint",count_update_endpoint)
if asset_id is not None and count_update_endpoint is not None and asset_hierarchy is not None:
response = post(url=count_update_endpoint,
json=dict(asset_hierarchy=asset_hierarchy, count_increment=1, asset_id=asset_id,
bag_type=bag_type), timeout=5)
if response.status_code != 200:
logger.warning(
"Value not updated in cards!. Invalid response from Update Count API: {}".format(response.content))
else:
logger.warning("Either asset_id, asset_hierarchy or count_update_endpoint is not set!."
" Not updating the cards API!")
def insert_attendance_event_to_mongo(self, data):
try:
input_data = {
"eventId": str(uuid1()).split('-')[0],
"cameraId": data['deviceId'],
"cameraName": self.camera_mapping_json.get(data['deviceId'], "Thermal Camera"),
"timestamp": datetime.now(),
"frame": data['frame'],
"eventtype": "Intrusion Detection",
"bg_color": data["bg_color"],
"font_color": data["font_color"],
"intrusion_message": data["message"],
"alert_sound": data["alert_sound"],
"logged_activity": data["activity"],
"mrp_frmae": data["mrp_frmae"],
"mrp_roi": data["mrp_roi"]}
if os.environ.get('app') is not None:
input_data['app'] = os.environ.get('app')
logger.info("Pushing to Mongo..")
self.attendance_event_collection.insert_one(input_data)
self.update_count_api(data["bag_type"])
except Exception as e:
logger.exception(e)
def get_camera_details(self, camera_id):
camera_details_json = self.camera_configuration.find_one({"cameraId": camera_id})
return camera_details_json
from datetime import datetime
from scripts.common.config import MONGO_DB_OBJ
class ModelCountTracker:
def __init__(
self,
device_id,
) -> None:
self.device_id = device_id
self.count_tracker = None
self._reset_tracker()
def _reset_tracker(self):
self.count_tracker = list()
def __call__(
self,
conf: float,
) -> None:
self.count_tracker.append(
{
"time": datetime.now(),
"deviceId": self.device_id,
"count_confidence": conf
})
if len(self.count_tracker) >= 10:
self.insert_to_mongo(self.count_tracker)
self._reset_tracker()
@staticmethod
def insert_to_mongo(
payload: list,
collection_name: str = "model_count_tracker"
) -> None:
MONGO_DB_OBJ[collection_name].insert_many(payload)
class ModelTracker:
def __init__(
self,
device_id,
) -> None:
self.device_id = device_id
self.model_tracker = None
self._reset_tracker()
def _reset_tracker(self):
self.model_tracker = list()
def __call__(
self,
conf: float,
) -> None:
self.model_tracker.append(
{
"time": datetime.now(),
"deviceId": self.device_id,
"model_confidence": conf
})
if len(self.model_tracker) >= 500:
self.insert_to_mongo(self.model_tracker)
self._reset_tracker()
@staticmethod
def insert_to_mongo(
payload: list,
collection_name: str = "model_confidence_tracker"
) -> None:
MONGO_DB_OBJ[collection_name].insert_many(payload)
import time
import requests
from edge_engine.common.logsetup import logger
class RelayHandler:
@staticmethod
def update_relay_status(
ep: str,
payload: dict,
) -> None:
logger.debug("Updating the relay status to : {}".format(payload))
response = None
for _ in range(0, 3):
response = requests.post(url=ep, json=payload, timeout=10)
if response.status_code == 200 and response.json().get('status'):
return
time.sleep(1)
logger.error("Unable to update the relay status. Error: {}".format(response.content))
raise RuntimeError("Unable to communicate to belt relay!")
\ No newline at end of file
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
import numpy as np
from numpy import dot
from scipy.linalg import inv, block_diag
class Tracker(): # class for Kalman Filter based tracker
def __init__(self):
# Initialize parametes for tracker (history)
self.id = 0 # tracker's id
self.box = [] # list to store the coordinates for a bounding box
self.hits = 0 # number of detection matches
self.no_losses = 0 # number of unmatched tracks (track loss)
# Initialize parameters for Kalman Filtering
# The state is the (x, y) coordinates of the detection box
# state: [up, up_dot, left, left_dot, down, down_dot, right, right_dot]
# or[up, up_dot, left, left_dot, height, height_dot, width, width_dot]
self.x_state = []
self.dt = 1. # time interval
# Process matrix, assuming constant velocity model
self.F = np.array([[1, self.dt, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 1, self.dt, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 1, self.dt, 0, 0],
[0, 0, 0, 0, 0, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 1, self.dt],
[0, 0, 0, 0, 0, 0, 0, 1]])
# Measurement matrix, assuming we can only measure the coordinates
self.H = np.array([[1, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 1, 0]])
# Initialize the state covariance
self.L = 100.0
self.P = np.diag(self.L * np.ones(8))
# Initialize the process covariance
self.Q_comp_mat = np.array([[self.dt ** 4 / 2., self.dt ** 3 / 2.],
[self.dt ** 3 / 2., self.dt ** 2]])
self.Q = block_diag(self.Q_comp_mat, self.Q_comp_mat,
self.Q_comp_mat, self.Q_comp_mat)
# Initialize the measurement covariance
self.R_ratio = 1.0 / 16.0
self.R_diag_array = self.R_ratio * np.array([self.L, self.L, self.L, self.L])
self.R = np.diag(self.R_diag_array)
def update_R(self):
R_diag_array = self.R_ratio * np.array([self.L, self.L, self.L, self.L])
self.R = np.diag(R_diag_array)
def kalman_filter(self, z):
'''
Implement the Kalman Filter, including the predict and the update stages,
with the measurement z
'''
x = self.x_state
# Predict
x = dot(self.F, x)
self.P = dot(self.F, self.P).dot(self.F.T) + self.Q
# Update
S = dot(self.H, self.P).dot(self.H.T) + self.R
K = dot(self.P, self.H.T).dot(inv(S)) # Kalman gain
y = z - dot(self.H, x) # residual
x += dot(K, y)
self.P = self.P - dot(K, self.H).dot(self.P)
self.x_state = x.astype(int) # convert to integer coordinates
# (pixel values)
def predict_only(self):
'''
Implment only the predict stage. This is used for unmatched detections and
unmatched tracks
'''
x = self.x_state
# Predict
x = dot(self.F, x)
self.P = dot(self.F, self.P).dot(self.F.T) + self.Q
self.x_state = x.astype(int)
if __name__ == "__main__":
import matplotlib.pyplot as plt
import glob
import helpers
# Creat an instance
trk = Tracker()
# Test R_ratio
trk.R_ratio = 1.0 / 16
# Update measurement noise covariance matrix
trk.update_R()
# Initial state
x_init = np.array([390, 0, 1050, 0, 513, 0, 1278, 0])
x_init_box = [x_init[0], x_init[2], x_init[4], x_init[6]]
# Measurement
z = np.array([399, 1022, 504, 1256])
trk.x_state = x_init.T
trk.kalman_filter(z.T)
# Updated state
x_update = trk.x_state
x_updated_box = [x_update[0], x_update[2], x_update[4], x_update[6]]
print('The initial state is: ', x_init)
print('The measurement is: ', z)
print('The update state is: ', x_update)
# Visualize the Kalman filter process and the
# impact of measurement nosie convariance matrix
images = [plt.imread(file) for file in glob.glob('./test_images/*.jpg')]
img = images[3]
plt.figure(figsize=(10, 14))
helpers.draw_box_label(img, x_init_box, box_color=(0, 255, 0))
ax = plt.subplot(3, 1, 1)
plt.imshow(img)
plt.title('Initial: ' + str(x_init_box))
helpers.draw_box_label(img, z, box_color=(255, 0, 0))
ax = plt.subplot(3, 1, 2)
plt.imshow(img)
plt.title('Measurement: ' + str(z))
helpers.draw_box_label(img, x_updated_box)
ax = plt.subplot(3, 1, 3)
plt.imshow(img)
plt.title('Updated: ' + str(x_updated_box))
plt.show()
This diff is collapsed.
black_white_ratio_dict = {'ambuja_plus': 1.2, 'acc_gold': 1.2, 'acc_suraksha_power_plus': 1.2, 'ambuja_buildcem': 1.2, 'acc_suraksha_power': 1.2, 'acc_nfr': 1.2, 'acc_concrete_plus': 1.2}
lack_white_ratio = black_white_ratio_dict["{class_name}".format(class_name="ambuja_plus")]
print(lack_white_ratio)
\ No newline at end of file
from os import environ
environ["config"] = '{"MONGO_URI": "mongodb://admin:iLens!8989@192.168.0.220:21017", "MONGO_DATABASE": "ilens_wps", ' \
'"MONGO_DB": "ilens_wps","MONGO_COLLECTION": "janusDeployment", "MONGO_KEY": "deploymentId", ' \
'"MONGO_VALUE": "1b180a0e", "MONGO_SERVICE_COLL": "serviceConfiguration", "MONGO_COLL": ' \
'"serviceConfiguration" } '
import unittest
from edge_engine.edge_processor import Pubs
from edge_engine.common.config import EDGE_CONFIG
from scripts.cement_counter import CementBagCounter
class TestCementBagCounter(unittest.TestCase):
def test__pre_process(self):
self.assertEqual(CementBagCounter(config=EDGE_CONFIG, model_config=EDGE_CONFIG["modelConfig"], pubs=Pubs(),
device_id=EDGE_CONFIG['deviceId'])._pre_process("5"), '5')
import torch
import numpy as np
from numpy import random
from yolov5processor.models.experimental import attempt_load
from yolov5processor.utils.datasets import letterbox
from yolov5processor.utils.general import (check_img_size, non_max_suppression, scale_coords)
from yolov5processor.utils.torch_utils import select_device
class ExecuteInference:
def __init__(self, weight, confidence=0.4, img_size=640, agnostic_nms=False, gpu=False, iou=0.5):
self.weight = weight
self.confidence = confidence
self.gpu = gpu
self.iou = iou
self.agnostic_nms = agnostic_nms
self.img_size = img_size
self.device, self.half = self.inference_device()
self.classes, self.model, self.names, self.colors = self.load_model()
print("Loaded Models...")
def inference_device(self):
if self.gpu:
device = select_device(str(torch.cuda.current_device()))
print("Using GPU Resource(s): {}".format(str(torch.cuda.current_device())))
else:
device = select_device('cpu')
print("Using CPU Resources")
half = device.type != 'cpu'
return device, half
def load_model(self):
model = attempt_load(self.weight, map_location=self.device)
imgsz = check_img_size(self.img_size, s=model.stride.max())
if self.half:
model.half()
names = model.module.names if hasattr(model, 'module') else model.names
print("Yolo v5 Model Classes: {}".format(names))
colors = [[random.randint(0, 255) for _ in range(3)] for _ in range(len(names))]
img = torch.zeros((1, 3, imgsz, imgsz), device=self.device)
_ = model(img.half() if self.half else img) if self.device.type != 'cpu' else None
class_map = {index: label for index, label in zip(range(len(names)), names)}
return class_map, model, names, colors
def predict(self, image):
img = letterbox(image, new_shape=self.img_size)[0]
img = img[:, :, ::-1].transpose(2, 0, 1)
img = np.ascontiguousarray(img)
img = torch.from_numpy(img).to(self.device)
img = img.half() if self.half else img.float()
img /= 255.0
if img.ndimension() == 3:
img = img.unsqueeze(0)
pred = self.model(img, augment=False)[0]
pred = non_max_suppression(pred, self.confidence, self.iou, classes=None, agnostic=self.agnostic_nms)
_output = list()
for i, det in enumerate(pred):
if det is not None and len(det):
det[:, :4] = scale_coords(img.shape[2:], det[:, :4], image.shape).round()
for *xyxy, conf, cls in reversed(det):
_output.append({"points": [int(each) for each in xyxy],
"conf": round(float(conf), 4),
"class": self.classes[int(cls)]})
return _output
This diff is collapsed.
This diff is collapsed.
# YOLOv5 🚀 by Ultralytics, GPL-3.0 license
# Default anchors for COCO data
# P5 -------------------------------------------------------------------------------------------------------------------
# P5-640:
anchors_p5_640:
- [10,13, 16,30, 33,23] # P3/8
- [30,61, 62,45, 59,119] # P4/16
- [116,90, 156,198, 373,326] # P5/32
# P6 -------------------------------------------------------------------------------------------------------------------
# P6-640: thr=0.25: 0.9964 BPR, 5.54 anchors past thr, n=12, img_size=640, metric_all=0.281/0.716-mean/best, past_thr=0.469-mean: 9,11, 21,19, 17,41, 43,32, 39,70, 86,64, 65,131, 134,130, 120,265, 282,180, 247,354, 512,387
anchors_p6_640:
- [9,11, 21,19, 17,41] # P3/8
- [43,32, 39,70, 86,64] # P4/16
- [65,131, 134,130, 120,265] # P5/32
- [282,180, 247,354, 512,387] # P6/64
# P6-1280: thr=0.25: 0.9950 BPR, 5.55 anchors past thr, n=12, img_size=1280, metric_all=0.281/0.714-mean/best, past_thr=0.468-mean: 19,27, 44,40, 38,94, 96,68, 86,152, 180,137, 140,301, 303,264, 238,542, 436,615, 739,380, 925,792
anchors_p6_1280:
- [19,27, 44,40, 38,94] # P3/8
- [96,68, 86,152, 180,137] # P4/16
- [140,301, 303,264, 238,542] # P5/32
- [436,615, 739,380, 925,792] # P6/64
# P6-1920: thr=0.25: 0.9950 BPR, 5.55 anchors past thr, n=12, img_size=1920, metric_all=0.281/0.714-mean/best, past_thr=0.468-mean: 28,41, 67,59, 57,141, 144,103, 129,227, 270,205, 209,452, 455,396, 358,812, 653,922, 1109,570, 1387,1187
anchors_p6_1920:
- [28,41, 67,59, 57,141] # P3/8
- [144,103, 129,227, 270,205] # P4/16
- [209,452, 455,396, 358,812] # P5/32
- [653,922, 1109,570, 1387,1187] # P6/64
# P7 -------------------------------------------------------------------------------------------------------------------
# P7-640: thr=0.25: 0.9962 BPR, 6.76 anchors past thr, n=15, img_size=640, metric_all=0.275/0.733-mean/best, past_thr=0.466-mean: 11,11, 13,30, 29,20, 30,46, 61,38, 39,92, 78,80, 146,66, 79,163, 149,150, 321,143, 157,303, 257,402, 359,290, 524,372
anchors_p7_640:
- [11,11, 13,30, 29,20] # P3/8
- [30,46, 61,38, 39,92] # P4/16
- [78,80, 146,66, 79,163] # P5/32
- [149,150, 321,143, 157,303] # P6/64
- [257,402, 359,290, 524,372] # P7/128
# P7-1280: thr=0.25: 0.9968 BPR, 6.71 anchors past thr, n=15, img_size=1280, metric_all=0.273/0.732-mean/best, past_thr=0.463-mean: 19,22, 54,36, 32,77, 70,83, 138,71, 75,173, 165,159, 148,334, 375,151, 334,317, 251,626, 499,474, 750,326, 534,814, 1079,818
anchors_p7_1280:
- [19,22, 54,36, 32,77] # P3/8
- [70,83, 138,71, 75,173] # P4/16
- [165,159, 148,334, 375,151] # P5/32
- [334,317, 251,626, 499,474] # P6/64
- [750,326, 534,814, 1079,818] # P7/128
# P7-1920: thr=0.25: 0.9968 BPR, 6.71 anchors past thr, n=15, img_size=1920, metric_all=0.273/0.732-mean/best, past_thr=0.463-mean: 29,34, 81,55, 47,115, 105,124, 207,107, 113,259, 247,238, 222,500, 563,227, 501,476, 376,939, 749,711, 1126,489, 801,1222, 1618,1227
anchors_p7_1920:
- [29,34, 81,55, 47,115] # P3/8
- [105,124, 207,107, 113,259] # P4/16
- [247,238, 222,500, 563,227] # P5/32
- [501,476, 376,939, 749,711] # P6/64
- [1126,489, 801,1222, 1618,1227] # P7/128
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment