wayandadang commited on
Commit
22b2bcd
·
1 Parent(s): 3337d26

first commit

Browse files
.gitignore ADDED
@@ -0,0 +1,148 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Local folder
10
+ local_folder
11
+ project_demo
12
+ project_demo/
13
+ logs/
14
+ local_folder/
15
+ /demo.py
16
+ demo.py
17
+ runs/
18
+
19
+ # Large folders
20
+ weights/
21
+ videos/
22
+ images/
23
+
24
+
25
+ # Distribution / packaging
26
+ .Python
27
+ build/
28
+ develop-eggs/
29
+ dist/
30
+ downloads/
31
+ eggs/
32
+ .eggs/
33
+ lib/
34
+ lib64/
35
+ parts/
36
+ sdist/
37
+ var/
38
+ wheels/
39
+ pip-wheel-metadata/
40
+ share/python-wheels/
41
+ *.egg-info/
42
+ .installed.cfg
43
+ *.egg
44
+ MANIFEST
45
+
46
+ # PyInstaller
47
+ # Usually these files are written by a python script from a template
48
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
49
+ *.manifest
50
+ *.spec
51
+
52
+ .vscode
53
+
54
+ # Installer logs
55
+ pip-log.txt
56
+ pip-delete-this-directory.txt
57
+
58
+ # Unit test / coverage reports
59
+ htmlcov/
60
+ .tox/
61
+ .nox/
62
+ .coverage
63
+ .coverage.*
64
+ .cache
65
+ nosetests.xml
66
+ coverage.xml
67
+ *.cover
68
+ *.py,cover
69
+ .hypothesis/
70
+ .pytest_cache/
71
+
72
+ # Translations
73
+ *.mo
74
+ *.pot
75
+
76
+ # Django stuff:
77
+ *.log
78
+ local_settings.py
79
+ db.sqlite3
80
+ db.sqlite3-journal
81
+
82
+ # Flask stuff:
83
+ instance/
84
+ .webassets-cache
85
+
86
+ # Scrapy stuff:
87
+ .scrapy
88
+
89
+ # Sphinx documentation
90
+ docs/_build/
91
+
92
+ # PyBuilder
93
+ target/
94
+
95
+ # Jupyter Notebook
96
+ .ipynb_checkpoints
97
+
98
+ # IPython
99
+ profile_default/
100
+ ipython_config.py
101
+
102
+ # pyenv
103
+ .python-version
104
+
105
+ # pipenv
106
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
107
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
108
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
109
+ # install all needed dependencies.
110
+ #Pipfile.lock
111
+
112
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow
113
+ __pypackages__/
114
+
115
+ # Celery stuff
116
+ celerybeat-schedule
117
+ celerybeat.pid
118
+
119
+ # SageMath parsed files
120
+ *.sage.py
121
+
122
+ # Environments
123
+ .env
124
+ .venv
125
+ env/
126
+ venv/
127
+ venv_/
128
+ ENV/
129
+ env.bak/
130
+ venv.bak/
131
+
132
+ # Spyder project settings
133
+ .spyderproject
134
+ .spyproject
135
+
136
+ # Rope project settings
137
+ .ropeproject
138
+
139
+ # mkdocs documentation
140
+ /site
141
+
142
+ # mypy
143
+ .mypy_cache/
144
+ .dmypy.json
145
+ dmypy.json
146
+
147
+ # Pyre type checker
148
+ .pyre/
app.py ADDED
@@ -0,0 +1,134 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Python In-built packages
2
+ from pathlib import Path
3
+ import PIL
4
+ import time
5
+
6
+ # External packages
7
+ import streamlit as st
8
+ import cv2
9
+
10
+ # Local Modules
11
+ import settings
12
+ import helper
13
+
14
+ # Setting page layout
15
+ st.set_page_config(
16
+ page_title="Object Detection using YOLOv9",
17
+ page_icon="🤖",
18
+ layout="wide",
19
+ initial_sidebar_state="expanded"
20
+ )
21
+
22
+ # Main page heading
23
+ st.title("Object Detection using YOLOv9")
24
+
25
+ # Sidebar
26
+ st.sidebar.header("ML Model Config")
27
+
28
+ # Model Options
29
+ model_type = st.sidebar.radio(
30
+ "Select Task", ['Detection', 'Segmentation'])
31
+ confidence = float(st.sidebar.slider(
32
+ "Select Model Confidence", 25, 100, 40)) / 100
33
+
34
+ # Selecting Detection Or Segmentation
35
+ if model_type == 'Detection':
36
+ model_path = Path(settings.DETECTION_MODEL)
37
+ elif model_type == 'Segmentation':
38
+ model_path = Path(settings.SEGMENTATION_MODEL)
39
+
40
+ # Load Pre-trained ML Model
41
+ try:
42
+ model = helper.load_model(model_path)
43
+ except Exception as ex:
44
+ st.error(f"Unable to load model. Check the specified path: {model_path}")
45
+ st.error(ex)
46
+
47
+ st.sidebar.header("Image/Video Config")
48
+ source_radio = st.sidebar.radio(
49
+ "Select Source", settings.SOURCES_LIST)
50
+ source_img = None
51
+
52
+ # If image is selected
53
+ if source_radio == settings.IMAGE:
54
+ source_img = st.sidebar.file_uploader(
55
+ "Choose an image...", type=("jpg", "jpeg", "png", 'bmp', 'webp'))
56
+ col1, col2 = st.columns(2)
57
+ with col1:
58
+ try:
59
+ if source_img is None:
60
+ default_image_path = str(settings.DEFAULT_IMAGE)
61
+ default_image = PIL.Image.open(default_image_path)
62
+ st.image(default_image_path, caption="Default Image",
63
+ use_column_width=True)
64
+ else:
65
+ uploaded_image = PIL.Image.open(source_img)
66
+ st.image(source_img, caption="Uploaded Image",
67
+ use_column_width=True)
68
+ except Exception as ex:
69
+ st.error("Error occurred while opening the image.")
70
+ st.error(ex)
71
+ with col2:
72
+ if source_img is None:
73
+ default_detected_image_path = str(settings.DEFAULT_DETECT_IMAGE)
74
+ default_detected_image = PIL.Image.open(
75
+ default_detected_image_path)
76
+ st.image(default_detected_image_path, caption='Detected Image',
77
+ use_column_width=True)
78
+ else:
79
+ if st.sidebar.button('Detect Objects'):
80
+ res = model.predict(uploaded_image,
81
+ conf=confidence
82
+ )
83
+ boxes = res[0].boxes
84
+ res_plotted = res[0].plot()[:, :, ::-1]
85
+ st.image(res_plotted, caption='Detected Image',
86
+ use_column_width=True)
87
+ try:
88
+ with st.expander("Detection Results"):
89
+ for box in boxes:
90
+ st.write(box.data)
91
+ except Exception as ex:
92
+ # st.write(ex)
93
+ st.write("No image is uploaded yet!")
94
+
95
+ elif source_radio == settings.VIDEO:
96
+ helper.play_stored_video(confidence, model)
97
+
98
+ elif source_radio == settings.YOUTUBE:
99
+ helper.play_youtube_video(confidence, model)
100
+
101
+ elif source_radio == settings.WEBCAM: # Adding webcam option
102
+ st.sidebar.markdown("**Webcam**")
103
+ webcam = cv2.VideoCapture(1)
104
+ if not webcam.isOpened():
105
+ st.error("Unable to open webcam. Please make sure it's connected.")
106
+ else:
107
+ webcam_status = st.sidebar.empty()
108
+ start_stop_button = st.sidebar.button("Start Webcam")
109
+
110
+ if start_stop_button:
111
+ webcam_started = True
112
+ webcam_status.text("Webcam Started!")
113
+
114
+ while webcam_started:
115
+ ret, frame = webcam.read()
116
+ if not ret:
117
+ st.error("Failed to capture frame from webcam")
118
+ break
119
+ frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
120
+
121
+ # Perform object detection on the frame
122
+ res = model.predict(frame, conf=confidence)
123
+ boxes = res[0].boxes
124
+ frame = res[0].plot()[:, :, ::-1]
125
+
126
+ # Display the frame
127
+ st.image(frame, channels="RGB", use_column_width=True)
128
+
129
+ stop_button = st.sidebar.button("Stop Webcam" + str(hash(time.time()))) # Unique key
130
+ if stop_button:
131
+ webcam_started = False
132
+ webcam_status.text("Webcam Stopped!")
133
+
134
+ webcam.release()
assets/Objdetectionyoutubegif-1.m4v ADDED
Binary file (528 kB). View file
 
assets/pic1.png ADDED
assets/pic3.png ADDED
assets/segmentation.png ADDED
helper.py ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from ultralytics import YOLO
2
+ import streamlit as st
3
+ import cv2
4
+ import pafy
5
+
6
+ import settings
7
+
8
+ def load_model(model_path):
9
+ model = YOLO(model_path)
10
+ return model
11
+
12
+ def _display_detected_frames(conf, model, st_frame, image):
13
+ # Resize the image to a standard size
14
+ image = cv2.resize(image, (720, int(720*(9/16))))
15
+
16
+ # Predict the objects in the image using the YOLOv9 model
17
+ res = model.predict(image, conf=conf)
18
+
19
+ # Plot the detected objects on the video frame
20
+ res_plotted = res[0].plot()
21
+ st_frame.image(res_plotted,
22
+ caption='Detected Video',
23
+ channels="BGR",
24
+ use_column_width=True
25
+ )
26
+
27
+ def play_youtube_video(conf, model):
28
+ source_youtube = st.sidebar.text_input("YouTube Video url")
29
+ if st.sidebar.button('Detect Objects'):
30
+ try:
31
+ video = pafy.new(source_youtube)
32
+ best = video.getbest(preftype="mp4")
33
+ vid_cap = cv2.VideoCapture(best.url)
34
+ st_frame = st.empty()
35
+ while (vid_cap.isOpened()):
36
+ success, image = vid_cap.read()
37
+ if success:
38
+ _display_detected_frames(conf,
39
+ model,
40
+ st_frame,
41
+ image,
42
+ )
43
+ else:
44
+ vid_cap.release()
45
+ break
46
+ except Exception as e:
47
+ st.sidebar.error("Error loading video: " + str(e))
48
+
49
+ def play_stored_video(conf, model):
50
+ source_vid = st.sidebar.selectbox(
51
+ "Choose a video...", settings.VIDEOS_DICT.keys())
52
+ with open(settings.VIDEOS_DICT.get(source_vid), 'rb') as video_file:
53
+ video_bytes = video_file.read()
54
+
55
+ if video_bytes:
56
+ st.video(video_bytes)
57
+ if st.sidebar.button('Detect Video Objects'):
58
+ try:
59
+ vid_cap = cv2.VideoCapture(
60
+ str(settings.VIDEOS_DICT.get(source_vid)))
61
+ st_frame = st.empty()
62
+ while (vid_cap.isOpened()):
63
+ success, image = vid_cap.read()
64
+ if success:
65
+ _display_detected_frames(conf,
66
+ model,
67
+ st_frame,
68
+ image,
69
+ )
70
+ else:
71
+ vid_cap.release()
72
+ break
73
+ except Exception as e:
74
+ st.sidebar.error("Error loading video: " + str(e))
packages.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ freeglut3-dev
2
+ libgtk2.0-dev
3
+ libgl1-mesa-glx
requirements.txt ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ altair==5.2.0
2
+ attrs==23.2.0
3
+ blinker==1.7.0
4
+ cachetools==5.3.3
5
+ certifi==2024.2.2
6
+ charset-normalizer==3.3.2
7
+ click==8.1.7
8
+ contourpy==1.2.0
9
+ cycler==0.12.1
10
+ filelock==3.13.1
11
+ fonttools==4.50.0
12
+ fsspec==2024.3.1
13
+ gitdb==4.0.11
14
+ GitPython==3.1.42
15
+ idna==3.6
16
+ Jinja2==3.1.3
17
+ jsonschema==4.21.1
18
+ jsonschema-specifications==2023.12.1
19
+ kiwisolver==1.4.5
20
+ markdown-it-py==3.0.0
21
+ MarkupSafe==2.1.5
22
+ matplotlib==3.8.3
23
+ mdurl==0.1.2
24
+ mpmath==1.3.0
25
+ networkx==3.2.1
26
+ numpy==1.26.4
27
+ nvidia-cublas-cu12==12.1.3.1
28
+ nvidia-cuda-cupti-cu12==12.1.105
29
+ nvidia-cuda-nvrtc-cu12==12.1.105
30
+ nvidia-cuda-runtime-cu12==12.1.105
31
+ nvidia-cudnn-cu12==8.9.2.26
32
+ nvidia-cufft-cu12==11.0.2.54
33
+ nvidia-curand-cu12==10.3.2.106
34
+ nvidia-cusolver-cu12==11.4.5.107
35
+ nvidia-cusparse-cu12==12.1.0.106
36
+ nvidia-nccl-cu12==2.19.3
37
+ nvidia-nvjitlink-cu12==12.4.99
38
+ nvidia-nvtx-cu12==12.1.105
39
+ opencv-python==4.9.0.80
40
+ packaging==23.2
41
+ pandas==2.2.1
42
+ pillow==10.2.0
43
+ protobuf==4.25.3
44
+ psutil==5.9.8
45
+ py-cpuinfo==9.0.0
46
+ pyarrow==15.0.2
47
+ pydeck==0.8.1b0
48
+ Pygments==2.17.2
49
+ pyparsing==3.1.2
50
+ python-dateutil==2.9.0.post0
51
+ pytz==2024.1
52
+ PyYAML==6.0.1
53
+ referencing==0.34.0
54
+ requests==2.31.0
55
+ rich==13.7.1
56
+ rpds-py==0.18.0
57
+ scipy==1.12.0
58
+ seaborn==0.13.2
59
+ six==1.16.0
60
+ smmap==5.0.1
61
+ streamlit==1.32.2
62
+ sympy==1.12
63
+ tenacity==8.2.3
64
+ thop==0.1.1.post2209072238
65
+ toml==0.10.2
66
+ toolz==0.12.1
67
+ torch==2.2.1
68
+ torchvision==0.17.1
69
+ tornado==6.4
70
+ tqdm==4.66.2
71
+ triton==2.2.0
72
+ typing_extensions==4.10.0
73
+ tzdata==2024.1
74
+ ultralytics==8.1.30
75
+ urllib3==2.2.1
76
+ watchdog==4.0.0
77
+ pafy
78
+ youtube-dl
settings.py ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pathlib import Path
2
+ import sys
3
+
4
+ # Get the absolute path of the current file
5
+ file_path = Path(__file__).resolve()
6
+
7
+ # Get the parent directory of the current file
8
+ root_path = file_path.parent
9
+
10
+ # Add the root path to the sys.path list if it is not already there
11
+ if root_path not in sys.path:
12
+ sys.path.append(str(root_path))
13
+
14
+ # Get the relative path of the root directory with respect to the current working directory
15
+ ROOT = root_path.relative_to(Path.cwd())
16
+
17
+ # Sources
18
+ IMAGE = 'Image'
19
+ VIDEO = 'Video'
20
+ YOUTUBE = 'YouTube'
21
+ WEBCAM = 'Webcam'
22
+ SOURCES_LIST = [IMAGE, VIDEO, YOUTUBE, WEBCAM]
23
+
24
+ # Images config
25
+ IMAGES_DIR = ROOT / 'images'
26
+ DEFAULT_IMAGE = IMAGES_DIR / 'office_4.jpg'
27
+ DEFAULT_DETECT_IMAGE = IMAGES_DIR / 'office_4_detected.jpg'
28
+
29
+ # Videos config
30
+ VIDEO_DIR = ROOT / 'videos'
31
+ VIDEO_1_PATH = VIDEO_DIR / 'video_1.mp4'
32
+ VIDEO_2_PATH = VIDEO_DIR / 'video_2.mp4'
33
+ VIDEO_3_PATH = VIDEO_DIR / 'video_3.mp4'
34
+ VIDEO_4_PATH = VIDEO_DIR / 'video_4.mp4'
35
+ VIDEO_5_PATH = VIDEO_DIR / 'video_5.mp4'
36
+ VIDEOS_DICT = {
37
+ 'video_1': VIDEO_1_PATH,
38
+ 'video_2': VIDEO_2_PATH,
39
+ 'video_3': VIDEO_3_PATH,
40
+ 'video_4': VIDEO_4_PATH,
41
+ 'video_5': VIDEO_5_PATH,
42
+ }
43
+
44
+ # ML Model config
45
+ MODEL_DIR = ROOT / 'weights'
46
+ DETECTION_MODEL = MODEL_DIR / 'yolov9c.pt'
47
+ SEGMENTATION_MODEL = MODEL_DIR / 'yolov9c-seg.pt'