繁体   English   中英

类型为unsigned char的负数

[英]Negative numbers of type unsigned char

我从头开始实现2D相关代码,我有一个简单的3x3图像矩阵,类型为unsigned char:

 unsigned char Image = [184   0   35
                        48   107  193
                        29   166  32]

我的相关内核

             Kernel = [-1 0 1]  

现在,当我执行相关时,第一行的结果在数学上是-149,但打印结果是107(2的补码)。

unsigned char res = -1.F *(Kernel[i-1]) + (Kernel[i+1]); 

这不是一个错误吗? 如何将结果保存为-149,但类型仍然保留为unsigned char? 我知道我的问题可能不合适,因为unsigned char的范围是0到255,但我想确定我是否遗漏了一些东西。 我也知道负数被转换成2的补码。
顺便说一下,这不是任何功课,我只是从图像处理的角度来研究C / C ++。

如何将结果保存为-149,但类型仍然保留为unsigned char?

不要这样做。 使用带符号的整数类型。

如果增加的内存使用量不是问题,请使用int
如果做不到,请使用short

在范围[0 max]的图像上计算渐变[-X 0 X]时,结果将在[-X max,X max]范围内。 根据您的需求和约束,有不同的方法来处理它:

  1. 如果您没有内存问题,可以增加编码(byte - > short,short - > int)。
  2. 如果你感兴趣但梯度强度而不是它的符号,你首先应用一个绝对值,以获得新的结果范围[0,X * max],然后你应用第三个解决方案
  3. 您可以拉伸结果以适应您想要的范围,这意味着您应用直方图拉伸(线性函数):[ - X max,X max] - > [0 max]。 不幸的是,这种解决方案失去了很多精确度。 对于您的示例,此解决方案将失去一半的精度(从[-255,255)]到[0,255]),除非您之前应用了点2。

现在,当我执行相关时,第一行的结果在数学上是-149,但打印结果是107(2的补码)。 这不是一个错误吗?

unsigned char res = -1.F *(Kernel[i-1]) + (Kernel[i+1]); 

res等无符号变量中保存负值不会更改res的类型。 它永远是unsigned char 通过重复添加/(或减去) UCHAR_MAX + 1 (256)来转换负值,直到它在unsigned char的范围内或在这种情况下: 107

要保存负值并在res保留负值,请使用符合范围要求的签名类型:

Type          Range of Type 
signed char   at least [-127 to 127]      Varies by platform
signed short  at least [-32767 to 32767]  Varies by platform
int8_t        exactly  [-128 to 127]
int16_t       exactly  [-32768 to 32767]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM