博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
访问cv::Mat中的数据时遇到的指针类型问题
阅读量:5911 次
发布时间:2019-06-19

本文共 2291 字,大约阅读时间需要 7 分钟。

在用Opencv的时候由于下图原本的图像尺寸是1111*1111,要进行resize,代码如下:

cv::Mat img = cv::imread("//Users//apple//td3//vase//19201.png",CV_LOAD_IMAGE_GRAYSCALE);cv::Mat img2;cv::resize(img, img2, cv::Size(400,400),0,0, cv::INTER_AREA);

因为我根本不知道img的数据是什么类型(不知道数据类型根本无法通过指针计算来访问每个像素的值,而且我想操作逐个像素来做blur),然后我就用int指针去访问,结果自然是很容易错误的。我将访问的值写入文本之后发现都是些奇怪的数值,例如-1,4294967296(2^32),还以其他奇葩数值。结果如果我利用其opencv自己重载的函数输出:

std::cout << img2.at
(0,0); //输出(0,0)的像素值为-1std::cout << img2; //输出矩阵的所有像素的像素值,结果很正常属于[0,255]

结果我以为矛盾,然后直接访问img2.data成员,写了一些很没道理的代码:

for(int row = 0; row 

然后设置断点查看了下img2.data里面的数据是'\xff',然后用cout打印出来是'\377',原来是字符串的十六进制和八进制表示,仔细分析为什么'\377'的值是-1,结果得出:

在C中有两种特殊的字符,八进制转义字符和十六进制转义字符,八进制字符的一般形式是'\ddd',d是0-9的数字。十六进制字符的一般形式是'\xhh',h是0-9或A-F内的一个。八进制字符和十六进制字符表示的是字符的ASCII码对应的数值。比如

'\063'表示的是字符'3',因为'3'的ASCII码是30(十六进制),48(十进制),63(八进制)。

'\x41'表示的是字符'A',因为'A'的ASCII码是41(十六进制),65(十进制),101(八进制)。

负数在计算机内部是用补码表示的例如 -11 的原码是 0000 0001则 -1 的反码是 1111 1110补码是 1111 1111

因为我强制转换为int指针,所以是指针指向的数是有符号的,并且一次性取得32位,将这4个'\xff'表示为二进制:1111 1111 1111 1111 1111 1111 1111 1111(32个1)所以在有符号整数中的值就是-1,而在无符号中的值又是4294967295。但是均不是我想要的255,然后查了各种资料,结果看到这个网站:

http://stackoverflow.com/questions/23819445/why-is-xff-not-being-recognized

中有一句话剪切过来:

'\xff' is a character constant, not a string literal. String literals have no signedness; they represent arrays. Type char may be either signed or unsigned, depending on the implementation. If plain char is  unsigned, then '\xff' has the value 255 of type int. If plain char is signed, the wording of the standard is unclear (at least to me).

 结果我试了几组代码:

char *sign_t = new char('\377');int j = *sign_t; //值是-1uint *intTest = new uint('\xff\xff\xff\xff'); //值是4294967295uchar *t = new uchar('\xff');int *pp = (int*)t; //值是255

结果我明白了很多,错误始终是在一开始我根本不清楚cv::Mat中的数据的深度和通道信息,然后我搜索了到了一个解答:

http://stackoverflow.com/questions/10167534/how-to-find-out-what-type-of-a-mat-object-is-with-mattype-in-opencv

http://answers.opencv.org/question/742/matrix-depth-equals-0/

将其解答剪切出来,我们可以用img2::type(), img2::channels(), img2::depth()来确定mat的类型。但是img2::type与img2::depth()需要区别如下:

So,至此所有问题都明朗了,最后贴上一个正确访问CV_8UC1类型Mat.data数据的代码:

for(int row = 40; row 

 

结果图如下:

 

 

 

 

 

 

 

还有留下的问题需要解决,继续看opencv,就是如果我要逐个操作每个像素值,我是否应该将CV_8UC1类型转为浮点型计算完成之后再转回来。还有另外一个问题就是负数的二进制表示还需要再看看资料。

转载于:https://www.cnblogs.com/Key-Ky/p/4189170.html

你可能感兴趣的文章
csu2161: 漫漫上学路(Hash+最短路)
查看>>
重复引用错误:duplicate symbols for architecture x86_64
查看>>
计算机图形学 课设
查看>>
ucenter1.5通讯过程分析(转载)
查看>>
js和html5实现画板
查看>>
浏览器中可以访问,但是git命令、go get命令使用时却无法连接
查看>>
Apache Spark源码走读之7 -- Standalone部署方式分析
查看>>
如何避免重构带来的危险
查看>>
有序的双链表
查看>>
MSSQLServer的备份与还原
查看>>
Eclipse导入的项目中发现包的形式变成了文件夹的形式,需要将文件夹的形式变成包...
查看>>
使用MySQL yum源安装MySQL
查看>>
iOS8中使用CoreLocation定位
查看>>
R语言处理Time series
查看>>
mvn package时设置了maven.test.skip=true依旧执行单元测试
查看>>
Java学习笔记(一)背景知识
查看>>
PAT 1118 Birds in Forest [一般]
查看>>
Adapting to views using css or js
查看>>
020PHP基础知识——函数(三)
查看>>
构造函数&&继承8.1
查看>>