Skip to content
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

feat(tagdetector): add #1

Merged
merged 1 commit into from
Apr 26, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
131 changes: 131 additions & 0 deletions src/mentabotix/tools/algrithm_tools.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
from random import choice
from typing import Tuple


# region Multiplier Generator
FLOAT_SET_UPPER = (0.9, 0.925, 0.95, 1.0, 1.05, 1.08, 1.1, 1.17, 1.25)

FLOAT_SET_LOWER = (0.8, 0.825, 0.85, 0.875, 0.9, 0.925, 0.95, 1.0, 1.05, 1.08, 1.1)

FLOAT_SET_MIDDLE = (0.8, 0.85, 0.9, 0.95, 1.0, 1.05, 1.1, 1.17, 1.25)

SHRINK_SET_LLL = (0.40, 0.5, 0.525, 0.55, 0.5625, 0.575, 0.5875, 0.6)

SHRINK_SET_LL = (0.55, 0.6, 0.625, 0.65, 0.6625, 0.675, 0.6875, 0.7)

SHRINK_SET_L = (0.65, 0.7, 0.725, 0.7375, 0.75, 0.7625, 0.775, 0.7875, 0.8)

ENLARGE_SET_L = (1.25, 1.275, 1.3, 1.325, 1.35, 1.375, 1.4, 1.45, 1.5)
ENLARGE_SET_LL = (1.5, 1.525, 1.55, 1.575, 1.6, 1.625, 1.65, 1.7, 1.75)

ENLARGE_SET_LLL = (1.75, 1.775, 1.8, 1.825, 1.85, 1.875, 1.9, 1.95, 2.0, 2.1, 2.2, 2.4)


def enlarge_multiplier_l() -> float:
"""
Generate a multiplier for enlargement in a lower range.

Returns:
float: The randomly generated multiplier for enlargement in a lower range.
"""
return choice(ENLARGE_SET_L)


def enlarge_multiplier_ll() -> float:
"""
Generate a multiplier for enlargement in a middle range.

Returns:
float: The randomly generated multiplier for enlargement in a middle range.
"""
return choice(ENLARGE_SET_LL)


def enlarge_multiplier_lll() -> float:
"""
Generate a multiplier for enlargement in an upper range.

Returns:
float: The randomly generated multiplier for enlargement in an upper range.
"""
return choice(ENLARGE_SET_LLL)


def shrink_multiplier_l() -> float:
"""
Generate a multiplier for shrinkage in a lower range.

Returns:
float: The randomly generated multiplier for shrinkage in a lower range.
"""
return choice(SHRINK_SET_L)


def shrink_multiplier_ll() -> float:
"""
Generate a multiplier for shrinkage in a middle range.

Returns:
float: The randomly generated multiplier for shrinkage in a middle range.
"""
return choice(SHRINK_SET_LL)


def shrink_multiplier_lll() -> float:
"""
Generate a multiplier for shrinkage in the upper range.

Returns:
float: The randomly generated multiplier for shrinkage in the upper range.
"""
return choice(SHRINK_SET_LLL)


def float_multiplier_middle() -> float:
"""
Generate a float multiplier in a middle range.

Returns:
float: The randomly generated float multiplier in a middle range.
"""
return choice(FLOAT_SET_MIDDLE)


def float_multiplier_lower() -> float:
"""
Generate a float multiplier in a lower range.

Returns:
float: The randomly generated float multiplier in a lower range.
"""
return choice(FLOAT_SET_LOWER)


def float_multiplier_upper() -> float:
"""
Generate a float multiplier in an upper range.
Returns:
float: The randomly generated float multiplier in the upper range.
"""
return choice(FLOAT_SET_UPPER)


# endregion
Location = Tuple[int | float, int | float]


def calc_p2p_dst(point_1: Location, point_2: Location) -> float:
return ((point_1[0] - point_2[0]) ** 2 + (point_1[1] - point_2[1]) ** 2) ** 0.5


def calc_p2p_error(start: Location, target: Location) -> float | int:
"""
drik distance
Args:
start:
target:

Returns:

"""
return abs(target[0] - start[0]) + abs(target[1] - start[0])
165 changes: 165 additions & 0 deletions src/mentabotix/vision/camra.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
import warnings
from time import time
from typing import Tuple, Optional, List

import cv2


class Camera(object):

def __init__(self, device_id: int = 0):
# 使用 cv2.VideoCapture(0) 创建视频捕获对象,从默认摄像头捕获视频。
self._frame_center: Optional[Tuple[int, int]] = None
self._origin_fps: Optional[int] = None
self._origin_height: Optional[float] = None
self._origin_width: Optional[float] = None
self._camera: Optional[cv2.VideoCapture] = None
self.open_camera(device_id)

def open_camera(self, device_id):
"""
open the cam with self-check
Args:
device_id:

Returns:

"""
self._camera = cv2.VideoCapture(device_id)
read_status, _ = self._camera.read()
if read_status:
self._origin_width: int = int(self._camera.get(cv2.CAP_PROP_FRAME_WIDTH))
self._origin_height: int = int(self._camera.get(cv2.CAP_PROP_FRAME_HEIGHT))
self._origin_fps: int = int(self._camera.get(cv2.CAP_PROP_FPS))
self._frame_center: Tuple = (int(self._origin_width / 2), int(self._origin_height / 2))
print(f"CAMERA RESOLUTION:{int(self._origin_width)}x{int(self._origin_height)}\n"
f"CAMERA FPS: [{self._origin_fps}]\n"
f"CAM CENTER: [{self._frame_center}]")
else:
warnings.warn('########CAN\'T GET VIDEO########\n'
'please check if the camera is attached!')

def close_camera(self):
"""
release the cam
Returns:

"""
self._camera.release()
self._camera = None

@property
def origin_width(self):
"""
the origin width of the cam
Returns:

"""
return self._origin_width

@property
def origin_height(self):
"""
the origin height of the cam
Returns:

"""
return self._origin_height

@property
def origin_fps(self):
"""
the fps of the cam
Returns:

"""
return self._origin_fps

@property
def frame_center(self) -> Tuple[int, int]:
"""
the pixel of the frame center
Returns:

"""
return self._frame_center

def _update_cam_center(self) -> None:
width = self._camera.get(cv2.CAP_PROP_FRAME_WIDTH)
height = self._camera.get(cv2.CAP_PROP_FRAME_HEIGHT)
self._frame_center = (int(width / 2), int(height / 2))

def set_cam_resolution(self, new_width: Optional[int] = None, new_height: Optional[int] = None,
resolution_multiplier: Optional[float] = None) -> None:
if not self._camera.isOpened():
warnings.warn("##CAN'T CHANGE the RESOLUTION##\n"
"because the camera is NOT opened\n\n")
return
assert (new_width is not None and new_height is not None) or (
resolution_multiplier is not None), 'Please specify the resolution params'
if resolution_multiplier:
self._camera.set(cv2.CAP_PROP_FRAME_WIDTH, int(resolution_multiplier * self._origin_width))
self._camera.set(cv2.CAP_PROP_FRAME_HEIGHT, int(resolution_multiplier * self._origin_height))
else:
self._camera.set(cv2.CAP_PROP_FRAME_WIDTH, new_width)
self._camera.set(cv2.CAP_PROP_FRAME_HEIGHT, new_height)
self._update_cam_center()

@property
def camera_device(self) -> cv2.VideoCapture:
"""
the device instance
Returns:

"""
return self._camera

def test_frame_time(self, test_frames_count: int = 600) -> float:
"""
test the frame time on the given count and return the average value of it
:param test_frames_count:
:return:
"""
from timeit import repeat
from numpy import mean, std
durations: List[float] = repeat(stmt=self._camera.read, number=1, repeat=test_frames_count)
hall_duration: float = sum(durations)
average_duration: float = float(mean(hall_duration))
std_error = std(a=durations, ddof=1)
print("Frame Time Test Results: \n"
f"\tRunning on [{test_frames_count}] frame updates\n"
f"\tTotal Time Cost: [{hall_duration}]\n"
f"\tAverage Frame time: [{average_duration}]\n"
f"\tStd Error: [{std_error}]\n")
return average_duration

def record_video(self, save_path: str, video_length: float):
end_time = time() + video_length

fourcc = cv2.VideoWriter_fourcc(*'mp4v')

writer = cv2.VideoWriter(save_path,
fourcc,
self._origin_fps,
(int(self._camera.get(cv2.CAP_PROP_FRAME_WIDTH)),
int(self._camera.get(cv2.CAP_PROP_FRAME_HEIGHT))))
while time() < end_time:
_, frame = self._camera.read()
writer.write(frame)
writer.release()

def take_a_picture(self, save_path: str, to_gray: bool = True):
"""

Args:
save_path:
to_gray:

Returns:

"""

_, frame = self._camera.read()
if to_gray:
frame = cv2.cvtColor(frame, cv2.COLOR_RGB2GRAY)
cv2.imwrite(save_path, frame)
Loading