Skip to content

Commit

Permalink
video tools
Browse files Browse the repository at this point in the history
  • Loading branch information
sronilsson committed May 6, 2024
1 parent 22e2e84 commit cf67973
Show file tree
Hide file tree
Showing 13 changed files with 72 additions and 53 deletions.
Binary file added docs/_static/img/VideoRotator.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/_static/img/clahe_enhance_video.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/_static/img/crop_single_video.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/_static/img/crop_single_video_circle.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/_static/img/superimpose_frame_count.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/_static/img/superimpose_frame_count.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/_static/img/to_greyscale.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

setuptools.setup(
name="Simba-UW-tf-dev",
version="1.91.5",
version="1.91.6",
author="Simon Nilsson, Jia Jie Choong, Sophia Hwang",
author_email="[email protected]",
description="Toolkit for computer classification of behaviors in experimental animals",
Expand Down
23 changes: 3 additions & 20 deletions simba/mixins/plotting_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -1598,26 +1598,9 @@ def polygons_onto_image(
:return:
"""

check_valid_array(
data=img, source=f"{PlottingMixin.polygons_onto_image.__name__} img"
)
check_valid_dataframe(
df=polygons,
source=f"{PlottingMixin.polygons_onto_image.__name__} polygons",
required_fields=[
"vertices",
"Center_X",
"Center_Y",
"Color BGR",
"Thickness",
"Tags",
],
)
check_int(
name=PlottingMixin.polygons_onto_image.__name__,
value=circle_size,
min_value=1,
)
check_valid_array(data=img, source=f"{PlottingMixin.polygons_onto_image.__name__} img")
check_valid_dataframe(df=polygons, source=f"{PlottingMixin.polygons_onto_image.__name__} polygons", required_fields=["vertices", "Color BGR", "Thickness", "Tags"])
check_int(name=PlottingMixin.polygons_onto_image.__name__, value=circle_size, min_value=1)
for _, row in polygons.iterrows():
img = cv2.polylines(
img,
Expand Down
19 changes: 10 additions & 9 deletions simba/plotting/ROI_feature_visualizer_mp.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,7 @@
BORDER_COLOR = "border_color"
POSE = "pose_estimation"
ANIMAL_NAMES = "animal_names"
STYLE_KEYS = [
ROI_CENTERS,
ROI_EAR_TAGS,
DIRECTIONALITY,
BORDER_COLOR,
POSE,
DIRECTIONALITY_STYLE,
ANIMAL_NAMES,
]
STYLE_KEYS = [ROI_CENTERS,ROI_EAR_TAGS,DIRECTIONALITY,BORDER_COLOR,POSE,DIRECTIONALITY_STYLE,ANIMAL_NAMES,]


def _roi_feature_visualizer_mp(frm_range: Tuple[int, np.ndarray],
Expand Down Expand Up @@ -422,6 +414,15 @@ def run(self):
stdout_success(msg=f"Video {self.video_name} complete. Video saved in project_folder/frames/output/ROI_features.", elapsed_time=self.timer.elapsed_time_str)



# style_attr = {'roi_centers': True, 'roi_ear_tags': True, 'directionality': True, 'directionality_style': 'funnel', 'border_color': (0, 0, 0), 'pose_estimation': True, 'animal_names': True}
# test = ROIfeatureVisualizerMultiprocess(config_path='/Users/simon/Desktop/envs/simba/troubleshooting/spontenous_alternation/project_folder/project_config.ini',
# video_path='/Users/simon/Desktop/envs/simba/troubleshooting/spontenous_alternation/project_folder/videos/NOR ENCODING FExMP8.mp4',
# style_attr=style_attr,
# body_parts=['Center'], core_cnt=-1)
# test.run()


# style_attr = {'roi_centers': True, 'roi_ear_tags': True, 'directionality': True, 'directionality_style': 'funnel', 'border_color': (0, 0, 0), 'pose_estimation': True, 'animal_names': True}
# test = ROIfeatureVisualizerMultiprocess(config_path='/Users/simon/Desktop/envs/simba/troubleshooting/RAT_NOR/project_folder/project_config.ini',
# video_path='/Users/simon/Desktop/envs/simba/troubleshooting/RAT_NOR/project_folder/videos/2022-06-20_NOB_DOT_4.mp4',
Expand Down
2 changes: 0 additions & 2 deletions simba/ui/pop_ups/video_processing_pop_up.py
Original file line number Diff line number Diff line change
Expand Up @@ -2069,11 +2069,9 @@ def run(self):

class BrightnessContrastPopUp(PopUpMixin):
"""
.. image:: _static/img/brightness_contrast_ui.gif
:width: 700
:align: center
"""
def __init__(self):
super().__init__(title="CHANGE BRIGHTNESS / CONTRAST")
Expand Down
2 changes: 1 addition & 1 deletion simba/utils/checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -1335,7 +1335,7 @@ def _count_generator(reader):
check_file_exist_and_readable(file_path=data)
with open(data, "rb") as fp:
c_generator = _count_generator(fp.raw.read)
data_count = (sum(buffer.count(b"\n") for buffer in c_generator))
data_count = (sum(buffer.count(b"\n") for buffer in c_generator)) - 1
else:
data_count = len(data)
if data_count != video_count:
Expand Down
77 changes: 57 additions & 20 deletions simba/video_processors/video_processing.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ def clahe_enhance_video(
Convert a single video file to clahe-enhanced greyscale .avi file. The result is saved with prefix
``CLAHE_`` in the same directory as in the input file if out_path is not passed. Else saved at the out_path.
.. image:: _static/img/clahe_enhance_video.gif
:width: 800
:align: center
:parameter Union[str, os.PathLike] file_path: Path to video file.
:parameter Optional[int] clip_limit: CLAHE amplification limit. Inccreased clip limit reduce noise in output. Default: 2.
:parameter Optional[Tuple[int]] tile_grid_size: The histogram kernel size.
Expand Down Expand Up @@ -432,13 +436,15 @@ def convert_to_mp4(
)


def video_to_greyscale(
file_path: Union[str, os.PathLike], gpu: Optional[bool] = False
) -> None:
def video_to_greyscale(file_path: Union[str, os.PathLike], gpu: Optional[bool] = False) -> None:
"""
Convert a video file to greyscale mp4 format. The result is stored in the same directory as the
input file with the ``_grayscale.mp4`` suffix.
.. image:: _static/img/to_greyscale.gif
:width: 700
:align: center
:parameter Union[str, os.PathLike] file_path: Path to video file.
:parameter Optional[bool] gpu: If True, use NVIDEA GPU codecs. Default False.
:raise FFMPEGCodecGPUError: If no GPU is found and ``gpu == True``.
Expand Down Expand Up @@ -476,13 +482,15 @@ def video_to_greyscale(
)


def batch_video_to_greyscale(
directory: Union[str, os.PathLike], gpu: Optional[bool] = False
) -> None:
def batch_video_to_greyscale(directory: Union[str, os.PathLike], gpu: Optional[bool] = False) -> None:
"""
Convert a directory of video file to greyscale mp4 format. The results are stored in the same directory as the
input files with the ``_grayscale.mp4`` suffix.
.. image:: _static/img/to_greyscale.gif
:width: 700
:align: center
:parameter Union[str, os.PathLike] directory: Path to directory holding video files in color.
:parameter Optional[bool] gpu: If True, use NVIDEA GPU codecs. Default False.
:raise FFMPEGCodecGPUError: If no GPU is found and ``gpu == True``.
Expand Down Expand Up @@ -525,13 +533,19 @@ def batch_video_to_greyscale(
)


def superimpose_frame_count(
file_path: Union[str, os.PathLike], gpu: Optional[bool] = False
) -> None:
def superimpose_frame_count(file_path: Union[str, os.PathLike], gpu: Optional[bool] = False) -> None:
"""
Superimpose frame count on a video file. The result is stored in the same directory as the
input file with the ``_frame_no.mp4`` suffix.
.. image:: _static/img/superimpose_frame_count.png
:width: 700
:align: center
.. image:: _static/img/superimpose_frame_count.gif
:width: 500
:align: center
:parameter Union[str, os.PathLike] file_path: Path to video file.
:parameter Optional[bool] gpu: If True, use NVIDEA GPU codecs. Default False.
Expand Down Expand Up @@ -1065,13 +1079,15 @@ def multi_split_video(
# multi_split_video(file_path=r'/Users/simon/Desktop/time_s_converted.mp4', start_times=['00:00:01', '00:00:02'], end_times=['00:00:04', '00:00:05'], gpu=False)


def crop_single_video(
file_path: Union[str, os.PathLike], gpu: Optional[bool] = False
) -> None:
def crop_single_video(file_path: Union[str, os.PathLike], gpu: Optional[bool] = False) -> None:
"""
Crop a single video using ``simba.video_processors.roi_selector.ROISelector`` interface. Results is saved in the same directory as input video with the
``_cropped.mp4`` suffix`.
.. image:: _static/img/crop_single_video.gif
:width: 700
:align: center
:parameter str file_path: Path to video file.
:parameter Optional[bool] gpu: If True, use NVIDEA GPU codecs. Default False.
Expand Down Expand Up @@ -1387,11 +1403,19 @@ class VideoRotator(ConfigReader):
"""
GUI Tool for rotating video. Rotated video is saved with the ``_rotated_DATETIME.mp4`` suffix.
.. image:: _static/img/VideoRotator.gif
:width: 700
:align: center
:parameter str input_path: Path to video to rotate.
:parameter str output_dir: Directory where to save the rotated video.
:parameter Optional[bool] gpu: If True, use FFMPEG NVIDEA GPU codecs. Else CPU codecs.
:parameter Optional[bool] gpu: If True, use FFPMPEG. Else, OpenCV.
:example:
>>> VideoRotator(input_path='project_folder/videos/Video_1.mp4', output_dir='project_folder/videos')
"""
Expand Down Expand Up @@ -1747,14 +1771,17 @@ def crop_single_video_circle(file_path: Union[str, os.PathLike]) -> None:
"""
Crop a video based on circular regions of interest (ROIs) selected by the user.
:param Union[str, os.PathLike] file_path: The path to the input video file.
.. image:: _static/img/crop_single_video_circle.gif
:width: 600
:align: center
.. note::
This function crops the input video based on circular regions of interest (ROIs) selected by the user.
The user is prompted to select a circular ROI on the video frame, and the function then crops the video
based on the selected ROI. The cropped video is saved with "_circle_cropped" suffix in the same directory
as the input video file.
:param Union[str, os.PathLike] file_path: The path to the input video file.
:example:
>>> crop_single_video_circle(file_path='/Users/simon/Desktop/AGGRESSIVITY_4_11_21_Trial_2_camera1_rotated_20240211143355.mp4')
"""
Expand Down Expand Up @@ -1791,21 +1818,27 @@ def crop_single_video_circle(file_path: Union[str, os.PathLike]) -> None:
)


def crop_multiple_videos_circles(
in_dir: Union[str, os.PathLike], out_dir: Union[str, os.PathLike]
) -> None:
def crop_multiple_videos_circles(in_dir: Union[str, os.PathLike], out_dir: Union[str, os.PathLike]) -> None:
"""
Crop multiple videos based on circular regions of interest (ROIs) selected by the user.
:param Union[str, os.PathLike] in_dir: The directory containing input video files.
:param Union[str, os.PathLike] out_dir: The directory to save the cropped video files.
.. image:: _static/img/crop_single_video_circle.gif
:width: 600
:align: center
.. note::
This function crops multiple videos based on circular ROIs selected by the user.
The user is asked to define a circle manually in one video within the input directory.
The function then crops all the video in the input directory according to the shape defined
using the first video and saves the videos in the ``out_dir`` with the same filenames as the original videos..
:param Union[str, os.PathLike] in_dir: The directory containing input video files.
:param Union[str, os.PathLike] out_dir: The directory to save the cropped video files.
:example:
>>> crop_multiple_videos_circles(in_dir='/Users/simon/Desktop/edited/tests', out_dir='/Users/simon/Desktop')
"""
Expand Down Expand Up @@ -1853,6 +1886,10 @@ def crop_single_video_polygon(file_path: Union[str, os.PathLike]) -> None:
"""
Crop a video based on polygonal regions of interest (ROIs) selected by the user.
.. image:: _static/img/roi_selector_polygon.gif
:width: 400
:align: center
:param Union[str, os.PathLike] file_path: The path to the input video file.
.. note::
Expand Down Expand Up @@ -2160,7 +2197,7 @@ def horizontal_video_concatenator(
Concatenates multiple videos horizontally.
.. image:: _static/img/horizontal_video_concatenator.gif
:width: 600
:width: 1000
:align: center
:param List[Union[str, os.PathLike]] video_paths: List of input video file paths.
Expand Down

0 comments on commit cf67973

Please sign in to comment.