Files
wehub-resource-sync 3a2c66702c
Tests on CPU (scheduled) / check-skip (push) Has been cancelled
Tests on CPU (scheduled) / pre-tests (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-ubuntu (float32) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-ubuntu (float64) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-windows (3.11, float32, 2.5.1) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-windows (3.11, float32, 2.9.1) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-windows (3.11, float64, 2.5.1) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-windows (3.11, float64, 2.9.1) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-windows (3.12, float32, 2.5.1) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-windows (3.12, float32, 2.9.1) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-windows (3.12, float64, 2.5.1) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-windows (3.12, float64, 2.9.1) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-windows (3.13, float32, 2.9.1) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-windows (3.13, float64, 2.9.1) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-mac (3.11, float32, 2.5.1) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-mac (3.11, float32, 2.9.1) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-mac (3.12, float32, 2.5.1) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-mac (3.12, float32, 2.9.1) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-mac (3.13, float32, 2.9.1) (push) Has been cancelled
Tests on CPU (scheduled) / coverage (push) Has been cancelled
Tests on CPU (scheduled) / typing (push) Has been cancelled
Tests on CPU (scheduled) / tutorials (push) Has been cancelled
Tests on CPU (scheduled) / docs (push) Has been cancelled
Lint / TOML Format (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:49:27 +08:00

140 lines
5.5 KiB
Python

# LICENSE HEADER MANAGED BY add-license-header
#
# Copyright 2018 Kornia Team
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
from __future__ import annotations
import pytest
import torch
from kornia.core.exceptions import BaseError
from kornia.models.structures import Prompts, SegmentationResults
class TestSegmentationResults:
def _make_results(self, B=2, C=3, H=16, W=16, threshold=0.0):
logits = torch.randn(B, C, H, W)
scores = torch.rand(B, C)
return SegmentationResults(logits=logits, scores=scores, mask_threshold=threshold)
def test_binary_masks_uses_logits_when_no_original(self):
r = self._make_results()
masks = r.binary_masks
assert masks.shape == r.logits.shape
assert masks.dtype == torch.bool
assert torch.equal(masks, r.logits > r.mask_threshold)
def test_binary_masks_uses_original_res_logits_when_set(self):
r = self._make_results()
# Simulate having called original_res_logits()
fake_hires = torch.randn(2, 3, 32, 32) + 10.0 # all positive -> all True
r._original_res_logits = fake_hires
masks = r.binary_masks
assert masks.shape == (2, 3, 32, 32)
assert masks.all()
def test_original_res_logits_without_encoder_resize(self):
r = self._make_results(B=1, C=1, H=8, W=8)
# No encoder resize (image_size_encoder=None), just crop and resize
result = r.original_res_logits(input_size=(8, 8), original_size=(32, 32), image_size_encoder=None)
assert result.shape == (1, 1, 32, 32)
assert r._original_res_logits is not None
def test_original_res_logits_with_encoder_resize(self):
r = self._make_results(B=1, C=1, H=8, W=8)
# With encoder resize: first resize to (16, 16), then crop, then resize to (32, 32)
result = r.original_res_logits(input_size=(16, 16), original_size=(32, 32), image_size_encoder=(16, 16))
assert result.shape == (1, 1, 32, 32)
def test_original_res_logits_crops_padding(self):
# Logits have extra spatial dimension due to padding
r = self._make_results(B=1, C=1, H=10, W=10)
# Crop to 8x8, then resize to 4x4
result = r.original_res_logits(input_size=(8, 8), original_size=(4, 4), image_size_encoder=None)
assert result.shape == (1, 1, 4, 4)
def test_squeeze_without_original_res_logits(self):
r = self._make_results(B=1, C=3, H=8, W=8)
squeezed = r.squeeze(dim=0)
assert squeezed.logits.shape == (3, 8, 8)
assert squeezed.scores.shape == (3,)
def test_squeeze_with_original_res_logits(self):
r = self._make_results(B=1, C=3, H=8, W=8)
r._original_res_logits = torch.randn(1, 3, 32, 32)
squeezed = r.squeeze(dim=0)
assert squeezed.logits.shape == (3, 8, 8)
assert isinstance(squeezed._original_res_logits, torch.Tensor)
assert squeezed._original_res_logits.shape == (3, 32, 32)
def test_binary_masks_threshold(self):
logits = torch.tensor([[[[0.5, -0.5], [0.3, 0.1]]]])
scores = torch.ones(1, 1)
r = SegmentationResults(logits=logits, scores=scores, mask_threshold=0.2)
masks = r.binary_masks
# 0.5 > 0.2 -> True, -0.5 > 0.2 -> False, 0.3 > 0.2 -> True, 0.1 > 0.2 -> False
expected = torch.tensor([[[[True, False], [True, False]]]])
assert torch.equal(masks, expected)
class TestPrompts:
def test_no_prompts(self):
p = Prompts()
assert p.points is None
assert p.boxes is None
assert p.masks is None
assert p.keypoints is None
assert p.keypoints_labels is None
def test_keypoints_from_tuple(self):
coords = torch.rand(2, 5, 2)
labels = torch.randint(0, 2, (2, 5)).float()
p = Prompts(points=(coords, labels))
assert torch.equal(p.keypoints, coords)
assert torch.equal(p.keypoints_labels, labels)
def test_keypoints_none_when_points_none(self):
p = Prompts(points=None)
assert p.keypoints is None
assert p.keypoints_labels is None
def test_boxes_only(self):
boxes = torch.rand(2, 4)
p = Prompts(boxes=boxes)
assert torch.equal(p.boxes, boxes)
assert p.keypoints is None
def test_keypoints_and_boxes_matching_batch(self):
coords = torch.rand(3, 5, 2)
labels = torch.rand(3, 5)
boxes = torch.rand(3, 4)
# Should not raise: batch sizes match
p = Prompts(points=(coords, labels), boxes=boxes)
assert p.keypoints.shape[0] == 3
assert p.boxes.shape[0] == 3
def test_keypoints_and_boxes_mismatched_batch_raises(self):
coords = torch.rand(2, 5, 2)
labels = torch.rand(2, 5)
boxes = torch.rand(3, 4) # different batch size
with pytest.raises(BaseError, match="same batch size"):
Prompts(points=(coords, labels), boxes=boxes)
def test_masks_only(self):
masks = torch.rand(2, 1, 32, 32)
p = Prompts(masks=masks)
assert torch.equal(p.masks, masks)