Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit acbedc6

Browse files
committed
Support differing subpixel alignment for nonaffine distortion table
1 parent 131648a commit acbedc6

2 files changed

Lines changed: 17 additions & 6 deletions

File tree

lib/matplotlib/tests/test_image.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1668,6 +1668,11 @@ def test__resample_valid_output():
16681668
np.array([[0.1, 0.1, 0.1, 0.1, 0.1, 0.14, 0.22, 0.3, 0.38, 0.46,
16691669
0.54, 0.62, 0.7, 0.78, 0.86, 0.9, 0.9, 0.9, 0.9, 0.9]])),
16701670
(np.array([[0.1, 0.1]]), mimage.BILINEAR, np.full((1, 10), 0.1)),
1671+
# Test at the subpixel level
1672+
(np.array([[0.1, 0.9]]), mimage.BILINEAR,
1673+
np.concatenate([np.full(256, 0.1),
1674+
np.linspace(0.5, 256, 512).astype(int) / 256 * 0.8 + 0.1,
1675+
np.full(256, 0.9)]).reshape(1, -1)),
16711676
]
16721677
)
16731678
def test_resample_nonaffine(data, interpolation, expected):

src/_image_resample.h

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -569,23 +569,28 @@ class lookup_distortion
569569
{
570570
public:
571571
lookup_distortion(const double *mesh, int in_width, int in_height,
572-
int out_width, int out_height) :
572+
int out_width, int out_height, bool edge_aligned_subpixels) :
573573
m_mesh(mesh),
574574
m_in_width(in_width),
575575
m_in_height(in_height),
576576
m_out_width(out_width),
577-
m_out_height(out_height)
577+
m_out_height(out_height),
578+
m_edge_aligned_subpixels(edge_aligned_subpixels)
578579
{}
579580

580581
void calculate(int* x, int* y) {
581582
if (m_mesh) {
583+
// Nearest-neighbor interpolation needs edge-aligned subpixels
584+
// All other interpolation approaches need center-aligned subpixels
585+
double offset = m_edge_aligned_subpixels ? 0 : 0.5;
586+
582587
double dx = double(*x) / agg::image_subpixel_scale;
583588
double dy = double(*y) / agg::image_subpixel_scale;
584589
if (dx >= 0 && dx < m_out_width &&
585590
dy >= 0 && dy < m_out_height) {
586591
const double *coord = m_mesh + (int(dy) * m_out_width + int(dx)) * 2;
587-
*x = int(coord[0] * agg::image_subpixel_scale + 0.5); // round
588-
*y = int(coord[1] * agg::image_subpixel_scale + 0.5); // round
592+
*x = int(coord[0] * agg::image_subpixel_scale + offset);
593+
*y = int(coord[1] * agg::image_subpixel_scale + offset);
589594
}
590595
}
591596
}
@@ -596,6 +601,7 @@ class lookup_distortion
596601
int m_in_height;
597602
int m_out_width;
598603
int m_out_height;
604+
bool m_edge_aligned_subpixels;
599605
};
600606

601607

@@ -781,7 +787,7 @@ void resample(
781787
using span_conv_t = agg::span_converter<span_gen_t, span_conv_alpha_t>;
782788
using nn_renderer_t = agg::renderer_scanline_aa<renderer_t, span_alloc_t, span_conv_t>;
783789
lookup_distortion dist(
784-
params.transform_mesh, in_width, in_height, out_width, out_height);
790+
params.transform_mesh, in_width, in_height, out_width, out_height, true);
785791
arbitrary_interpolator_t interpolator(inverted, dist);
786792
span_gen_t span_gen(input_accessor, interpolator);
787793
span_conv_t span_conv(span_gen, conv_alpha);
@@ -806,7 +812,7 @@ void resample(
806812
using span_conv_t = agg::span_converter<span_gen_t, span_conv_alpha_t>;
807813
using int_renderer_t = agg::renderer_scanline_aa<renderer_t, span_alloc_t, span_conv_t>;
808814
lookup_distortion dist(
809-
params.transform_mesh, in_width, in_height, out_width, out_height);
815+
params.transform_mesh, in_width, in_height, out_width, out_height, false);
810816
arbitrary_interpolator_t interpolator(inverted, dist);
811817
span_gen_t span_gen(input_accessor, interpolator, filter);
812818
span_conv_t span_conv(span_gen, conv_alpha);

0 commit comments

Comments
 (0)