|
import pandas as pd |
|
import os |
|
from PIL import Image |
|
import numpy as np |
|
import torch |
|
import matplotlib.pyplot as plt |
|
from IPython import get_ipython |
|
import sys |
|
import gc |
|
import streamlit as st |
|
from typing import Tuple, Dict, List, Union |
|
|
|
|
|
def show_image(image: Union[str, Image.Image, np.ndarray, torch.Tensor]) -> None: |
|
""" |
|
Display an image in various environments (Jupyter, PyCharm, Hugging Face Spaces). |
|
Handles different types of image inputs (file path, PIL Image, numpy array, PyTorch tensor). |
|
|
|
Args: |
|
image (Union[str, Image.Image, np.ndarray, torch.Tensor]): The image to display. |
|
|
|
Returns: |
|
None |
|
""" |
|
|
|
in_jupyter = is_jupyter_notebook() |
|
in_colab = is_google_colab() |
|
|
|
|
|
if isinstance(image, str): |
|
|
|
if os.path.isfile(image): |
|
image = Image.open(image) |
|
else: |
|
raise ValueError("File path provided does not exist.") |
|
elif isinstance(image, np.ndarray): |
|
|
|
if image.ndim == 3 and image.shape[2] in [3, 4]: |
|
|
|
image = Image.fromarray(image[..., ::-1] if image.shape[2] == 3 else image) |
|
else: |
|
|
|
image = Image.fromarray(image) |
|
elif torch.is_tensor(image): |
|
|
|
image = Image.fromarray(image.permute(1, 2, 0).numpy().astype(np.uint8)) |
|
|
|
|
|
if in_jupyter or in_colab: |
|
|
|
from IPython.display import display |
|
display(image) |
|
else: |
|
|
|
image.show() |
|
|
|
|
|
|
|
def show_image_with_matplotlib(image: Union[str, Image.Image, np.ndarray, torch.Tensor]) -> None: |
|
""" |
|
Display an image using Matplotlib. |
|
|
|
Args: |
|
image (Union[str, Image.Image, np.ndarray, torch.Tensor]): The image to display. |
|
|
|
Returns: |
|
None |
|
""" |
|
|
|
if isinstance(image, str): |
|
image = Image.open(image) |
|
elif isinstance(image, np.ndarray): |
|
image = Image.fromarray(image) |
|
elif torch.is_tensor(image): |
|
image = Image.fromarray(image.permute(1, 2, 0).numpy().astype(np.uint8)) |
|
|
|
plt.imshow(image) |
|
plt.axis('off') |
|
plt.show() |
|
|
|
|
|
def is_jupyter_notebook() -> bool: |
|
""" |
|
Check if the code is running in a Jupyter notebook. |
|
|
|
Returns: |
|
bool: True if running in a Jupyter notebook, False otherwise. |
|
""" |
|
try: |
|
from IPython import get_ipython |
|
if 'IPKernelApp' not in get_ipython().config: |
|
return False |
|
if 'ipykernel' in str(type(get_ipython())): |
|
return True |
|
except (NameError, AttributeError): |
|
return False |
|
|
|
return False |
|
|
|
|
|
def is_pycharm() -> bool: |
|
""" |
|
Check if the code is running in PyCharm. |
|
|
|
Returns: |
|
bool: True if running in PyCharm, False otherwise. |
|
""" |
|
|
|
return 'PYCHARM_HOSTED' in os.environ |
|
|
|
|
|
def is_google_colab() -> bool: |
|
""" |
|
Check if the code is running in Google Colab. |
|
|
|
Returns: |
|
bool: True if running in Google Colab, False otherwise. |
|
""" |
|
|
|
return 'COLAB_GPU' in os.environ or 'google.colab' in sys.modules |
|
|
|
|
|
def get_image_path(name: str, path_type: str) -> str: |
|
""" |
|
Generates a path for models, images, or data based on the specified type. |
|
|
|
Args: |
|
name (str): The name of the model, image, or data folder/file. |
|
path_type (str): The type of path needed ('models', 'images', or 'data'). |
|
|
|
Returns: |
|
str: The full path to the specified resource. |
|
""" |
|
|
|
|
|
current_dir = os.getcwd() |
|
|
|
|
|
parent_dir = os.path.dirname(current_dir) |
|
|
|
|
|
folder_path = os.path.join(parent_dir, path_type) |
|
|
|
|
|
full_path = os.path.join(folder_path, name) |
|
|
|
return full_path |
|
|
|
|
|
def get_model_path(model_name: str) -> str: |
|
""" |
|
Get the path to the specified model folder. |
|
|
|
Args: |
|
model_name (str): Name of the model folder. |
|
|
|
Returns: |
|
str: Absolute path to the specified model folder. |
|
""" |
|
|
|
|
|
current_script_dir = os.path.dirname(os.path.abspath(__file__)) |
|
|
|
|
|
app_dir = os.path.dirname(os.path.dirname(current_script_dir)) |
|
|
|
|
|
model_path = os.path.join(app_dir, "models", model_name) |
|
|
|
return model_path |
|
|
|
def add_detected_objects_to_dataframe(df: pd.DataFrame, detector_type: str, image_directory: str, detector: object) -> pd.DataFrame: |
|
""" |
|
Adds a column to the DataFrame with detected objects for each image specified in the 'image_name' column. |
|
Prints a message every 200 images processed. |
|
|
|
Args: |
|
df (pd.DataFrame): DataFrame containing a column 'image_name' with image filenames. |
|
detector_type (str): The detection model to use ('detic' or 'yolov5'). |
|
image_directory (str): Path to the directory containing images. |
|
detector (object): An instance of the ObjectDetector class. |
|
|
|
Returns: |
|
pd.DataFrame: The original DataFrame with an additional column 'detected_objects'. |
|
""" |
|
|
|
|
|
if 'image_name' not in df.columns: |
|
raise ValueError("DataFrame must contain an 'image_name' column.") |
|
|
|
detector.load_model(detector_type) |
|
|
|
|
|
images_processed = 0 |
|
|
|
|
|
def detect_objects_for_image(image_name): |
|
nonlocal images_processed |
|
image_path = os.path.join(image_directory, image_name) |
|
if os.path.exists(image_path): |
|
|
|
image = detector.process_image(image_path) |
|
detected_objects_str, _ = detector.detect_objects(image, 0.2) |
|
images_processed += 1 |
|
|
|
|
|
if images_processed % 200 == 0: |
|
print(f"Completed {images_processed} images detection") |
|
|
|
return detected_objects_str |
|
else: |
|
images_processed += 1 |
|
return "Image not found" |
|
|
|
|
|
df[detector.model_name] = df['image_name'].apply(detect_objects_for_image) |
|
|
|
return df |
|
|
|
|
|
|
|
def free_gpu_resources() -> None: |
|
""" |
|
Clears GPU memory. |
|
|
|
Returns: |
|
None |
|
""" |
|
|
|
if torch.cuda.is_available(): |
|
torch.cuda.empty_cache() |
|
torch.cuda.empty_cache() |
|
gc.collect() |
|
gc.collect() |
|
|
|
|