gpt4 book ai didi

c++ - 双线性图像采样不可重现的访问冲突

转载 作者:行者123 更新时间:2023-11-30 05:27:22 26 4
gpt4 key购买 nike

我有一个模板 2D 图像缓冲区类,可以与许多值类型一起使用。这些值存储为 T 的一维动态数组,通过 Row 方法访问以获得指向正确行的指针。

该类的一个方法用于对图像中的值进行双线性采样。

该代码通常可以正常工作,但在生产中我很少会在该方法中遇到访问冲突异常,我似乎无法重新创建该异常,因为故障转储不包含传递给该方法的坐标。

这些是代码的相关部分:

T* data;
int width, height;

T* Row(int y) const { return data + width * y; }

T GetValueBilinear(float x, float y) const
{
const float PIXEL_CENTER_OFFSET = 0.5F;

const float cx = clamp(0.0F, width - 1.0F, x - PIXEL_CENTER_OFFSET);
const float cy = clamp(0.0F, height - 1.0F, y - PIXEL_CENTER_OFFSET);

const float tx = fmod(cx, 1.0F);
const float ty = fmod(cy, 1.0F);

const int xInt = (int)cx;
const int yInt = (int)cy;

const T* r0 = Row(yInt);
const T* r1 = ty && yInt < (height - 1) ? Row(yInt + 1) : r0;

//interpolate on Y
const T& c00 = r0[xInt];
const T& c01 = r1[xInt];
T c0 = lerp(c00, c01, ty);

if (tx && xInt < (width - 1))
{
//interpolate on X
const T& c10 = r0[xInt + 1];
const T& c11 = r1[xInt + 1];
T c1 = lerp(c10, c11, ty);
return lerp(c0, c1, tx);
}
else
{
return c0;
}
}

clamplerp 的定义是:

template <typename T>
inline T clamp(T min, T max, T value) { return value < min ? min : value > max ? max : value; }

template <typename T>
inline T lerp(T a, T b, float t) { return a + (b - a) * t; } //i.e. a(1-t)+bt

您是否看到任何明显的错误,这些错误会导致 xy 的任何非 NaN 值的访问冲突?

您可以假设 widthheightdata 是有效和正确的(即正尺寸 - 在这种特殊情况下为 1280x720,data 不是悬挂指针)。

如果它很重要,那么 T 在这种情况下是一个 float

事实上,这是不可重现的,而且通常在 99.9% 的时间里都有效,这让我觉得这可能是一个准确性问题,尽管我看不出它会从哪里来。

或者,我可以使用哪些调试技术来更有效地分析故障转储?

最佳答案

我用 1073741824 个随机值对 (x,y) 在 1280x720 data 上测试了你的 GetValueBilinear > 没有访问冲突.. 所以我会说它在 99.999999%1 的时间里工作正常 :-) 我怀疑问题不在 GetValueBilinear 中,而是在其他地方.. .

#include <cmath>
#include <algorithm>

template <typename T>
inline T clamp(T min, T max, T value) { return value < min ? min : value > max ? max : value; }

template <typename T>
inline T lerp(T a, T b, float t) { return a + (b - a) * t; } //i.e. a(1-t)+bt

template < typename T >
class C
{
public:
C(int w, int h) : height(h), width(w) {
float lower_bound = T(0);
float upper_bound = std::nextafter(T(255), std::numeric_limits<T>::max());
std::uniform_real_distribution<float> unif(lower_bound, upper_bound);
std::default_random_engine re;
data = new T[width*height];// I know... a leak! But... who cares?!
std::generate(data, data + (width*height), [&]() {return unif(re); });
}
T GetValueBilinear(float x, float y) const
{
const float PIXEL_CENTER_OFFSET = 0.5F;

const float cx = clamp(0.0F, width - 1.0F, x - PIXEL_CENTER_OFFSET);
const float cy = clamp(0.0F, height - 1.0F, y - PIXEL_CENTER_OFFSET);

const float tx = fmod(cx, 1.0F);
const float ty = fmod(cy, 1.0F);

const int xInt = (int)cx;
const int yInt = (int)cy;

const T* r0 = Row(yInt);
const T* r1 = ty && yInt < (height - 1) ? Row(yInt + 1) : r0;

//interpolate on Y
const T& c00 = r0[xInt];
const T& c01 = r1[xInt];
T c0 = lerp(c00, c01, ty);

if (tx && xInt < (width - 1))
{
//interpolate on X
const T& c10 = r0[xInt + 1];
const T& c11 = r1[xInt + 1];
T c1 = lerp(c10, c11, ty);
return lerp(c0, c1, tx);
}
else
{
return c0;
}
}




T* data;
int width, height;

T* Row(int y) const { return data + width * y; }


};

#include <random>
#include <iostream>

#include <Windows.h>


float x;
float y;

LONG WINAPI my_filter(_In_ struct _EXCEPTION_POINTERS *ExceptionInfo)
{
std::cout << x << " " << y << "\n";
return EXCEPTION_EXECUTE_HANDLER;
}

int main()
{
auto a = ::SetUnhandledExceptionFilter(my_filter);

float lower_bound = -(1 << 20);
float upper_bound = -lower_bound;
std::uniform_real_distribution<float> unif(lower_bound, upper_bound);
std::default_random_engine re;

float acc = 0;
C<float> img(1280, 720);

img.GetValueBilinear(1.863726958e-043, 1.5612089e-038);

for (size_t i = 0; i < (1 << 30); i++) {
x = unif(re);
y = unif(re);

acc += img.GetValueBilinear(x, y);
}

return static_cast<int>(acc);
}


1 即使没有发现访问冲突,我也不能说该算法 100% 运行良好,使用的是朴素模型和此 R 代码:

prop.test(0,1073741824)

我得到了比例的 true 值的置信区间,区间是 (0.000000e+00, 4.460345e-09) 所以成功百分比是(1-4.460345e-09)*100,但是...不要相信我,我不是统计学家!

关于c++ - 双线性图像采样不可重现的访问冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37432246/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com