Skip to content
This repository was archived by the owner on Nov 13, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions modules/detect_target/detect_target_contour.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,17 @@
MIN_CONTOUR_AREA = 100
MAX_CIRCULARITY = 1.3
MIN_CIRCULARITY = 0.7

UPPER_BLUE = np.array([130, 255, 255])
LOWER_BLUE = np.array([100, 50, 50])

CONFIDENCE = 1.0
LABEL = 0


class DetectTargetContour(base_detect_target.BaseDetectTarget):
"""
Predicts annd locates landing pads using the classical computer vision methodology.
Predicts and locates landing pads using the classical computer vision methodology.
"""

def __init__(
Expand All @@ -49,7 +51,7 @@ def detect_landing_pads_contours(
"""
Detects landing pads using contours/classical CV.

image: Current image frame.
image_and_time_data: Data for the current image and time.
timestamp: Timestamp for the detections.

Return: Success, the DetectionsAndTime object, and the annotated image.
Expand Down
63 changes: 20 additions & 43 deletions tests/unit/generate_detect_target_contour.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import numpy as np

from modules import detections_and_time
from modules import image_and_time


LANDING_PAD_COLOUR_BLUE = (100, 50, 50) # BGR
Expand Down Expand Up @@ -57,56 +58,27 @@ class BoundingBox:

def __init__(self, top_left: tuple[float, float], bottom_right: tuple[float, float]):
"""
top_left: pixel coordinates representing the top left corner of the bounding box on an image.
top_left: The pixel coordinates representing the top left corner of the bounding box on an image.
bottom_right: pixel coordinates representing the bottom right corner of the bounding box on an image.
"""
self.top_left = top_left
self.bottom_right = bottom_right


class InputImageAndExpectedBoundingBoxes:
class InputImageAndTimeAndExpectedBoundingBoxes:
"""
Struct to hold the data needed to perform the tests.
"""

def __init__(self, image: np.ndarray, boxes_list: np.ndarray):
def __init__(self, image_and_time_data: image_and_time.ImageAndTime, bounding_box_list: list):
"""
image: A numpy array that represents the image needed to be tested.
bounding_box_list: A numpy array that holds a list of expected bounding box coordinates.

The bounding box coordinates are in the following format:
top_left_x = boxes_list[0]
top_left_y = boxes_list[1]

bottom_right_x = boxes_list[2]
bottom_right_x = boxes_list[3]
image_and_time_data: ImageAndTime object containing the image and timestamp
bounding_box_list: A list that holds expected bounding box coordinates.
Given in the following format:
[conf, label, top_left_x, top_left_y, bottom_right_x, bottom_right_y]
"""
self.image = image
self.bounding_box_list = boxes_list


def create_detections(detections_from_file: np.ndarray) -> detections_and_time.DetectionsAndTime:
"""
Create DetectionsAndTime from expected.
Format: [confidence, label, x_1, y_1, x_2, y_2] .
"""
assert detections_from_file.shape[1] == 6

result, detections = detections_and_time.DetectionsAndTime.create(0)
assert result
assert detections is not None

for i in range(0, detections_from_file.shape[0]):
result, detection = detections_and_time.Detection.create(
detections_from_file[i][2:],
int(detections_from_file[i][1]),
detections_from_file[i][0],
)
assert result
assert detection is not None
detections.append(detection)

return detections
self.image_and_time_data = image_and_time_data
self.bounding_box_list = bounding_box_list


def add_blurred_landing_pad(
Expand Down Expand Up @@ -168,7 +140,7 @@ def draw_landing_pad(
width = 2 * math.sqrt(ux**2 + vx**2)
height = 2 * math.sqrt(uy**2 + vy**2)

top_left = (int(max(centre_x - (0.5) * width, 0)), int(max(centre_y - (0.5) * height, 0)))
top_left = (max(centre_x - (0.5) * width, 0), max(centre_y - (0.5) * height, 0))
bottom_right = (
min(centre_x + (0.5) * width, image.shape[1]),
min(centre_y + (0.5) * height, image.shape[0]),
Expand All @@ -193,15 +165,17 @@ def draw_landing_pad(
return NumpyImage(image), bounding_box


def create_test(landing_list: list[LandingPadImageConfig]) -> InputImageAndExpectedBoundingBoxes:
def create_test(
landing_list: list[LandingPadImageConfig],
) -> InputImageAndTimeAndExpectedBoundingBoxes:
"""
Generates test cases given a data set.

landing_list: List of landing pad data to be generated.

Returns: The image and expected bounding box.
"""
image = np.full(shape=(1000, 2000, 3), fill_value=255, dtype=np.int8)
image = np.full(shape=(1000, 2000, 3), fill_value=255, dtype=np.uint8)
confidence_and_label = [1, 0]

# List to hold the bounding boxes.
Expand All @@ -220,7 +194,10 @@ def create_test(landing_list: list[LandingPadImageConfig]) -> InputImageAndExpec
boxes_list, reverse=True, key=lambda box: abs((box[4] - box[2]) * (box[5] - box[3]))
)

boxes_list = np.array(boxes_list)
image = image.astype(np.uint8)
result, image_and_time_data = image_and_time.ImageAndTime.create(image)

assert result
assert image_and_time_data is not None

return InputImageAndExpectedBoundingBoxes(image, boxes_list)
return InputImageAndTimeAndExpectedBoundingBoxes(image_and_time_data, boxes_list)
Loading
Loading