77 lines
3.1 KiB
Python
77 lines
3.1 KiB
Python
# HY-WorldPlay/hyvideo/utils/data_utils.py
|
|
|
|
# Licensed under the TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# https://github.com/Tencent-Hunyuan/HunyuanVideo-1.5/blob/main/LICENSE
|
|
#
|
|
# Unless and only to the extent required by applicable law, the Tencent Hunyuan works and any
|
|
# output and results therefrom are provided "AS IS" without any express or implied warranties of
|
|
# any kind including any warranties of title, merchantability, noninfringement, course of dealing,
|
|
# usage of trade, or fitness for a particular purpose. You are solely responsible for determining the
|
|
# appropriateness of using, reproducing, modifying, performing, displaying or distributing any of
|
|
# the Tencent Hunyuan works or outputs and assume any and all risks associated with your or a
|
|
# third party's use or distribution of any of the Tencent Hunyuan works or outputs and your exercise
|
|
# of rights and permissions under this agreement.
|
|
# See the License for the specific language governing permissions and limitations under the License.
|
|
|
|
import numpy as np
|
|
from PIL import Image
|
|
|
|
|
|
def resize_and_center_crop(image, target_width, target_height):
|
|
if target_height == image.shape[0] and target_width == image.shape[1]:
|
|
return image
|
|
|
|
pil_image = Image.fromarray(image)
|
|
original_width, original_height = pil_image.size
|
|
scale_factor = max(target_width / original_width, target_height / original_height)
|
|
resized_width = int(round(original_width * scale_factor))
|
|
resized_height = int(round(original_height * scale_factor))
|
|
resized_image = pil_image.resize((resized_width, resized_height), Image.LANCZOS)
|
|
left = (resized_width - target_width) / 2
|
|
top = (resized_height - target_height) / 2
|
|
right = (resized_width + target_width) / 2
|
|
bottom = (resized_height + target_height) / 2
|
|
cropped_image = resized_image.crop((left, top, right, bottom))
|
|
return np.array(cropped_image)
|
|
|
|
|
|
def get_closest_ratio(height: float, width: float, ratios: list, buckets: list):
|
|
"""
|
|
Get the closest ratio in the buckets.
|
|
|
|
Args:
|
|
height (float): video height
|
|
width (float): video width
|
|
ratios (list): video aspect ratio
|
|
buckets (list): buckets generated by `generate_crop_size_list`
|
|
|
|
Returns:
|
|
the closest size in the buckets and the corresponding ratio
|
|
"""
|
|
aspect_ratio = float(height) / float(width)
|
|
|
|
ratios_array = np.array(ratios)
|
|
closest_ratio_id = np.abs(ratios_array - aspect_ratio).argmin()
|
|
closest_size = buckets[closest_ratio_id]
|
|
closest_ratio = ratios_array[closest_ratio_id]
|
|
|
|
return closest_size, closest_ratio
|
|
|
|
|
|
def generate_crop_size_list(base_size=256, patch_size=16, max_ratio=4.0):
|
|
num_patches = round((base_size / patch_size) ** 2)
|
|
assert max_ratio >= 1.0
|
|
crop_size_list = []
|
|
wp, hp = num_patches, 1
|
|
while wp > 0:
|
|
if max(wp, hp) / min(wp, hp) <= max_ratio:
|
|
crop_size_list.append((wp * patch_size, hp * patch_size))
|
|
if (hp + 1) * wp <= num_patches:
|
|
hp += 1
|
|
else:
|
|
wp -= 1
|
|
return crop_size_list
|