-
Notifications
You must be signed in to change notification settings - Fork 12
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
get_match_centers_scaling: New function #165
Conversation
Warning Rate Limit Exceeded@LightArrowsEXE has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 6 minutes and 4 seconds before requesting another review. How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. WalkthroughThis update introduces a significant enhancement to the Changes
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (invoked as PR comments)
Additionally, you can add CodeRabbit Configration File (
|
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.
Review Status
Actionable comments generated: 1
Configuration used: CodeRabbit UI
Files selected for processing (1)
- lvsfunc/util.py (2 hunks)
Additional comments: 1
lvsfunc/util.py (1)
- 8-10: Consider grouping imports from
vstools
into a single line for consistency and readability.
lvsfunc/util.py
Outdated
def get_match_centers_scaling( | ||
clip: vs.VideoNode, target_width: int | None = None, target_height: int | None = 720 | ||
) -> KwargsT: | ||
""" | ||
Convenience function to calculate the native resolution for sources that were upsampled | ||
using the "match centers" model as opposed to the more common "match edges" models. | ||
|
||
While match edges will align the edges of the outermost pixels in the target image, | ||
match centers will instead align the *centers* of the outermost pixels. | ||
|
||
Here's a visual example for a 3x1 image upsampled to 9x1: | ||
|
||
* Match edges: | ||
|
||
+-----------+-----------+-----------+ | ||
| . | . | . | | ||
+-----------+-----------+-----------+ | ||
↓ ↓ | ||
+---+---+---+---+---+---+---+---+---+ | ||
| . | . | . | . | . | . | . | . | . | | ||
+---+---+---+---+---+---+---+---+---+ | ||
|
||
* Match centers: | ||
|
||
+-----------+-----------+-----------+ | ||
| . | . | . | | ||
+-----------+-----------+-----------+ | ||
↓ ↓ | ||
+---+---+---+---+---+---+---+---+---+ | ||
| . | . | . | . | . | . | . | . | . | | ||
+---+---+---+---+---+---+---+---+---+ | ||
|
||
For a more detailed explanation, refer to this page: `<https://entropymine.com/imageworsener/matching/>`. | ||
|
||
The formula for calculating values we can use during desampling is simple: | ||
|
||
* width: clip.width * (target_width - 1) / (clip.width - 1) | ||
* height: clip.height * (target_height - 1) / (clip.height - 1) | ||
|
||
Example usage: | ||
|
||
.. code-block:: python | ||
|
||
>>> from vodesfunc import DescaleTarget | ||
>>> ... | ||
>>> native_res = get_match_centers_scaling(src, 1280, 720) | ||
>>> rescaled = DescaleTarget(kernel=Catrom, upscaler=Waifu2x, downscaler=Hermite(linear=True), **native_res) | ||
|
||
The output is meant to be passed to `vodesfunc.DescaleTarget` as keyword arguments, | ||
but it may also apply to other functions that require similar parameters. | ||
|
||
:param clip: The clip to base the calculations on. | ||
:param target_width: Target width for the descale. This should probably be equal to the base width. | ||
If not provided, this value is calculated using the `target_height`. | ||
Default: None. | ||
:param target_height: Target height for the descale. This should probably be equal to the base height. | ||
If not provided, this value is calculated using the `target_width`. | ||
Default: 720. | ||
|
||
:return: A dictionary with the keys, {width, height, base_width, base_height}, | ||
which can be passed directly to `vodesfunc.DescaleTarget` or similar functions. | ||
""" | ||
|
||
if target_width is None and target_height is None: | ||
raise CustomValueError("Either `target_width` or `target_height` must be provided.", get_match_centers_scaling) | ||
|
||
check_variable_resolution(clip, get_match_centers_scaling) | ||
|
||
if target_height is None: | ||
target_height = get_h(target_width, clip, 1) | ||
|
||
if not float(target_height).is_integer(): | ||
raise CustomValueError("`target_height` must be an integer.", get_match_centers_scaling) | ||
|
||
elif target_width is None: | ||
target_width = get_w(target_height, clip, 1) | ||
|
||
if not float(target_width).is_integer(): | ||
raise CustomValueError("`target_width` must be an integer.", get_match_centers_scaling) | ||
|
||
width = clip.width * (target_width - 1) / (clip.width - 1) | ||
height = clip.height * (target_height - 1) / (clip.height - 1) | ||
|
||
return KwargsT(width=width, height=height, base_width=target_width, base_height=target_height) |
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.
- The function
get_match_centers_scaling
lacks validation fortarget_width
andtarget_height
being positive integers. This is crucial to prevent unexpected behavior or division by zero errors. - The calculation of
target_height
fromtarget_width
(lines 174-178) and vice versa (lines 180-184) does not account for the case where both are provided but one does not match the expected calculation based on the clip's aspect ratio. This could lead to incorrect scaling. - The use of
float(target_height).is_integer()
(line 177) andfloat(target_width).is_integer()
(line 183) is unnecessary sincetarget_height
andtarget_width
should already be integers if provided or calculated. A direct integer check would be more appropriate. - The formula used for calculating
width
andheight
(lines 186-187) does not handle the case whereclip.width
orclip.height
is 1, leading to a division by zero error. - The function documentation (lines 157-166) promises to return a dictionary but actually returns a
KwargsT
object. Ensure the documentation accurately reflects the return type. - The example usage (lines 145-155) references
vodesfunc
instead ofvstools
orlvsfunc
, which might be a typo or incorrect reference. - The function does not handle non-integer results for
width
andheight
calculations (lines 186-187), which could be problematic for functions expecting integer dimensions.
- return KwargsT(width=width, height=height, base_width=target_width, base_height=target_height)
+ return KwargsT(width=int(round(width)), height=int(round(height)), base_width=int(target_width), base_height=int(target_height))
- Add validation for positive
target_width
andtarget_height
. - Clarify behavior and validation when both
target_width
andtarget_height
are provided. - Correct the documentation and example usage to accurately reflect the function's behavior and return type.
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.
def get_match_centers_scaling( | |
clip: vs.VideoNode, target_width: int | None = None, target_height: int | None = 720 | |
) -> KwargsT: | |
""" | |
Convenience function to calculate the native resolution for sources that were upsampled | |
using the "match centers" model as opposed to the more common "match edges" models. | |
While match edges will align the edges of the outermost pixels in the target image, | |
match centers will instead align the *centers* of the outermost pixels. | |
Here's a visual example for a 3x1 image upsampled to 9x1: | |
* Match edges: | |
+-----------+-----------+-----------+ | |
| . | . | . | | |
+-----------+-----------+-----------+ | |
↓ ↓ | |
+---+---+---+---+---+---+---+---+---+ | |
| . | . | . | . | . | . | . | . | . | | |
+---+---+---+---+---+---+---+---+---+ | |
* Match centers: | |
+-----------+-----------+-----------+ | |
| . | . | . | | |
+-----------+-----------+-----------+ | |
↓ ↓ | |
+---+---+---+---+---+---+---+---+---+ | |
| . | . | . | . | . | . | . | . | . | | |
+---+---+---+---+---+---+---+---+---+ | |
For a more detailed explanation, refer to this page: `<https://entropymine.com/imageworsener/matching/>`. | |
The formula for calculating values we can use during desampling is simple: | |
* width: clip.width * (target_width - 1) / (clip.width - 1) | |
* height: clip.height * (target_height - 1) / (clip.height - 1) | |
Example usage: | |
.. code-block:: python | |
>>> from vodesfunc import DescaleTarget | |
>>> ... | |
>>> native_res = get_match_centers_scaling(src, 1280, 720) | |
>>> rescaled = DescaleTarget(kernel=Catrom, upscaler=Waifu2x, downscaler=Hermite(linear=True), **native_res) | |
The output is meant to be passed to `vodesfunc.DescaleTarget` as keyword arguments, | |
but it may also apply to other functions that require similar parameters. | |
:param clip: The clip to base the calculations on. | |
:param target_width: Target width for the descale. This should probably be equal to the base width. | |
If not provided, this value is calculated using the `target_height`. | |
Default: None. | |
:param target_height: Target height for the descale. This should probably be equal to the base height. | |
If not provided, this value is calculated using the `target_width`. | |
Default: 720. | |
:return: A dictionary with the keys, {width, height, base_width, base_height}, | |
which can be passed directly to `vodesfunc.DescaleTarget` or similar functions. | |
""" | |
if target_width is None and target_height is None: | |
raise CustomValueError("Either `target_width` or `target_height` must be provided.", get_match_centers_scaling) | |
check_variable_resolution(clip, get_match_centers_scaling) | |
if target_height is None: | |
target_height = get_h(target_width, clip, 1) | |
if not float(target_height).is_integer(): | |
raise CustomValueError("`target_height` must be an integer.", get_match_centers_scaling) | |
elif target_width is None: | |
target_width = get_w(target_height, clip, 1) | |
if not float(target_width).is_integer(): | |
raise CustomValueError("`target_width` must be an integer.", get_match_centers_scaling) | |
width = clip.width * (target_width - 1) / (clip.width - 1) | |
height = clip.height * (target_height - 1) / (clip.height - 1) | |
return KwargsT(width=width, height=height, base_width=target_width, base_height=target_height) | |
def get_match_centers_scaling( | |
clip: vs.VideoNode, target_width: int | None = None, target_height: int | None = 720 | |
) -> KwargsT: | |
""" | |
Convenience function to calculate the native resolution for sources that were upsampled | |
using the "match centers" model as opposed to the more common "match edges" models. | |
While match edges will align the edges of the outermost pixels in the target image, | |
match centers will instead align the *centers* of the outermost pixels. | |
Here's a visual example for a 3x1 image upsampled to 9x1: | |
* Match edges: | |
+-----------+-----------+-----------+ | |
| . | . | . | | |
+-----------+-----------+-----------+ | |
↓ ↓ | |
+---+---+---+---+---+---+---+---+---+ | |
| . | . | . | . | . | . | . | . | . | | |
+---+---+---+---+---+---+---+---+---+ | |
* Match centers: | |
+-----------+-----------+-----------+ | |
| . | . | . | | |
+-----------+-----------+-----------+ | |
↓ ↓ | |
+---+---+---+---+---+---+---+---+---+ | |
| . | . | . | . | . | . | . | . | . | | |
+---+---+---+---+---+---+---+---+---+ | |
For a more detailed explanation, refer to this page: `<https://entropymine.com/imageworsener/matching/>`. | |
The formula for calculating values we can use during desampling is simple: | |
* width: clip.width * (target_width - 1) / (clip.width - 1) | |
* height: clip.height * (target_height - 1) / (clip.height - 1) | |
Example usage: | |
.. code-block:: python | |
>>> from vodesfunc import DescaleTarget | |
>>> ... | |
>>> native_res = get_match_centers_scaling(src, 1280, 720) | |
>>> rescaled = DescaleTarget(kernel=Catrom, upscaler=Waifu2x, downscaler=Hermite(linear=True), **native_res) | |
The output is meant to be passed to `vodesfunc.DescaleTarget` as keyword arguments, | |
but it may also apply to other functions that require similar parameters. | |
:param clip: The clip to base the calculations on. | |
:param target_width: Target width for the descale. This should probably be equal to the base width. | |
If not provided, this value is calculated using the `target_height`. | |
Default: None. | |
:param target_height: Target height for the descale. This should probably be equal to the base height. | |
If not provided, this value is calculated using the `target_width`. | |
Default: 720. | |
:return: A dictionary with the keys, {width, height, base_width, base_height}, | |
which can be passed directly to `vodesfunc.DescaleTarget` or similar functions. | |
""" | |
if target_width is None and target_height is None: | |
raise CustomValueError("Either `target_width` or `target_height` must be provided.", get_match_centers_scaling) | |
check_variable_resolution(clip, get_match_centers_scaling) | |
if target_height is None: | |
target_height = get_h(target_width, clip, 1) | |
if not float(target_height).is_integer(): | |
raise CustomValueError("`target_height` must be an integer.", get_match_centers_scaling) | |
elif target_width is None: | |
target_width = get_w(target_height, clip, 1) | |
if not float(target_width).is_integer(): | |
raise CustomValueError("`target_width` must be an integer.", get_match_centers_scaling) | |
width = clip.width * (target_width - 1) / (clip.width - 1) | |
height = clip.height * (target_height - 1) / (clip.height - 1) | |
return KwargsT(width=int(round(width)), height=int(round(height)), base_width=int(target_width), base_height=int(target_height)) |
* match_centers_formula: new util function * match_centers_formula: Expand docstring * get_match_centers_scaling: rename function, expand docs, minor optimisations * get_match_centers_scaling: Updates based on review
* match_centers_formula: new util function * match_centers_formula: Expand docstring * get_match_centers_scaling: rename function, expand docs, minor optimisations * get_match_centers_scaling: Updates based on review
Summary by CodeRabbit