OpenCV关于IplImage的imageData问题出现负值
2012-04-03 20:30
295 查看
今天在
原来是
vc编译器、x86上的 gcc 都把 char 定义为 signed char;而 arm-linux-gcc 却把 char 定义为 unsigned char 。
不带signed或unsigned关键字的char型 无符号数? 有符号数? C标准规定为 Implementation Defined(由实作环境决定)。
arm-linux-gcc 规定 char 为 unsigned char 。
gcc规定为signed char
以前总以为 char 代表有符号,而 unsigned char 代表无符号。现在才知道如果换做 short 或 int ,这样理解都没问题,因为c标准明确定义了。但是,唯独 char 不能这样理解,因为c标准中对此是 Impementation Defined,就是未明确定义,由具体的编译器明确定义。
为了代码移植,一定不要用 char !
我以前总以为 char 代表有符号,而 unsigned char 代表无符号。现在才知道如果换做 short 或 int , 这样理解都没问题,因为c标准明确定义了。但是,唯独 char 不能这样理解,因为c标准中对此是 Impementation Defined,就是未明确定义,由具体的编译器明确定义。
vc编译器、x86上的 gcc 都把 char 定义为 signed char;而 arm-linux-gcc 却把 char 定义为 unsigned char 。这样一来,在代码移植上就会出现问题。举个最简单的例子:
char a = 0xb6; if ( a == 0xb6) puts("hello world !");
在vc 或 x86的gcc 上,都是不会打印出 hello world! 的。用 arm-linux-gcc 编译,在arm板上,是可以打印出hello world ! 的。是不是很神奇啊??? 我们再变化一下:
char a = 0xb6;
short b = 0xb600;
int c = 0xb6000000;
if ( a == 0xb6) puts("a");
if ( b == 0xb600) puts("b");
if ( c == 0xb6000000) puts("c");
在vc 或 x86的gcc 上,只会打印出 c 。用 arm-linux-gcc 编译,在arm板上,是可以打印出 a 和 c 。是不是发现了什么了呢?
首先,介绍 Integer Promotion 。通俗点说,c在处理整型(char short int)时,都会自动提升为int(如果int范围不够,则提升成 unsigned int)。比如 “a == 0xb6”,首先0xb6会当一个int来处理,变为0x000000b6(关于常量,后面还会仔细说明)。a 会提升为int ,假如 char 被定义为有符合的,那么 a 为负数,因为最高位为1,所以 a会提升为 0xffffffb6。假如 char 被定义为无符号的,那么a会提升为 0x000000b6
。
即,在vc 或 x86的gcc 上,a == 0xb6 会变为 0xffffffb6 == 0x000000b6 ,而在 arm-linux-gcc 上,变为 0x000000b6 == 0x000000b6。
对于 short,因为c标准明确规定 不加关键字,就代表有符号数。所以,无论在什么编译器上 b == 0xb600 都会变成 0xffffb600 == 0x0000b600 。
对于 int,本身是int,也就不用 Integer Promotion 了,所以 c == 0xb60000 中 ,c不做任何处理,直接从内存中读出来,即 0xb60000 == 0xb60000。
最后,简单说一下常量。我后面会转帖一部分资料,有兴趣可以看看,我现在只说用八进制(0开头)或十六进制(0x开头)表示的常量,他们都会当成无符号数处理!另外像 char a = 0xb6; 这句就有两个 Implementation Defined,一个是char带不带符号,另外一个是,假如char为有符合, 0xb6 会当int 0x000000b6 处理,把这个int 变为 有符合的 char 有溢出,会有问题,0xb6本为正数,赋值到a中却变为负数,具体要怎么处理,c对此也是 Implementation
Defined。
扩展阅读:http://learn.akae.cn/media/ch15s01.html
imageData[i*widthStep+j])<=127) image->imageData[i*widthStep+j]=0; 发线所有的值都变为了0,而且,跟踪发现imageData出现负值。
原来是
vc编译器、x86上的 gcc 都把 char 定义为 signed char;而 arm-linux-gcc 却把 char 定义为 unsigned char 。
不带signed或unsigned关键字的char型 无符号数? 有符号数? C标准规定为 Implementation Defined(由实作环境决定)。
arm-linux-gcc 规定 char 为 unsigned char 。
gcc规定为signed char
以前总以为 char 代表有符号,而 unsigned char 代表无符号。现在才知道如果换做 short 或 int ,这样理解都没问题,因为c标准明确定义了。但是,唯独 char 不能这样理解,因为c标准中对此是 Impementation Defined,就是未明确定义,由具体的编译器明确定义。
为了代码移植,一定不要用 char !
我以前总以为 char 代表有符号,而 unsigned char 代表无符号。现在才知道如果换做 short 或 int , 这样理解都没问题,因为c标准明确定义了。但是,唯独 char 不能这样理解,因为c标准中对此是 Impementation Defined,就是未明确定义,由具体的编译器明确定义。
vc编译器、x86上的 gcc 都把 char 定义为 signed char;而 arm-linux-gcc 却把 char 定义为 unsigned char 。这样一来,在代码移植上就会出现问题。举个最简单的例子:
char a = 0xb6; if ( a == 0xb6) puts("hello world !");
在vc 或 x86的gcc 上,都是不会打印出 hello world! 的。用 arm-linux-gcc 编译,在arm板上,是可以打印出hello world ! 的。是不是很神奇啊??? 我们再变化一下:
char a = 0xb6;
short b = 0xb600;
int c = 0xb6000000;
if ( a == 0xb6) puts("a");
if ( b == 0xb600) puts("b");
if ( c == 0xb6000000) puts("c");
在vc 或 x86的gcc 上,只会打印出 c 。用 arm-linux-gcc 编译,在arm板上,是可以打印出 a 和 c 。是不是发现了什么了呢?
首先,介绍 Integer Promotion 。通俗点说,c在处理整型(char short int)时,都会自动提升为int(如果int范围不够,则提升成 unsigned int)。比如 “a == 0xb6”,首先0xb6会当一个int来处理,变为0x000000b6(关于常量,后面还会仔细说明)。a 会提升为int ,假如 char 被定义为有符合的,那么 a 为负数,因为最高位为1,所以 a会提升为 0xffffffb6。假如 char 被定义为无符号的,那么a会提升为 0x000000b6
。
即,在vc 或 x86的gcc 上,a == 0xb6 会变为 0xffffffb6 == 0x000000b6 ,而在 arm-linux-gcc 上,变为 0x000000b6 == 0x000000b6。
对于 short,因为c标准明确规定 不加关键字,就代表有符号数。所以,无论在什么编译器上 b == 0xb600 都会变成 0xffffb600 == 0x0000b600 。
对于 int,本身是int,也就不用 Integer Promotion 了,所以 c == 0xb60000 中 ,c不做任何处理,直接从内存中读出来,即 0xb60000 == 0xb60000。
最后,简单说一下常量。我后面会转帖一部分资料,有兴趣可以看看,我现在只说用八进制(0开头)或十六进制(0x开头)表示的常量,他们都会当成无符号数处理!另外像 char a = 0xb6; 这句就有两个 Implementation Defined,一个是char带不带符号,另外一个是,假如char为有符合, 0xb6 会当int 0x000000b6 处理,把这个int 变为 有符合的 char 有溢出,会有问题,0xb6本为正数,赋值到a中却变为负数,具体要怎么处理,c对此也是 Implementation
Defined。
扩展阅读:http://learn.akae.cn/media/ch15s01.html
相关文章推荐
- 关于在VS2012下opencv+QT出现“无法解析的外部命令”问题的解决方案
- opencv中关于图像图像处理时出现Bad argument (Array should be the cvMat or IplImage) in unknown function ……错误的解决办法
- 关于opencv编译出现importerror:../../lib/libopencv_core.so cannot share or open问题
- Opencv 中透视变换函数对IplImage图像变换时出现的问题?
- 关于解决在使用opencv时出现*.exe 已触发了一个断点的问题
- 关于在linux平台或cygwin平台运行opencv出现Illege instruction(core dump)问题的缘由
- 关于vs2012中opencv调试出现的问题的一些感受
- 关于在python3.5下配置opencv3.0出现的问题
- 关于配置好了openCV后,新建第二个project可能出现的Link问题
- OpenCV中IplImage*转化为cv::mat时出现的问题
- 关于opencv摄像头图像显示 经常出现select timeout的问题
- 关于OpenCV中IplImage的字节对齐问题
- 关于Android studio安装出现“ 'tools.jar' seems to be not in Android Studio classpath..."的问题
- 关于从js用Jquery向Action传递值出现中文乱码的问题解决
- OpenCV2.0在VS2010配置中出现问题的解决方法 VS2010 C++中出现常见问题:back_inserter
- 关于库的手动引入出现的头文件不存在的问题
- 关于写数3缺1程序过程中出现的问题总结
- 关于用ST-Link V2下载出现internal command error和keil无法识别ST—LINK的问题解决法法如下
- 关于连接SQLSERVER2005数据出现Net Authenticated权限问题
- 安卓初学者关于在setContentView(..)出现source not found 的问题