opencv2 读取16bit图像数据小结
2015-10-20 13:06
585 查看
今天师弟跑来问我一个关于opencv图像值读取的问题, 原话是这样的
在opencv中想要加载一幅16位的图像,鼠标点击显示其位置和灰度数值,但是我写的程序中灰度数值最多只能显示255
拿到这个问题, 自己也不是很清楚, 因为自己其实也是刚刚才接触opencv2.x, 虽然已经出来3了,anyway, 总是要装下逼的, 于是就让他把代码拿了过来, 打算自己调试一下。
本来想试试qt调试, 结果整了半天都没停到断点处, 只好换成了vs。
经过调试发现:
一开始我们以为是数据载人有问题, 结果发现数据载入进来的确是 CV_16U类型的, 单通道灰度图。 imread 的参数 CV_LOAD_IMAGE_UNCHANGED 和 CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH 效果是一致的
我们试图用 Mat 的 at 方法读取数据, 由于at 是个模板方法, 试了一下发现 uchar 不行, Vec2b 也不行(后来发现, Vec2b 使用在 2 通道的情况底下的), 显然CV_16U 对应的类型应该是 2 个字节, 故而用 ushort 类型, 正好满足要求。
至此, 已经能够满足读取灰度值的要求了。
3.师弟的程序中用了
来获取灰度值, 显然是不正确的, 因为每个元素是 CV_16U 类型, ie, 每个图像数据占 2 个字节, 而这里仅仅只是访问到了该位置图像数据的第一个部分的数据, 前1个字节, 还剩下一个字节没有读取!!!
一般我们的intel cpu x86 x64 大多都是使用小端模式存储的, ie, 低地址放低字节, 高地址放高字节。
在我们现在这个环境中, 高字节部分没有读取, 因而需要加上高字节部分, 同时需要注意 C++ 的 运算符优先级, 优先级 ′+′>′<<′ '+' \quad > \quad
'\lt\lt'
因而 data2 << 8 需要加上括号!!!
如下所示:
4.注意opencv图像表示中是按照行列来表示的, 图像坐标系处于图像的左上角, 而我们一般认为的 x, y 笛卡尔坐标系的原点是位于 图像的左下角, 通过 at 方法读取数据的时候, 要注意第一个参数应该表示图像的行, 第二个参数才是表示图像的列。
在opencv中想要加载一幅16位的图像,鼠标点击显示其位置和灰度数值,但是我写的程序中灰度数值最多只能显示255
拿到这个问题, 自己也不是很清楚, 因为自己其实也是刚刚才接触opencv2.x, 虽然已经出来3了,anyway, 总是要装下逼的, 于是就让他把代码拿了过来, 打算自己调试一下。
本来想试试qt调试, 结果整了半天都没停到断点处, 只好换成了vs。
经过调试发现:
一开始我们以为是数据载人有问题, 结果发现数据载入进来的确是 CV_16U类型的, 单通道灰度图。 imread 的参数 CV_LOAD_IMAGE_UNCHANGED 和 CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH 效果是一致的
我们试图用 Mat 的 at 方法读取数据, 由于at 是个模板方法, 试了一下发现 uchar 不行, Vec2b 也不行(后来发现, Vec2b 使用在 2 通道的情况底下的), 显然CV_16U 对应的类型应该是 2 个字节, 故而用 ushort 类型, 正好满足要求。
至此, 已经能够满足读取灰度值的要求了。
auto it = img.at<ushort>(y, x);
3.师弟的程序中用了
uchar * data = img.data; // img.at(i, j) data = img.data + pt.y*img.step + pt.x*img.elemSize(); int intgray = (*data);
来获取灰度值, 显然是不正确的, 因为每个元素是 CV_16U 类型, ie, 每个图像数据占 2 个字节, 而这里仅仅只是访问到了该位置图像数据的第一个部分的数据, 前1个字节, 还剩下一个字节没有读取!!!
一般我们的intel cpu x86 x64 大多都是使用小端模式存储的, ie, 低地址放低字节, 高地址放高字节。
在我们现在这个环境中, 高字节部分没有读取, 因而需要加上高字节部分, 同时需要注意 C++ 的 运算符优先级, 优先级 ′+′>′<<′ '+' \quad > \quad
'\lt\lt'
因而 data2 << 8 需要加上括号!!!
如下所示:
uchar * data = img.data; // img.at(i, j) data = img.data + pt.y*img.step + pt.x*img.elemSize(); uchar data2 = *(data + 1); int intgray = (*data) + (data2 << 8);
4.注意opencv图像表示中是按照行列来表示的, 图像坐标系处于图像的左上角, 而我们一般认为的 x, y 笛卡尔坐标系的原点是位于 图像的左下角, 通过 at 方法读取数据的时候, 要注意第一个参数应该表示图像的行, 第二个参数才是表示图像的列。
#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include<opencv.hpp> #include <opencv\highgui.h> using namespace cv; using namespace std; Mat img; //图像 const string lpwindowname = "图像09230021"; const string lpImageName = R"(E:\system dir\Desktop\QT\opencv2 computer vision\Opencv2\tmp\pixel\09230021.tif)"; void on_mousemove(int event, int x, int y, int flags, void* param); int mid(int i, int a, int b); int main() { img = imread(lpImageName, CV_LOAD_IMAGE_UNCHANGED);//加载图像 namedWindow(lpwindowname, 0);//创建窗口 imshow(lpwindowname, img);//在已经创建的窗口中显示图像 setMouseCallback(lpwindowname, on_mousemove, 0);//响应鼠标事件 waitKey(0); destroyAllWindows(); return 0; } int mid(int i, int a, int b) { return min(max(i, min(a, b)), max(a, b)); } void on_mousemove(int event, int x, int y, int flags, void* param) { //Font font; //cvinitFont(&font, CV_FONT_HERSHEY_DUPLEX, 1, 1, 1, 1, CV_AA); int width = img.cols;//图片宽度 int height = img.rows;//图片高度 Point text_pt; Size text_size; int baseline; if (event == CV_EVENT_LBUTTONDOWN) { x = mid(x, 0, img.cols); y = mid(y, 0, img.rows); // auto tmp = img.type(); // auto tmp2 = img.depth(); Point pt = Point(x, y); int aaa = img.channels(); uchar * data = img.data; // img.at(i, j) data = img.data + pt.y*img.step + pt.x*img.elemSize(); uchar data2 = *(data + 1); int intgray = (*data) + (data2 << 8); auto a2 = img.at<ushort>(y, x); // ************* 后面就没调试了 ****************** char site[100]; sprintf(site, "(%d,%d)%d", pt.x, pt.y, intgray); circle(img, pt, 2, Scalar(255, 255, 255), 1, CV_AA, 0); text_size = getTextSize(site, CV_FONT_HERSHEY_DUPLEX, 1, 1, &baseline); text_pt.x = mid(pt.x, 0, width - text_size.width); text_pt.y = mid(pt.y, text_size.height + baseline, height); putText(img, site, text_pt, CV_FONT_HERSHEY_DUPLEX, 1, Scalar(255,255,255), 1, CV_AA); imshow(lpwindowname, img); img = imread(lpImageName, CV_LOAD_IMAGE_UNCHANGED);//加载图像 } }
相关文章推荐
- linux shell 脚本中创建对话框 (whiptail 工具)
- centos 安装 GraphicsMagick
- python在linux(anaconda)的图形界面(snack)
- select option
- OPENCV笔记之环境搭建
- docker for windows 安装
- linux系统添加java和glassfish环境变量
- JSP userBean setProperty getProperty指令使用
- 硬盘MBR详细介绍
- 微软发布 Windows 版 OpenSSH 源码
- Tomcat7开启CGI支持的方法
- Modern Operating System --- Multiple Processor Systems
- 终极 Shell——ZSH
- linux iptables实现
- Linux进程和内核级进程的一些知识
- Mac OS10.10 openfire无法启动问题(转)
- apache与nginx 日志切割
- Mapreduce实例-Top Key
- openstack资源部署策略
- iscsi target tgt架构