-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Created FakeDetector and FakeGroundTruthDatareader, need to revise datareaders structure and layout(groundtruth) file format #5
base: main
Are you sure you want to change the base?
Changes from 6 commits
f5ba254
5f96140
7a4a98e
4a15d93
3bb242f
0c37522
7f12459
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import cv2 as cv | ||
from ..utils.data_reader import DataReader, GroundtruthReader, FakeGTReader | ||
from ..vehicle_detector.fake_detector import FakeDetector | ||
import random | ||
# class PseudoDetector: | ||
# def __init__(self, annotation_file): | ||
# self.frame_annotations = self.__rd_form_ret_annotations(annotation_file) | ||
# def __rd_form_ret_annotations(self, annotation_file): | ||
# rand_bias = self.__get_random_bias() | ||
# frame_annotations = {} | ||
# with open(annotation_file, 'r') as file: | ||
# annotations = file.readlines() | ||
|
||
# for line in annotations: | ||
# parts = line.strip().split() | ||
# frame_idx = int(parts[0]) | ||
# label = parts[1] | ||
# x1, y1 = int(parts[2]) + rand_bias, int(parts[3]) - rand_bias | ||
# x2, y2 = int(parts[4]) - rand_bias, int(parts[5]) + rand_bias | ||
|
||
# if frame_idx not in frame_annotations: | ||
# frame_annotations[frame_idx] = [] | ||
# frame_annotations[frame_idx].append((label, x1, y1, x2, y2)) | ||
# return frame_annotations | ||
|
||
# def __get_random_bias(self): | ||
# random.seed() | ||
# return random.randint(10, 15) | ||
|
||
|
||
|
||
# def get_annotations(self): | ||
# return self.frame_annotations | ||
|
||
class Visualize: | ||
def __init__(self, datareader:DataReader, detector:FakeDetector, gt_path:str): | ||
self.datareader = datareader | ||
self.detector = detector | ||
self.gt_data = FakeGTReader().read() | ||
def show(self): | ||
try: | ||
frame_idx = 0 | ||
for image in self.datareader: | ||
if image is None: | ||
break | ||
|
||
for box in self.detector.detect(image): | ||
self.__draw_box(image, box, (255, 0, 0)) | ||
|
||
if self.gt_data: | ||
for box in self.__format_groundtruth(frame_idx): | ||
self.__draw_box(image, box, (0, 255, 0)) | ||
|
||
frame_idx+=1 | ||
if cv.waitKey(25) & 0xFF == ord('q'): | ||
break | ||
except Exception as e: | ||
print(f"An error occurred: {e}") | ||
finally: | ||
cv.destroyAllWindows() | ||
|
||
def __draw_box(self, image, box, color): | ||
label, x1, y1, x2, y2 = box | ||
cv.rectangle(image, (x1, y1), (x2, y2), color, 2) | ||
cv.putText(image, label, (x1, y1 - 10), cv.FONT_HERSHEY_SIMPLEX, 0.5, color, 2) | ||
cv.imshow("Image", image) | ||
|
||
def __format_groundtruth(self, frame_idx): | ||
|
||
return [item[1:] for item in self.gt_data if item[0] == frame_idx] | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,147 @@ | ||
import csv | ||
import cv2 as cv | ||
import os | ||
from abc import ABC, abstractmethod | ||
import random | ||
class DataReader(ABC): | ||
@abstractmethod | ||
def __iter__(self): | ||
pass | ||
|
||
@abstractmethod | ||
def __next__(self): | ||
pass | ||
|
||
class GroundtruthReader: | ||
@staticmethod | ||
def create(mode, dir_path): | ||
if mode == "video": | ||
return VideoDataReader(dir_path) | ||
elif mode == "image": | ||
return ImgDataReader(dir_path) | ||
elif mode == "groundtruth": | ||
return GroundtruthReader(dir_path) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Удалить |
||
else: | ||
raise ValueError(f"Unsupported mode: {mode}") | ||
|
||
class VideoDataReader(DataReader): | ||
|
||
def __init__(self, video_path): | ||
self.video_path = video_path | ||
self.cap = cv.VideoCapture(video_path) | ||
if not self.cap.isOpened(): | ||
raise ValueError(f"Cannot open video file: {video_path}") | ||
|
||
|
||
def __iter__(self): | ||
return self | ||
|
||
def __next__(self): | ||
if self.cap.isOpened(): | ||
ret, frame = self.cap.read() | ||
if ret: | ||
return frame | ||
else: | ||
self.cap.release() | ||
raise StopIteration | ||
else: | ||
raise StopIteration | ||
|
||
class ImgDataReader(DataReader): | ||
def __init__(self, dir_path): | ||
self.index = 0 | ||
self.directory_path = dir_path | ||
if not os.path.exists(dir_path): | ||
raise ValueError(f"Directory does not exist: {dir_path}") | ||
self.image_files = [ | ||
os.path.join(dir_path, f) for f in os.listdir(dir_path) | ||
if f.lower().endswith((".png", ".jpg", ".jpeg", ".bmp", ".tiff")) | ||
] | ||
|
||
def __iter__(self): | ||
return self | ||
|
||
def __next__(self): | ||
if self.index < len(self.image_files): | ||
img_path = self.image_files[self.index] | ||
self.index += 1 | ||
img = cv.imread(img_path) | ||
if img is None: | ||
raise ValueError(f"Cannot read image file: {img_path}") | ||
return img | ||
else: | ||
raise StopIteration | ||
|
||
class FakeGTReader(): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Реализовать наследника от |
||
def __init__( | ||
self, | ||
total_frames: int = 1000, | ||
prob_missing: float = 0.5, | ||
image_width: int = 1920, | ||
image_height: int = 1080, | ||
max_objects_per_frame: int = 5, | ||
seed: int = None | ||
): | ||
self.total_frames = total_frames | ||
self.prob_missing = prob_missing | ||
self.image_width = image_width | ||
self.image_height = image_height | ||
self.max_objects_per_frame = max_objects_per_frame | ||
self.labels = ['car', 'truck', 'bus'] | ||
|
||
if seed is not None: | ||
random.seed(seed) | ||
|
||
def __generate_bbox(self): | ||
"""Генерация случайного bounding box.""" | ||
x = random.randint(0, self.image_width - 1) | ||
y = random.randint(0, self.image_height - 1) | ||
w = random.randint(1, self.image_width - x) | ||
h = random.randint(1, self.image_height - y) | ||
return (x, y, h, w) | ||
|
||
def read(self, file_path:str = None): | ||
parsed_data = list() | ||
if (file_path): | ||
try: | ||
with open(file_path, 'r') as file: | ||
annotations = file.readlines() | ||
|
||
for line in annotations: | ||
|
||
parts = line.strip().split() | ||
|
||
frame_idx = int(parts[0]) | ||
label = parts[1] | ||
x1, y1 = int(parts[2]), int(parts[3]) | ||
x2, y2 = int(parts[4]), int(parts[5]) | ||
|
||
|
||
row_data = (frame_idx, label, x1, y1, x2, y2) | ||
parsed_data.append(row_data) | ||
return parsed_data | ||
except FileNotFoundError: | ||
print(f"File {file_path} was not found.") | ||
except Exception as e: | ||
print(f"Error when reading the file {file_path}: {e}") | ||
|
||
|
||
else: | ||
for frame in range(self.total_frames): | ||
|
||
if random.random() < self.prob_missing: | ||
continue | ||
|
||
|
||
num_objects = random.randint(0, self.max_objects_per_frame) | ||
for _ in range(num_objects): | ||
label = random.choice(self.labels) | ||
x, y, h, w = self.__generate_bbox() | ||
parsed_data.append((frame, label, x, y, h, w)) | ||
|
||
return parsed_data | ||
|
||
|
||
class GroundtruthReader(): | ||
@staticmethod | ||
def read(file_path): | ||
""" | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import cv2 as cv | ||
import random | ||
from abc import ABC, abstractmethod | ||
class Detector(ABC): | ||
@abstractmethod | ||
def detect(image): | ||
pass | ||
@staticmethod | ||
def create(mode): | ||
if mode == "vehicle": | ||
return VehicleDetector() | ||
elif mode == "fake": | ||
return FakeDetector(42) | ||
else: | ||
raise ValueError(f"Unsupported mode: {mode}") | ||
|
||
class VehicleDetector(Detector): | ||
def __init__(self): | ||
pass | ||
def detect(image): | ||
pass | ||
class FakeDetector(Detector): | ||
def __init__(self, seed = None): | ||
if seed is not None: | ||
random.seed(seed) | ||
|
||
@staticmethod | ||
def detect(image): | ||
if image is None or image.size == 0: | ||
return [] | ||
height, width = image.shape[:2] | ||
bboxes = [] | ||
num_boxes = random.randint(0, 7) | ||
|
||
for _ in range(num_boxes): | ||
if width < 2 or height < 2: | ||
continue | ||
cl = random.choice(["car", "bus", "truck"]) | ||
x1 = random.randint(0, width - 2) | ||
x2 = random.randint(x1 + 1, width - 1) | ||
|
||
y1 = random.randint(0, height - 2) | ||
y2 = random.randint(y1 + 1, height - 1) | ||
|
||
bboxes.append((cl, x1, y1, x2, y2)) | ||
|
||
return bboxes |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import sys | ||
import os | ||
|
||
project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) | ||
sys.path.append(project_root) | ||
|
||
from src.gui_application.visualizer import Visualize | ||
from src.utils.data_reader import DataReader, GroundtruthReader | ||
from src.vehicle_detector.detector import Detector | ||
import datetime | ||
import argparse | ||
import os | ||
from PIL import Image | ||
|
||
import cv2 as cv | ||
import numpy as np | ||
|
||
def cli_argument_parser(): | ||
parser = argparse.ArgumentParser() | ||
|
||
parser.add_argument('-t', '--mode', | ||
help='Mode (\'image\', \'video\')', | ||
type=str, | ||
dest='mode', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. choices=['image', 'video'], |
||
required=True) | ||
parser.add_argument('-v', '--video', | ||
help='Path to a video file', | ||
type=str, | ||
dest='video_path') | ||
parser.add_argument('-i', '--image', | ||
help='Path to images', | ||
type=str, | ||
dest='images_path') | ||
parser.add_argument('-g', '--groundtruth', | ||
help='Path to a file of groundtruth', | ||
type=str, | ||
dest='groundtruth_path', | ||
required=False) | ||
parser.add_argument('-m', '--model', | ||
help='Path to a model', | ||
type=str, | ||
dest='model_path', | ||
required=True, | ||
default=None) | ||
|
||
|
||
args = parser.parse_args() | ||
return args | ||
|
||
#некоторое подобие main | ||
def main(): | ||
args = cli_argument_parser() | ||
reader = DataReader.create( args.mode, (args.video_path or args.images_path) ) | ||
adapter = None | ||
detector = Detector.create( "fake" ) | ||
visualizer = Visualize( reader, detector, args.groundtruth_path ) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. visualizer = Visualize( reader, detector, GroundtruthReader.read(args.groundtruth_path) ) |
||
visualizer.show() | ||
|
||
if __name__ == '__main__': | ||
main() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
присваивание