我有-1.396655
到1.74707
之间任意位置范围内的双打列表甚至可能更高或更低,无论哪种方式我都知道Min
和{{1} } value在规范化之前。我的问题是如何在Max
到-1
之间规范化这些值,或者更好地将它们从double值转换为char值1
到0
任何帮助都将不胜感激。
255
答案 0 :(得分:4)
您需要y = mx + c
表单的mapping,并且需要找到m
和c
。你有两个固定的数据点,即:
1 = m * max + c
-1 = m * min + c
从那里开始,simple algebra。
答案 1 :(得分:2)
最简单的方法是首先通过从每个数字中减去Min来移动所有值,使min为0。然后乘以255 /(Max-Min),以便移位的Max将映射到255,其他所有内容将线性缩放。所以我相信你的等式看起来像这样:
newval = (unsigned char) ((oldval - Min)*(255/(Max-Min)))
在转换为char之前,您可能需要更仔细地进行舍入。
答案 2 :(得分:0)
有两项更改。
首先,使用256作为限制。
第二,请确保将范围略微缩小以免达到256。
public int GetRangedValue(double value, double min, double max)
{
int outputLimit = 256;
double range = (max - min) - double.Epsilon; // Here we shorten the range slightly
// Then we build a range such that value >= 0 and value < 1
double rangedValue = (value - min) / range;
return (int)(outputLimit * rangedValue);
}
通过这两个更改,您将在输出中获得正确的分布。
答案 3 :(得分:0)
当我深入研究使用 C++ 做一些卷积的东西时,我解决了这个需求。
希望我的代码能给你一个有用的参考:)
bool normalize(uint8_t*& dst, double* src, int width, int height) {
dst = new uint8_t[sizeof(uint8_t)*width*height];
if (dst == NULL)
return false;
memset(dst, 0, sizeof(uint8_t)*width*height);
double max = std::numeric_limits<double>::min();
double min = std::numeric_limits<double>::max();
double range = std::numeric_limits<double>::max();
double norm = 0.0;
//find the boundary
for (int j=0; j<height; j++) {
for (int i=0; i<width; i++) {
if (src[i+j*width] > max)
max = src[i+j*width];
else if (src[i+j*width] < min)
min = src[i+j*width];
}
}
//normalize double matrix to be an uint8_t matrix
range = max - min;
for (int j=0; j<height; j++) {
for (int i=0; i<width; i++) {
norm = src[i+j*width];
norm = 255.0*(norm-min)/range;
dst[i+j*width] = (uint8_t)norm;
}
}
return true;
}
基本上输出(calley 通过 'dst' 接收)大约是 [0, 255]。