opencv2 读取16bit图像数据小结

https://blog.csdn.net/zhyh1435589631/article/details/49275945

今天师弟跑来问我一个关于opencv图像值读取的问题, 原话是这样的

在opencv中想要加载一幅16位的图像,鼠标点击显示其位置和灰度数值,但是我写的程序中灰度数值最多只能显示255

拿到这个问题, 自己也不是很清楚, 因为自己其实也是刚刚才接触opencv2.x, 虽然已经出来3了,anyway, 总是要装下逼的, 于是就让他把代码拿了过来, 打算自己调试一下。

本来想试试qt调试, 结果整了半天都没停到断点处, 只好换成了vs。 
经过调试发现:

  1. 一开始我们以为是数据载人有问题, 结果发现数据载入进来的确是 CV_16U类型的, 单通道灰度图。 imread 的参数 CV_LOAD_IMAGE_UNCHANGED 和 CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH 效果是一致的
  2. 我们试图用 Mat 的 at 方法读取数据, 由于at 是个模板方法, 试了一下发现 uchar 不行, Vec2b 也不行(后来发现, Vec2b 使用在 2 通道的情况底下的), 显然CV_16U 对应的类型应该是 2 个字节, 故而用 ushort 类型, 正好满足要求。 
    至此, 已经能够满足读取灰度值的要求了。
auto it = img.at<ushort>(y, x);
  • 1

3.师弟的程序中用了

        uchar * data = img.data;// img.at(i, j)data = img.data + pt.y*img.step + pt.x*img.elemSize();int intgray = (*data);
  • 1
  • 2
  • 3
  • 4

来获取灰度值, 显然是不正确的, 因为每个元素是 CV_16U 类型, ie, 每个图像数据占 2 个字节, 而这里仅仅只是访问到了该位置图像数据的第一个部分的数据, 前1个字节, 还剩下一个字节没有读取!!!

一般我们的intel cpu x86 x64 大多都是使用小端模式存储的, ie, 低地址放低字节, 高地址放高字节。 
在我们现在这个环境中, 高字节部分没有读取, 因而需要加上高字节部分, 同时需要注意 C++ 的 运算符优先级, 优先级

′+′>′<<′′+′>′<<′

因而 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);
  • 1
  • 2
  • 3
  • 4
  • 5

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);//加载图像}
}

读取16bit图像数据小结相关推荐

  1. opencv2 读取16bit图像数据小结

    今天师弟跑来问我一个关于opencv图像值读取的问题, 原话是这样的 在opencv中想要加载一幅16位的图像,鼠标点击显示其位置和灰度数值,但是我写的程序中灰度数值最多只能显示255 拿到这个问题, ...

  2. 从二进制数据流中构造GDAL可以读取的图像数据

    在很多时候,我们的图像数据往往都不是文件方式存储在磁盘上,而是可能从网络或者数据库中获取的是二进制的图像数据流.最简单的方式和最容易想到的方式就是将这个文件流保存到磁盘上形成一个文件,然后再使用GDA ...

  3. 8bit、12bit、16bit图像数据

        注:以下信息摘自各个网页和论坛.只是做一个综合.谢谢前辈们的分享. 一. 若R.G.B每种颜色使用一个字节(8bit)表示,每幅图像可以有1670万种颜色:若R.G.B每种颜色使用两个字节(1 ...

  4. 从二进制数据流中构造GDAL可以读取的图像数据(C#)

    在上一篇博客中,讲了一下使用GDAL从文件流中构造一个GDAL可以识别的数据来进行处理.原以为这个接口在C#中没有,仔细看了下GDAL库中源码,发现C#版本也有类似的函数,下面是GDAL库中的一个C# ...

  5. 【Matlab】Matlab读取dcm图像的函数以及CT值失真的问题处理

    Matlab版本:2020a 一.dicomread函数 Matlab读取dcm图像的函数是dicomread,根据dicomread的帮助文档,该函数有四种参数输入方式: X = dicomread ...

  6. PC电脑实时接收树莓派摄像头图像数据并显示(Python实现)

    目录 一.任务概述 二.环境安装 三.实现 3.1 上位机端(PC服务器端) 3.2 树莓派端(客户请求端) 四.运行效果 一.任务概述 最近在做一个树莓派自动驾驶小车,上位机使用windows10 ...

  7. Kinect V1读取图像数据(For Windows)

    Kinect V1读取图像数据(For Windows) 这篇博客 Kinect V1介绍 数据读取的基本流程 运行代码和注释 结尾 这篇博客  刚好有一台现成的Kinect V1相机,所以就拿过来学 ...

  8. 图像数据读取及数据扩增方法

    Datawhale干货 作者:王程伟,Datawhale成员 本文为干货知识+竞赛实践系列分享,旨在理论与实践结合,从学习到项目实践.(零基础入门系列:数据挖掘/cv/nlp/金融风控/推荐系统等,持 ...

  9. c++读取图片_Pytorch读取,加载图像数据(一)

    Pytorch读取,加载图像数据(一) 在学习Pytorch的时候,先学会如何正确创建或者加载数据,至关重要. 有了数据,很多函数,操作的效果就变得很直观. 本文主要用其他库读取图像文件(学会这个,你 ...

最新文章

  1. Spring Boot 2.x基础教程:使用@Scheduled实现定时任务
  2. Gartner2018新兴技术成熟度曲线:人机界线日益模糊!
  3. mysql 数据结构设计_MYSQL 设计数据结构需注意问题
  4. Java ObjectOutputStream writeFloat()方法与示例
  5. Java servlet ajax
  6. 人脸方向学习(十一):Face Landmark Detection-PFLD解读
  7. SpringCloud和AlibabaCloud区别
  8. Java 对字符以及字符数组的操作
  9. 基于FPGA的按键消抖
  10. 【2020年领域新星】 Ruibo Liu 达特茅斯学院
  11. Python实验、Pandas数据处理与分析
  12. 服务器上txt文件编辑器,网站后台文本编辑器使用方法
  13. 10分钟内在windows下安装woocommerce开发测试环境
  14. Spring--AOP知识学习
  15. 推荐几个美女和年薪百万大佬的公众号!
  16. ubtunu20.04 opencl 安装
  17. 【猿团专访】| 潜心研究的云视“华山派”,关于技术研发的那些事
  18. word中插入endnote 为什么会是大括号,而且后面没有文献
  19. java音视频开发技术_FFmpeg音视频核心技术精讲与实战
  20. 哈佛大学开放课程:《公正:该如何做是好?》8

热门文章

  1. 计算机英语作文50词左右带翻译,七年级英语作文50词左右及翻译
  2. 俄罗斯方块_c++实现
  3. 问题描述:Mybaits执行insert语句,执行一次会插入两次,数据库出现两条一模一样的记录
  4. MQTT协议的智能灯控
  5. 面向 JavaScript 开发人员的 5 大物联网库
  6. 【AC大牛陈鸿的ACM总结贴】【ID AekdyCoin】人家当初也一样是菜鸟
  7. ssh:connect to host xxx port 22: Connection refused---------you don‘t have permission to acccess the
  8. 华为在线机试训练Python答案1-5题
  9. 异或^操作符(C语言)
  10. 计算机网络——Windows 服务器基本配置使用