diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..6a01bf659aacf6d1f9846b5263f6f8e7b40aa253 --- /dev/null +++ b/.gitignore @@ -0,0 +1,163 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide +.pdm.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +.idea/ +resources +images + diff --git a/Dockerfiles b/Dockerfiles new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/README.md b/README.md index 60d0b2196c58eaf02bab152307971b1f34006f53..c10c8c5f41c764af63249be396f57b432be0e034 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,126 @@ ---- -title: Weapon Detection -emoji: 😻 -colorFrom: purple -colorTo: pink -sdk: streamlit -sdk_version: 1.32.2 -app_file: app.py -pinned: false -license: apache-2.0 ---- - -Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference +# weapon-detection-alert-location-share + +This project focuses on enhancing the security of different places, like public areas and banks, by implementing a +robust gun detection and location-sharing system. The system is designed to capture images from an IP camera +strategically placed within the bank premises. When a captured image contains an identifiable gun, the system takes +appropriate actions, such as sending alerts or sharing the location of the detected firearm. + +1. **Image Capture:** + + Utilizes an IP camera to continuously capture images in real-time within the camera range.Images are processed and + analyzed for potential gun presence. + +2. **Gun Detection:** + + Employs advanced computer vision algorithms for accurate gun detection in captured images. + The system recognizes various types of firearms and distinguishes them from other objects. +3. Alert Systems: + + When a gun is detected, the system triggers immediate alerts. + Alerts can be configured to notify security personnel, law enforcement, and relevant authorities. +4. Location Sharing: + + If a gun is detected, the system captures the location of the incident. + The location information is shared in real-time with designated security personnel and law enforcement agencies. + +## File Structure + +File structure of the project + +```commandline + +β”œβ”€β”€ config +β”‚Β Β  β”œβ”€β”€ config.ini +β”‚Β Β  └── config.yaml +β”œβ”€β”€ examples +β”‚Β Β  β”œβ”€β”€ start_cap.py +β”‚Β Β  └── stop_cap.py +β”œβ”€β”€ images +β”‚Β Β  β”œβ”€β”€ cam_images +β”‚Β Β  └── detected_image +β”‚Β Β  β”œβ”€β”€ img_1.png +β”‚Β Β  └── img.png +β”œβ”€β”€ logs +β”‚Β Β  └── gun_det.log +β”œβ”€β”€ resources +β”‚Β Β  └── models +β”‚Β Β  └── yolov7.pt +β”œβ”€β”€ services +β”‚Β Β  β”œβ”€β”€ entity +β”‚Β Β  β”‚Β Β  └── __init__.py +β”‚Β Β  β”œβ”€β”€ gun_det_service +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ detection_example_cam.py +β”‚Β Β  β”‚Β Β  └── __init__.py +β”‚Β Β  β”œβ”€β”€ image_capture +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ capture_main.py +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ __init__.py +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ main_start_stop.py +β”‚Β Β  β”‚Β Β  └── yolov7_detection_example.py +β”‚Β Β  β”œβ”€β”€ image_load +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ __init__.py +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ main_load.py +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ main_start_stop.py +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ start_load.py +β”‚Β Β  β”‚Β Β  └── stop_load.py +β”‚Β Β  β”œβ”€β”€ __init__.py +β”‚Β Β  └── location_share +β”‚Β Β  └── __init__.py +β”œβ”€β”€ utils +β”‚Β Β  β”œβ”€β”€ __init__.py +β”‚Β Β  β”œβ”€β”€ __pycache__ +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ __init__.cpython-310.pyc +β”‚Β Β  β”‚Β Β  └── settings.cpython-310.pyc +β”‚Β Β  └── settings.py +β”œβ”€β”€ Dockerfiles +β”œβ”€β”€ main.py +β”œβ”€β”€ README.md +β”œβ”€β”€ requirements.txt +└── visualization + + +``` + +## How to Run + +1. **Clone the repository:** + ```bash + git clone https://github.com/ishworrsubedii/gun-detection-alert.git + cd cd gun-detection + ``` + +2. **Create and activate the Conda environment:** + ```bash + conda create -n weapon-detection python=3.10 -y + conda activate gun-detection + ``` + +3. **Install required packages:** + ```bash + pip install -r requirements.txt + ``` + +4. **Perform Inference/Prediction:** + ```bash + python3 main.py + streamlit run streamlit_app.py + ``` + + - We have to run both programs for inference. py for fastapi post request and streamlit for UI for the prediction. + +### Docker + +```commandline +``` + +# πŸ”₯Features + +# ⚠️ Limitations + +# Future Work + +# Demo + +# Recommendations + +Your recommendations are highly valuable, and I highly value your insights and suggestions to enhance this project! Feel +free to propose new features, report bugs, or suggest improvements. \ No newline at end of file diff --git a/app.py b/app.py new file mode 100644 index 0000000000000000000000000000000000000000..a2e1c053771d5a8346c7a5ac6ddf229b3935ba74 --- /dev/null +++ b/app.py @@ -0,0 +1,56 @@ +""" +Created By: ishwor subedi +Date: 2024-04-04 +""" +import streamlit as st +from PIL import Image + +from demos.single_image_inference import single_image_inference + +# Constants +MAX_FILE_SIZE = 5 * 1024 * 1024 # 5MB + +# Configure Streamlit +st.set_page_config(layout="wide", page_title="Weapon Detection") + +# Write to Streamlit +st.write("## Weapon Detection") +st.write( + "This app uses a custom trained yolov8 model to detect weapons in images. Upload an image to see the detection results." +) +st.sidebar.write("## Browse images:") + + +def process_image(upload): + """ + Process the uploaded image and display the original and processed images side by side. + """ + try: + image = Image.open(upload) + col1, col2 = st.columns(2) + col1.write("Original Uploaded Image") + col1.image(image) + + processed_image = single_image_inference(image) + col2.write("Predicted Image") + col2.image(processed_image) + st.sidebar.markdown("\n") + except Exception as e: + st.error(f"Error processing image: {e}") + + +def handle_upload(): + """ + Handle the file upload process. + """ + uploaded_file = st.sidebar.file_uploader("Upload an image", type=["png", "jpg", "jpeg"]) + + if uploaded_file is not None: + if uploaded_file.size > MAX_FILE_SIZE: + st.error("The uploaded file is too large. Please upload an image smaller than 5MB.") + else: + process_image(upload=uploaded_file) + + +# Call the upload handler +handle_upload() diff --git a/config/config.ini b/config/config.ini new file mode 100644 index 0000000000000000000000000000000000000000..5b82fd0a12e8070b13419ebd3e2b94a4eba536fa --- /dev/null +++ b/config/config.ini @@ -0,0 +1,7 @@ +[default] +server.host = localhost +server.port = 8000 + +[example.model_info] +yolo.model_path = resources/models/v1/best.pt +path.cam_image_dir = images/cam_images diff --git a/demos/__init__.py b/demos/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..bb1e49ff372647d15cb0be48846a7f120b2ef468 --- /dev/null +++ b/demos/__init__.py @@ -0,0 +1,4 @@ +""" +Created By: ishwor subedi +Date: 2023-12-28 +""" diff --git a/demos/__pycache__/__init__.cpython-39.pyc b/demos/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..12e1624b666f770d54156b1764b204c60486bac6 Binary files /dev/null and b/demos/__pycache__/__init__.cpython-39.pyc differ diff --git a/demos/__pycache__/single_image_inference.cpython-39.pyc b/demos/__pycache__/single_image_inference.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..62304f7959f04842677dc46ff856999b340b9ba8 Binary files /dev/null and b/demos/__pycache__/single_image_inference.cpython-39.pyc differ diff --git a/demos/alert_service_example.py b/demos/alert_service_example.py new file mode 100644 index 0000000000000000000000000000000000000000..106553dbbac9d4b75adc26c1453fbd56efdb00c0 --- /dev/null +++ b/demos/alert_service_example.py @@ -0,0 +1,9 @@ +""" +Created By: ishwor subedi +Date: 2023-12-30 +""" +from services.alert_service.alert_service import AlertService + +if __name__ == '__main__': + alert_service = AlertService("resources/alert/alert.mp3") + alert_service.play_alert() diff --git a/demos/cam_service_example/__pycache__/start_frame_capturing.cpython-39.pyc b/demos/cam_service_example/__pycache__/start_frame_capturing.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dc7b3071e1616a77bda9c46a7848ae884a8721f1 Binary files /dev/null and b/demos/cam_service_example/__pycache__/start_frame_capturing.cpython-39.pyc differ diff --git a/demos/cam_service_example/__pycache__/stop_frame_capturing.cpython-39.pyc b/demos/cam_service_example/__pycache__/stop_frame_capturing.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3a33160e756e8d8c02132a4795eb5b53a04a3554 Binary files /dev/null and b/demos/cam_service_example/__pycache__/stop_frame_capturing.cpython-39.pyc differ diff --git a/demos/cam_service_example/start_frame_capturing.py b/demos/cam_service_example/start_frame_capturing.py new file mode 100644 index 0000000000000000000000000000000000000000..d79607af9b8179a5516cd5c810d1020484442477 --- /dev/null +++ b/demos/cam_service_example/start_frame_capturing.py @@ -0,0 +1,86 @@ +import os +import time +from services.image_capture_service.capture_main import FrameSaver + + +class ImageCaptureService: + def __init__(self, flag_path, source, image_path_to_save, image_hash_threshold): + self.flag_path = flag_path + self.source = source + self.image_path_to_save = image_path_to_save + self.image_hash_threshold = image_hash_threshold + self.running = False + + def create_stop_flag(self): + try: + with open(self.flag_path, 'w') as flag_file: + flag_file.write('False') # Set initial content as 'False' + print("Flag file created and set to 'False'.") + except Exception as e: + print(f"Error creating flag file: {e}") + + def check_stop_flag(self): + try: + if os.path.exists(self.flag_path): + with open(self.flag_path, 'r') as flag_file: + content = flag_file.read().strip() + return content.lower() == "true" + else: + return False + except Exception as e: + print(f"Error checking stop flag: {e}") + return False + + def update_stop_flag(self, value): + try: + with open(self.flag_path, 'w') as flag_file: + flag_file.write(str(value)) # Write the provided value to the flag file + except Exception as e: + print(f"Error updating stop flag: {e}") + + def start_service(self): + try: + print("Image Capturing service starting.") + self.running = True + start_capture = FrameSaver(self.source, self.image_path_to_save, self.image_hash_threshold) + start_capture.start_stream() + + while self.running: + time.sleep(1) + stop_flag = self.check_stop_flag() + + if stop_flag: + print("Stop flag detected. Stopping all frame capturing services.") + self.running = False + stop_successful = start_capture.stop_stream() + if stop_successful: + print("Frame capturing services successfully stopped.") + else: + print("Issue encountered while stopping frame capturing services.") + + except Exception as e: + print(f"Error in setting up FrameSaver: {e}") + print(f"Error in setting up FrameSaver: {e}") + finally: + if 'start_capture' in locals(): + stop_successful = start_capture.stop_stream() + if stop_successful: + print("Frame capturing services successfully stopped in finally block.") + else: + print("Issue encountered while stopping frame capturing services in finally block.") + + def stop_service(self): + self.update_stop_flag("True") + + +if __name__ == "__main__": + FLAG_PATH = "resources/image_capturing" + # SOURCE = 'rtsp://ishwor:subedi@192.168.1.106:5555/h264_opus.sdp' + SOURCE = 0 + IMAGE_PATH_TO_SAVE = "images/cam_images" + IMAGE_HASH_THRESHOLD = 5 + + image_capture_service = ImageCaptureService(FLAG_PATH, SOURCE, IMAGE_PATH_TO_SAVE, IMAGE_HASH_THRESHOLD) + image_capture_service.create_stop_flag() + image_capture_service.start_service() + time.sleep(1) diff --git a/demos/cam_service_example/stop_frame_capturing.py b/demos/cam_service_example/stop_frame_capturing.py new file mode 100644 index 0000000000000000000000000000000000000000..6d5a24f55eda8f8fdce594db671cd4deba0a0d54 --- /dev/null +++ b/demos/cam_service_example/stop_frame_capturing.py @@ -0,0 +1,21 @@ +import os + + +class StopImageCaptureServiceExample: + def __init__(self, stop_flag_path): + self.stop_flag_path = stop_flag_path + + def stop_example_ipcam_webcam(self): + try: + with open(self.stop_flag_path, 'w') as flag_file: + flag_file.write("True") + print("Stop flag set.") + os.remove(self.stop_flag_path) + except Exception as e: + print(f"Error setting stop flag: {e}") + + +if __name__ == "__main__": + STOP_FLAG_PATH = "resources/flag" + stop_load_image_example = StopImageCaptureServiceExample(STOP_FLAG_PATH) + stop_load_image_example.stop_example_ipcam_webcam() diff --git a/demos/image_load_service_example/__pycache__/start_image_load_example.cpython-39.pyc b/demos/image_load_service_example/__pycache__/start_image_load_example.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1b412379511dcd3d86524011c46fa4096babd035 Binary files /dev/null and b/demos/image_load_service_example/__pycache__/start_image_load_example.cpython-39.pyc differ diff --git a/demos/image_load_service_example/__pycache__/stop_image_load_example.cpython-39.pyc b/demos/image_load_service_example/__pycache__/stop_image_load_example.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4554799a090e8337266b7527d18eb4237eb083bb Binary files /dev/null and b/demos/image_load_service_example/__pycache__/stop_image_load_example.cpython-39.pyc differ diff --git a/demos/image_load_service_example/start_image_load_example.py b/demos/image_load_service_example/start_image_load_example.py new file mode 100644 index 0000000000000000000000000000000000000000..3560bc613aeebfa0f44767b9322f890e7c1074cf --- /dev/null +++ b/demos/image_load_service_example/start_image_load_example.py @@ -0,0 +1,84 @@ +import os +import sys +import time +import threading +from services.image_capture_service.image_load_main import ImageLoad + + +class StartImageLoadExample: + def __init__(self, flag_path, image_dir, model_path): + self.flag_path = flag_path + self.image_dir = image_dir + self.model_path = model_path + + self.running = False + + def create_stop_flag(self): + try: + with open(self.flag_path, 'w') as flag_file: + flag_file.write('False') + except Exception as e: + print(f"Error creating stop flag: {e}") + + def check_stop_flag(self): + try: + if os.path.exists(self.flag_path): + with open(self.flag_path, 'r') as flag_file: + content = flag_file.read().strip() + return content.lower() == "true" + else: + return False + except Exception as e: + print(f"Error checking stop flag: {e}") + return False + + def update_stop_flag(self, value): + try: + with open(self.flag_path, 'w') as flag_file: + flag_file.write(str(value)) + except Exception as e: + print(f"Error updating stop flag: {e}") + + def start_service(self): + try: + self.running = True + start_load = ImageLoad(self.image_dir, self.model_path) + start_load.start_load_image() + print("Image loading service successfully started") + + while self.running: + time.sleep(1) + stop_flag = self.check_stop_flag() + + if stop_flag: + self.running = False + stop_successful = start_load.stop_load_image() + if stop_successful: + print("Image loading services_trinetra successfully stopped.") + else: + print("Issue encountered while stopping image loading services_trinetra.") + + except Exception as e: + print(f"Error starting image loading services_trinetra: {e}") + finally: + if 'start_load' in locals(): + stop_successful = start_load.stop_load_image() + if stop_successful: + print("Image loading services_trinetra successfully stopped in finally block.") + else: + print( + "Issue encountered while stopping image loading services_trinetra in finally block.") + + def stop_service(self): + self.update_stop_flag("True") + + +if __name__ == "__main__": + flag_path = "resources/flag_load_image" + image_dir = 'images/cam_images' + model_path = 'resources/models/v1/best.pt' + + image_load_service = StartImageLoadExample(flag_path, image_dir, model_path) + image_load_service.create_stop_flag() + image_load_service.start_service() + time.sleep(1) diff --git a/demos/image_load_service_example/stop_image_load_example.py b/demos/image_load_service_example/stop_image_load_example.py new file mode 100644 index 0000000000000000000000000000000000000000..be1b7cec77f60538134269eeac9a603f8d797c56 --- /dev/null +++ b/demos/image_load_service_example/stop_image_load_example.py @@ -0,0 +1,28 @@ +""" +Created By: ishwor subedi +Date: 2023-12-28 +""" + +import os +import os +from services import ipcam_logger + + +class StopImageLoadServiceExample: + def __init__(self, stop_flag_path): + self.stop_flag_path = stop_flag_path + self.logger = ipcam_logger() + + def stop_service(self): + try: + with open(self.stop_flag_path, 'w') as flag_file: + flag_file.write("True") + self.logger.info("Stop flag set.") + except Exception as e: + self.logger.error(f"Error setting stop flag: {e}") + + +if __name__ == "__main__": + STOP_FLAG_PATH = "resources/flag_load_image" + webcam_controller = StopImageLoadServiceExample(STOP_FLAG_PATH) + webcam_controller.stop_service() diff --git a/demos/single_image_inference.py b/demos/single_image_inference.py new file mode 100644 index 0000000000000000000000000000000000000000..a73aa3141ffca130e898954ed8a7015ec24d51f0 --- /dev/null +++ b/demos/single_image_inference.py @@ -0,0 +1,38 @@ +""" +Created By: ishwor subedi +Date: 2024-04-04 +""" +from services.weapon_det_service.weapon_detection_service import DetectionService +import cv2 as cv + + +def single_image_inference(image_path): + detection_service = DetectionService( + model_path='resources/models/v1/best.pt', + + ) + results = detection_service.image_det_save( + image_path=image_path, + thresh=0.2 + ) + for result in results: + original_image = result.orig_img + bbox = result.boxes.xyxy.int().tolist() + for i, bbox in enumerate(bbox): + x1, y1, x2, y2 = bbox + + cv.putText(original_image, f'{result.names[result.boxes.cls[i].int().tolist()]}', (x1, y1 - 10), + cv.FONT_HERSHEY_SIMPLEX, + 0.9, + (0, 0, 255), 2) + cv.rectangle(original_image, (x1, y1), (x2, y2), (0, 0, 255), 2) + + return original_image + + +if __name__ == '__main__': + image_path = '/home/ishwor/Desktop/gun-detection/images/cam_images/th-3711382641.jpg' + image = single_image_inference(image_path) + cv.imshow('Weapon Detection', image) + cv.waitKey(0) + cv.destroyAllWindows() diff --git a/images/cam_images/PY-4856_Crosman-Bushmaster-MPW-Full_1558033480-458822316.jpg b/images/cam_images/PY-4856_Crosman-Bushmaster-MPW-Full_1558033480-458822316.jpg new file mode 100644 index 0000000000000000000000000000000000000000..318fc8e752f61e5ff0d2bd1aac35c88d0ac43335 Binary files /dev/null and b/images/cam_images/PY-4856_Crosman-Bushmaster-MPW-Full_1558033480-458822316.jpg differ diff --git a/images/cam_images/th-2208139001.jpg b/images/cam_images/th-2208139001.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d06e8f86f41d2c4b0b6d8e1213627b4f94b3d6cc Binary files /dev/null and b/images/cam_images/th-2208139001.jpg differ diff --git a/images/cam_images/th-3711382641.jpg b/images/cam_images/th-3711382641.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1f0897688a4fabf8ac920d5219ca6a9f46ec3974 Binary files /dev/null and b/images/cam_images/th-3711382641.jpg differ diff --git a/logs/gun_det.log b/logs/gun_det.log new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/logs/ipcam.log b/logs/ipcam.log new file mode 100644 index 0000000000000000000000000000000000000000..8a97a70c8e13c84ef63b34052dc4da73f10a7452 --- /dev/null +++ b/logs/ipcam.log @@ -0,0 +1 @@ +[2024-04-04 00:05:06,251:INFO:stop_image_load_example:Stop flag set.] diff --git a/main.py b/main.py new file mode 100644 index 0000000000000000000000000000000000000000..9969cd2a2d70e1c4bf6c97251ade38b61738c74d --- /dev/null +++ b/main.py @@ -0,0 +1,10 @@ +""" +Created By: ishwor subedi +Date: 2024-01-02 +""" +import uvicorn + +from services.api.fast_api import app + +if __name__ == "__main__": + uvicorn.run(app, host="localhost", port=8000) diff --git a/resources/alert/alert.mp3 b/resources/alert/alert.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..9259977cf209891918ab031d8c4292615da91ae9 Binary files /dev/null and b/resources/alert/alert.mp3 differ diff --git a/resources/flag_load_image b/resources/flag_load_image new file mode 100644 index 0000000000000000000000000000000000000000..4791ed5559bd77f54e1520025768e2b368705876 --- /dev/null +++ b/resources/flag_load_image @@ -0,0 +1 @@ +True \ No newline at end of file diff --git a/resources/image_capturing b/resources/image_capturing new file mode 100644 index 0000000000000000000000000000000000000000..c1f22fbc23bb6ee67824843d6685826db10313d3 --- /dev/null +++ b/resources/image_capturing @@ -0,0 +1 @@ +False \ No newline at end of file diff --git a/resources/models/best.pt b/resources/models/best.pt new file mode 100644 index 0000000000000000000000000000000000000000..83b4f0c37dd17e7c4ef70ed007be913675ace734 --- /dev/null +++ b/resources/models/best.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:21d61ad8068caca3062d33fd8d05da445ef9ae81a2bb817249e085b0f1307cf0 +size 6263257 diff --git a/resources/models/v1/best.pt b/resources/models/v1/best.pt new file mode 100644 index 0000000000000000000000000000000000000000..89805fa9d0dbc18a3ed0bb40892602b0dfb4f150 --- /dev/null +++ b/resources/models/v1/best.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4937605a869713f16e72981374933daf2ce884ff5603a91c42403ece282c2988 +size 12349682 diff --git a/resources/models/weapon_detector.pt b/resources/models/weapon_detector.pt new file mode 100644 index 0000000000000000000000000000000000000000..eccf54c78e00f6213157f10cd9b00e923c42d1d3 --- /dev/null +++ b/resources/models/weapon_detector.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:74ee5662c4a57267ac270068aa20a805b221f1ffe6d88c08c9131b9eb873b296 +size 74802191 diff --git a/resources/models/yolov7.pt b/resources/models/yolov7.pt new file mode 100644 index 0000000000000000000000000000000000000000..e5002a7ba03b1c6f30ed3196a66d3df3d4f0fb04 --- /dev/null +++ b/resources/models/yolov7.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d1ac3c74eb96a3eec77949c0f37a06bc272756606ff011d9353f7abff4e0c71d +size 75587165 diff --git a/resources/models/yolov7_2.pt b/resources/models/yolov7_2.pt new file mode 100644 index 0000000000000000000000000000000000000000..e5002a7ba03b1c6f30ed3196a66d3df3d4f0fb04 --- /dev/null +++ b/resources/models/yolov7_2.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d1ac3c74eb96a3eec77949c0f37a06bc272756606ff011d9353f7abff4e0c71d +size 75587165 diff --git a/services/__init__.py b/services/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c07bf1cc44d4420d8ecfc65d543f133b448eb385 --- /dev/null +++ b/services/__init__.py @@ -0,0 +1,64 @@ +import os +import sys +import logging + + +def configure_logger(logger_name, log_filename, log_dir="logs"): + """ + Configures a logger with specified parameters. + + :param logger_name: Name of the logger. + :param log_filename: Name of the log file. + :param log_dir: Directory where logs will be stored. Defaults to "logs". + :return: Configured logger. + """ + logging_str = "[%(asctime)s:%(levelname)s:%(module)s:%(message)s]" + + log_path = os.path.join(log_dir, log_filename) + os.makedirs(log_dir, exist_ok=True) + + logger = logging.getLogger(logger_name) + logger.setLevel(logging.INFO) + + formatter = logging.Formatter(logging_str) + + file_handler = logging.FileHandler(log_path) + file_handler.setFormatter(formatter) + + stream_handler = logging.StreamHandler(sys.stdout) + stream_handler.setFormatter(formatter) + + logger.addHandler(file_handler) + logger.addHandler(stream_handler) + + return logger + + +def main_sys_logger(log_dir="logs"): + """ + Configures and returns the main system logger. + + :param log_dir: Directory where logs will be stored. Defaults to "logs". + :return: Main system logger. + """ + return configure_logger("main_sys_logger", "gun_det.log", log_dir) + + +def ipcam_logger(log_dir="logs"): + """ + Configures and returns the IP camera logger. + + :param log_dir: Directory where logs will be stored. Defaults to "logs". + :return: IP camera logger. + """ + return configure_logger("ipcam_logger", "ipcam.log", log_dir) + + +def detection_logger(log_dir="logs"): + """ + Configures and returns the detection logger. + + :param log_dir: Directory where logs will be stored. Defaults to "logs". + :return: Detection logger. + """ + return configure_logger("detection_logger", "detection.log", log_dir) diff --git a/services/__pycache__/__init__.cpython-310.pyc b/services/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4a359149d65ebbd9fce06e683ce5366aaffa3362 Binary files /dev/null and b/services/__pycache__/__init__.cpython-310.pyc differ diff --git a/services/__pycache__/__init__.cpython-39.pyc b/services/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..48fc57a7930911f8615a9f0931ddb240d601347c Binary files /dev/null and b/services/__pycache__/__init__.cpython-39.pyc differ diff --git a/services/alert_service/__init__.py b/services/alert_service/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d280816e33d3bf3ca5406b5e7096b772688fc305 --- /dev/null +++ b/services/alert_service/__init__.py @@ -0,0 +1,4 @@ +""" +Created By: ishwor subedi +Date: 2023-12-29 +""" diff --git a/services/alert_service/__pycache__/__init__.cpython-39.pyc b/services/alert_service/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c9257b48ebc5f3f26944420c1f21a33ea5b1c37f Binary files /dev/null and b/services/alert_service/__pycache__/__init__.cpython-39.pyc differ diff --git a/services/alert_service/__pycache__/alert_service.cpython-39.pyc b/services/alert_service/__pycache__/alert_service.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7431aca603aa2221c81849a49926e5eae5719e1e Binary files /dev/null and b/services/alert_service/__pycache__/alert_service.cpython-39.pyc differ diff --git a/services/alert_service/alert_service.py b/services/alert_service/alert_service.py new file mode 100644 index 0000000000000000000000000000000000000000..79a3094e567cac54aff0d0887ebb797ce7cdeff6 --- /dev/null +++ b/services/alert_service/alert_service.py @@ -0,0 +1,30 @@ +""" +Created By: ishwor subedi +Date: 2023-12-30 +""" + +import pygame + + +class AlertService: + def __init__(self, alert_sound_path): + self.alert_sound_path = alert_sound_path + pygame.init() + + def play_alert(self): + """ + This function help us to play the alert sound + :return: + """ + try: + pygame.mixer.init() + alert_sound = pygame.mixer.Sound(self.alert_sound_path) + alert_sound.play() + pygame.time.wait(int(alert_sound.get_length() * 1000)) # Wait for the sound to finish playing + except pygame.error as e: + print(f"Error playing alert sound: {e}") + + +if __name__ == '__main__': + alert_service = AlertService("resources/alert/alert.mp3") + alert_service.play_alert() diff --git a/services/api/__init__.py b/services/api/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..bb1e49ff372647d15cb0be48846a7f120b2ef468 --- /dev/null +++ b/services/api/__init__.py @@ -0,0 +1,4 @@ +""" +Created By: ishwor subedi +Date: 2023-12-28 +""" diff --git a/services/api/__pycache__/__init__.cpython-39.pyc b/services/api/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d5b7c211abee4553956b20b0da65ea235a36a719 Binary files /dev/null and b/services/api/__pycache__/__init__.cpython-39.pyc differ diff --git a/services/api/__pycache__/fast_api.cpython-39.pyc b/services/api/__pycache__/fast_api.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7a486fdac6a27c4d067f877cea3fc4f1115a340e Binary files /dev/null and b/services/api/__pycache__/fast_api.cpython-39.pyc differ diff --git a/services/api/fast_api.py b/services/api/fast_api.py new file mode 100644 index 0000000000000000000000000000000000000000..4a677efd2e73317fcb0b92cbbc6ccff720f04193 --- /dev/null +++ b/services/api/fast_api.py @@ -0,0 +1,109 @@ +from fastapi import FastAPI +from fastapi.responses import JSONResponse +from fastapi import HTTPException +import uvicorn +import base64 +import io +from PIL import Image +from demos.cam_service_example.start_frame_capturing import ImageCaptureService +from demos.cam_service_example.stop_frame_capturing import StopImageCaptureServiceExample +from demos.image_load_service_example.start_image_load_example import StartImageLoadExample +from demos.image_load_service_example.stop_image_load_example import StopImageLoadServiceExample +from demos.single_image_inference import single_image_inference +from pydantic import BaseModel + +app = FastAPI() + + +# Helper functions +def start_ipcam(): + flag_path = "resources/flag" + + source = 'rtsp://ishwor:subedi@192.168.1.106:5555/h264_opus.sdp' + + image_path_to_save = "images/cam_images" + image_hash_threshold = 5 + image_capture_start_example = ImageCaptureService(flag_path, source, image_path_to_save, + image_hash_threshold) + image_capture_start_example.start_service() + + +def stop_ipcam(): + flag_path = "resources/flag" + + image_capture_stop_example = StopImageCaptureServiceExample(flag_path) + image_capture_stop_example.stop_load_image_example() + + +def start_detection(): + flag_path = "resources/flag_load_image" + + image_dir_path = "images/cam_images" + + start_load_image_example = StartImageLoadExample(flag_path, image_dir_path, model_path="resources/model/v1/best.pt") + start_load_image_example.start_service() + + +def stop_detection(): + flag_path = "resources/flag_load_image" + + stop_load_image_example = StopImageLoadServiceExample(flag_path) + stop_load_image_example.stop_service() + + +# FastAPI Endpoints +@app.post("/start_ipcam_server") +def start_ipcam_server_api(): + try: + start_ipcam() + return JSONResponse(content={"message": "IP Cam Server started!"}, status_code=200) + except Exception as e: + raise HTTPException(status_code=500, detail=str(e)) + + +@app.post("/stop_ipcam_server") +def stop_ipcam_server_api(): + try: + stop_ipcam() + return JSONResponse(content={"message": "IP Cam Server stopped!"}, status_code=200) + except Exception as e: + raise HTTPException(status_code=500, detail=str(e)) + + +@app.post("/start_detection_service") +def start_detection_service_api(): + try: + start_detection() + return JSONResponse(content={"message": "Image loading Server started!"}, status_code=200) + except Exception as e: + raise HTTPException(status_code=500, detail=str(e)) + + +@app.post("/stop_detection_service") +def stop_detection_service_api(): + try: + stop_detection() + return JSONResponse(content={"message": "Image loading Server stopped!"}, status_code=200) + except Exception as e: + raise HTTPException(status_code=500, detail=str(e)) + + +class ImageInput(BaseModel): + base64_image: str + + +@app.post("/single_image_detection") +def single_image_detection_api(image_input: ImageInput): + try: + image_data = base64.b64decode(image_input.base64_image) + + image = Image.open(io.BytesIO(image_data)) + image = single_image_inference(image) + encoded_img = base64.b64encode(image) + return encoded_img + except Exception as e: + raise HTTPException(status_code=500, detail=str(e)) + + +if __name__ == "__main__": + uvicorn.run(app, host="localhost", port=8001) diff --git a/services/entity/__init__.py b/services/entity/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/services/entity/entity_config.py b/services/entity/entity_config.py new file mode 100644 index 0000000000000000000000000000000000000000..ac87be1a2a51e72a84972e930fd2cb97b134137a --- /dev/null +++ b/services/entity/entity_config.py @@ -0,0 +1,7 @@ +from dataclasses import dataclass +from pathlib import Path + + +@dataclass(frozen=True) +class StreamLitConfig: + pass diff --git a/services/image_capture_service/__init__.py b/services/image_capture_service/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/services/image_capture_service/__pycache__/__init__.cpython-39.pyc b/services/image_capture_service/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..430d4166bb8ae9abaa160233fe802abbbb7a8b20 Binary files /dev/null and b/services/image_capture_service/__pycache__/__init__.cpython-39.pyc differ diff --git a/services/image_capture_service/__pycache__/capture_main.cpython-39.pyc b/services/image_capture_service/__pycache__/capture_main.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0dad09bf593195d8f4d6a97e70460168fa5c2426 Binary files /dev/null and b/services/image_capture_service/__pycache__/capture_main.cpython-39.pyc differ diff --git a/services/image_capture_service/__pycache__/image_load_main.cpython-39.pyc b/services/image_capture_service/__pycache__/image_load_main.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..42d8e18b627b4d5537332156a6356b1c1f71bfe7 Binary files /dev/null and b/services/image_capture_service/__pycache__/image_load_main.cpython-39.pyc differ diff --git a/services/image_capture_service/capture_main.py b/services/image_capture_service/capture_main.py new file mode 100644 index 0000000000000000000000000000000000000000..a057447422ca3a269b8b2538fc1e18ba7256f82a --- /dev/null +++ b/services/image_capture_service/capture_main.py @@ -0,0 +1,81 @@ +""" +Author: ishwor subedi +Date: 2023-12-28 +Project Name:gun-detection + +""" +import os +from PIL import Image +from datetime import datetime +import threading +import imagehash +import cv2 as cv +from utils.settings import get_frame_save_dir + + +class FrameSaver: + def __init__(self, source, image_path_to_save, image_hash_threshold): + self.source = source + self.image_path_to_save = image_path_to_save + if self.image_path_to_save is None or not os.path.exists(self.image_path_to_save): + self.image_path_to_save = get_frame_save_dir() + self.thread_running = False + self.frame_save_thread = None + self.cap = cv.VideoCapture(self.source) + self.image_hash_threshold = image_hash_threshold + + def start_stream(self): + self.frame_save_thread = threading.Thread(target=self.video_webcam_frame_extraction) + self.frame_save_thread.start() + self.thread_running = True + + def stop_stream(self): + if self.thread_running: + self.thread_running = False + self.frame_save_thread.join() + self.cap.release() + + def hashing_diff(self, prev_frame, current_frame): + if prev_frame is None: + return None + else: + hash1 = imagehash.average_hash(Image.fromarray(prev_frame)) + hash2 = imagehash.average_hash(Image.fromarray(current_frame)) + return hash2 - hash1 + + def video_webcam_frame_extraction(self): + """ + + :return: + """ + + try: + + previous_frame = None + while self.cap.isOpened(): + success, frame = self.cap.read() + if success: + hash_diff = self.hashing_diff(previous_frame, frame) + if hash_diff is None or hash_diff > self.image_hash_threshold: + current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S') + name = os.path.join(self.image_path_to_save, f"{current_time}.jpg") + success = cv.imwrite(name, frame) + if success: + print(f"Saved {name}...") + else: + print(f"Failed to save image: {name}") + previous_frame = frame + except Exception as e: + print(f"Exception occurred: {e}") + try: + self.stop_stream() + except Exception as e: + print(f"Failed to stop stream: {e}") + + +if __name__ == '__main__': + source = 'rtsp://ishwor:subedi@192.168.1.106:5555/h264_opus.sdp' + image_path_to_save = "images/cam_images" + image_hash_threshold = 5 + image_capture_service = FrameSaver(source, image_path_to_save, image_hash_threshold) + image_capture_service.video_webcam_frame_extraction() diff --git a/services/image_capture_service/image_load_main.py b/services/image_capture_service/image_load_main.py new file mode 100644 index 0000000000000000000000000000000000000000..42f7cfc777be3a4910450ea539d597518129dd7c --- /dev/null +++ b/services/image_capture_service/image_load_main.py @@ -0,0 +1,79 @@ +import os +import time +import threading +from services.weapon_det_service.weapon_detection_service import DetectionService +import cv2 + + +class ImageLoad: + def __init__(self, image_dir, model_path, ): + self.flag = False + self.thread_running = False + self.image_load = None + self.image_path_img = image_dir + self.latest_image_path = None + self.detection_service = DetectionService( + model_path=model_path, + ) + self.filename = None + self.display = True + + self.image_info_save = None + self.original_image = None + self.bbox = None + self.image_display_thread = None + + def start_load_image(self): + """ + Start the image loading thread + :return: + """ + self.image_load = threading.Thread(target=self.image_list) + + self.image_load.start() + + self.thread_running = True + + def stop_load_image(self): + if self.thread_running: + self.thread_running = False + + self.image_load.join() + print("Stopping the image loading thread...") + + def image_list(self): + time.sleep(2) + while self.thread_running: + files = sorted(os.listdir(self.image_path_img)) + for self.filename in files: + if not self.thread_running: + break + + image_path = os.path.join(self.image_path_img, self.filename) + + self.latest_image_path = image_path + print("Processing:", self.latest_image_path) + + rd = cv2.imread(self.latest_image_path) + time.sleep(0.5) + if rd is not None: + results = self.detection_service.image_det_save(image_path=self.latest_image_path, + thresh=0.5, + ) + cv2.waitKey(3) + print('done') + os.remove(self.latest_image_path) + else: + print('Image Loading Failed .......') + + +if __name__ == '__main__': + image_load = ImageLoad( + image_dir='images/cam_images', + model_path='resources/models/v1/best.pt', + ) + + image_load.start_load_image() + # time.sleep(10) + # image_load.stop_load_image() + # print("Exiting the program...") diff --git a/services/location_share/__init__.py b/services/location_share/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/services/location_share/location_share_service.py b/services/location_share/location_share_service.py new file mode 100644 index 0000000000000000000000000000000000000000..820c3b67177e1cf47f3c03eff05fa7456e2fdde5 --- /dev/null +++ b/services/location_share/location_share_service.py @@ -0,0 +1,15 @@ +""" +Created By: ishwor subedi +Date: 2023-12-30 +""" + + +class LocationShareService: + def __init__(self): + pass + + def request_access_of_location_from_browser(self): + pass + + def location_show(self): + pass diff --git a/services/weapon_det_service/__init__.py b/services/weapon_det_service/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/services/weapon_det_service/__pycache__/__init__.cpython-39.pyc b/services/weapon_det_service/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1b2d365fc068423224f46e6adc504fd38ba19def Binary files /dev/null and b/services/weapon_det_service/__pycache__/__init__.cpython-39.pyc differ diff --git a/services/weapon_det_service/__pycache__/weapon_detection_service.cpython-39.pyc b/services/weapon_det_service/__pycache__/weapon_detection_service.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..86e04338ead47c71e14847f3c5ef6069042bb3d8 Binary files /dev/null and b/services/weapon_det_service/__pycache__/weapon_detection_service.cpython-39.pyc differ diff --git a/services/weapon_det_service/weapon_detection_service.py b/services/weapon_det_service/weapon_detection_service.py new file mode 100644 index 0000000000000000000000000000000000000000..4386d4a3606c06ea9c35465fccb377543b4e46b3 --- /dev/null +++ b/services/weapon_det_service/weapon_detection_service.py @@ -0,0 +1,36 @@ +import os +import time +from pathlib import Path +from ultralytics import YOLO + + +class DetectionService: + def __init__(self, model_path): + self.model_path = model_path + + def image_det_save(self, image_path, thresh=0.2): + """ + image detection and save the image with bounding box + :param image_path: + :param thresh: + :return: + """ + detector = YOLO(self.model_path) + results = detector.predict(image_path, conf=thresh, show=False) + + return results + + +if __name__ == "__main__": + detection_service = DetectionService( + model_path='resources/models/v1/best.pt', + + ) + input_image_path = Path( + "/home/ishwor/Downloads/PY-4856_Crosman-Bushmaster-MPW-Full_1558033480-458822316.jpg") + + detection_service.image_det_save( + image_path=str(input_image_path), + + thresh=0.2 + ) diff --git a/streamlit_app.py b/streamlit_app.py new file mode 100644 index 0000000000000000000000000000000000000000..446ce57cd2a371f976212572bf03e1e682f7d263 --- /dev/null +++ b/streamlit_app.py @@ -0,0 +1,136 @@ +import os +import requests +import streamlit as st +import pandas as pd +import uvicorn + +from services.api.fast_api import app + +LOG_DIR = "logs" +API_URL = "http://localhost:8000" + +ipcam_server_status = False +detection_service_status = False + + +def call_api(endpoint): + try: + response = requests.post(f"{API_URL}/{endpoint}") + return response.json() + except Exception as e: + return {"error": str(e)} + + +def start_stop_server(start_message, already_running_message, not_running_message): + global ipcam_server_status, detection_service_status + if not ipcam_server_status: + result = call_api("start_ipcam_server") + ipcam_server_status = True + return {"message": start_message, "result": result} + else: + return {"message": already_running_message} + + +def start_ipcam_server(): + return start_stop_server("IP Cam Server started.", "IP Cam Server is already running.", + "IP Cam Server is not running.")["result"] + + +def stop_ipcam_server(): + global ipcam_server_status + if ipcam_server_status: + result = call_api("stop_ipcam_server") + ipcam_server_status = False + return {"message": "IP Cam Server stopped.", "result": result} + else: + return {"message": "IP Cam Server is not running."} + + +def start_detection_service(): + return start_stop_server("Detection Service started.", "Detection Service is already running.", + "Detection Service is not running.")["result"] + + +def stop_detection_service(): + global detection_service_status + if detection_service_status: + result = call_api("stop_detection_service") + detection_service_status = False + return {"message": "Detection Service stopped.", "result": result} + else: + return {"message": "Detection Service is not running."} + + +def extract_info_from_filename(filename): + parts = os.path.splitext(filename)[0].split() + + date, time = parts[0], parts[1] + + return date, time, filename + + +def create_datatable(image_folder): + st.subheader("Image DataTable") + + image_files = [file for file in os.listdir(image_folder) if + file.lower().endswith(('.png', '.jpg', '.jpeg', '.gif', '.bmp'))] + + data = {"Date": [], "Time": [], "ImageName": []} + + for img in image_files: + date, time, image_name = extract_info_from_filename(img) + data["Date"].append(date) + data["Time"].append(time) + data["ImageName"].append(image_name) + + df = pd.DataFrame(data) + + # Convert Date and Time columns to datetime for sorting + df['DateTime'] = pd.to_datetime(df['Date'] + ' ' + df['Time']) + + # Sort DataFrame by DateTime in descending order + df = df.sort_values(by='DateTime', ascending=False).drop('DateTime', axis=1) + + st.table(df) + + +def main_streamlit(): + global ipcam_server_status, detection_service_status + + image_folder = "images/cam_images" + st.sidebar.header("Weapon Detection and Location Sharing Alert Systems") + + container = st.sidebar.empty() + + selected_option = st.sidebar.selectbox('Select an option', + ["IP Cam Service", "Detection Service"]) + + if selected_option == "IP Cam Service": + st.subheader("IP Cam Service") + if st.button('Start Server'): + result = start_ipcam_server() + st.write(result) + if st.button('Stop Server'): + result = stop_ipcam_server() + st.write(result) + if st.button('Refresh Datatable'): + create_datatable(image_folder) + + elif selected_option == "Detection Service": + st.subheader("Detection Service") + if st.button('Start Server'): + result = start_detection_service() + st.write(result) + if st.button('Stop Server'): + result = stop_detection_service() + st.write(result) + + container.subheader("Service Status:") + container.write(f"IP Cam Service: {'Running' if ipcam_server_status else 'Stopped'}") + container.write(f"Detection Service: {'Running' if detection_service_status else 'Stopped'}") + + +if __name__ == '__main__': + uvicorn.run(app, host="localhost", port=8000) + + main_streamlit() diff --git a/utils/__init__.py b/utils/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/utils/__pycache__/__init__.cpython-310.pyc b/utils/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..909d660d0014a2240c943f6426c0598610d7a9ff Binary files /dev/null and b/utils/__pycache__/__init__.cpython-310.pyc differ diff --git a/utils/__pycache__/__init__.cpython-39.pyc b/utils/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..19c53973e6545c6303d8a18d8b96bf677ec573aa Binary files /dev/null and b/utils/__pycache__/__init__.cpython-39.pyc differ diff --git a/utils/__pycache__/settings.cpython-310.pyc b/utils/__pycache__/settings.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..30a818e6ef55965861ddaa2287675a3305aaa29d Binary files /dev/null and b/utils/__pycache__/settings.cpython-310.pyc differ diff --git a/utils/__pycache__/settings.cpython-39.pyc b/utils/__pycache__/settings.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fe4e296bd044ae7a93ca204746f3aaedd3406acc Binary files /dev/null and b/utils/__pycache__/settings.cpython-39.pyc differ diff --git a/utils/pathutils.py b/utils/pathutils.py new file mode 100644 index 0000000000000000000000000000000000000000..14603b2e2bf2680e828766a28d4264ec8a669e61 --- /dev/null +++ b/utils/pathutils.py @@ -0,0 +1,44 @@ +""" +Author: ishwor subedi +Date: 2023-12-28 + +""" +import os +import yaml +from box import ConfigBox # we can access the value using dot and key name +from box.exceptions import BoxValueError +from ensure import ensure_annotations +from pathlib import Path +from services import main_sys_logger as logger + + +@ensure_annotations +def read_yaml_file(path_to_yaml_file: Path) -> ConfigBox: + """ + + :param path_to_yaml_file: + :return: + """ + try: + with open(path_to_yaml_file) as yaml_file: + content = yaml.safe_load(yaml_file) + logger.info(f"yaml file:{path_to_yaml_file} loaded successfully") + return ConfigBox(content) + except BoxValueError: + raise ValueError("yaml file is empty") + except Exception as e: + raise e + + +@ensure_annotations +def create_directories(path_to_directories: list, verbose=True): + """ + + :param path_to_directories: + :param verbose: + :return: + """ + for path in path_to_directories: + os.makedirs(path, exist_ok=True) + if verbose: + logger.info(f"created directory at: {path}") diff --git a/utils/settings.py b/utils/settings.py new file mode 100644 index 0000000000000000000000000000000000000000..f5ee4018a878623d3995f62b183fbe41fe97e41c --- /dev/null +++ b/utils/settings.py @@ -0,0 +1,60 @@ +""" +Author: ishwor subedi +Date: 2023-12-27 + +""" +import os + +from services import main_sys_logger +import cv2 as cv + +main_sys_logger = main_sys_logger() + + +def get_frame_save_dir(): + """ + Create a directory for saving images from a video. + + :return: + str: The path of the created or existing directory. + """ + root_dir = 'images/cam_images' + + frame_dir = os.path.join(root_dir) + if not os.path.exists(frame_dir): + main_sys_logger.info(f"<<<<<<<<<<<<<<<<<< Folder created {frame_dir} >>>>>>>>>>>>>>>>>>>>") + os.makedirs(frame_dir) + return frame_dir + + +def imutil(image_path, output_path, new_size=None): + """ + Resize an image using OpenCV. + + :param image_path: str, path to the input image file. + :param output_path: str, path to save the resized image. + :param new_size: tuple, (width, height) of the desired size. + """ + try: + image = cv.imread(image_path) + + if new_size is not None: + image = cv.resize(image, new_size) + + cv.imwrite(output_path, image) + main_sys_logger.info(f"Image saved to: {output_path}") + except Exception as e: + main_sys_logger.error(f"Error in imutil: {e}") + + +# Example usage: +if __name__ == "__main__": + # Get the directory for saving frames + frame_dir = get_frame_save_dir() + + # Example image path and output path + input_image_path = 'path/to/your/input/image.jpg' + output_image_path = os.path.join(frame_dir, 'resized_image.jpg') + + # Resize the image and save it + imutil(input_image_path, output_image_path, new_size=(800, 600))