使用C++ opencv将16位图像转换为8位

现在有一张16bit深度的图像,如果不使用PS或者其他工具的话,是很难直接获取到图像里储存的信息的。如下。

直接在Window里打开一张16位tif格式的图片

如果能将16位转换成8位的话,就能正常显示了。

原理

一张16位的图像,意思是一张图像的每个像素点的像素值都由16位的二进制数表示,每个像素点的颜色有 2^16 = 65536 种可能。

也就是说,图像的颜色区间被划分成了2^16 = 65536份。

同理,8位图像,图像的颜色区间被划分成了2^8 = 256份。

那么,将16位转换成8位,不就是将区间 [0,65535] 映射到 [0,255] 吗?

软件环境

  • VS2017
  • OPENCV 3.41

测试与分析

16位到8位,是高精度到低精度的转换,必然造成信息的丢失
在实际的测试中也是这样。

下面是笔者直接将16位映射到8位的转换结果

这实际上是一张失真很严重的图像。

上面这种方法虽然道理是没错,但是这种转换遗失了图像中太多信息,不是我们想要的。然而当我在百度上搜索关于16位到8位图像的转换思路的时候,提供的却大多是这种方法,这也是我写这篇博客的原因。

问题的原因是我

错误地认为了16位的图像像素值就是分布在 [0,65535] 的。

解决的方法是:

取图像 像素值 最小值 到 最大值 区间映射到[0,255]。

最终处理结果如下:

是不是感觉细节层次丰富了很多呢?

代码

#include <iostream>
#include <opencv.hpp>
#include <opencv\highgui.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>using namespace cv;
using namespace std;int main()
{DWORD Start_time = GetTickCount(); //计时开始Mat img = imread("task1.tif", CV_LOAD_IMAGE_UNCHANGED);//加载图像;int width = img.cols;//图片宽度int height = img.rows;//图片高度Mat dst = Mat::zeros(height, width, CV_8UC1);//先生成空的目标图片double minv = 0.0, maxv = 0.0;double* minp = &minv;double* maxp = &maxv;minMaxIdx(img, minp, maxp);  //取得像素值最大值和最小值//用指针访问像素,速度更快ushort *p_img;uchar *p_dst;for (int i = 0; i < height; i++){p_img = img.ptr<ushort>(i);//获取每行首地址p_dst = dst.ptr<uchar>(i);for (int j = 0; j < width; ++j){p_dst[j] = (p_img[j] - minv) / (maxv - minv) * 255;//下面是失真较大的转换方法//int temp = img.at<ushort>(i, j);//dst.at<uchar>(i, j) = temp;}}DWORD End_time = GetTickCount(); //计时结束cout << "Time used:" << End_time - Start_time << " ms"<<'\n';imshow("8bit image", dst);imwrite("task1_8bit.jpg", dst);waitKey(0);system("pause");return 0;
}

不光是16位,24位图像的转换也是同样的思路,感兴趣的朋友可以自己试一试。
不过要另外多说一句,高精度到低精度,信息的丢失是不可避免的,上面提供的方法只是相对效果更好。

补充: 关于数据类型的说明
ushort 为无符号16位整数,占2个字节,取值范围在0~65,535之间。
uchar 为无符号8位,占1个字节,取值范围在0~255之间。

要转换数据记得选择合适的数据类型哦。

使用C++ opencv将16位图像映射到8位相关推荐

  1. python将图像转换为8位单通道_Python OpenCV读取16位单通道图像并转换为8位灰度图显示...

    语义.实例分割数据集的标注图像以及一些深度图像等都是由单通道16位整型图像存储的,我们通常需要读取这种图像并显示出来,由于OpenCV一般只能够对8位图像进行显示,也就是像素范围在0-255的图像,而 ...

  2. opencv读取16位色深图片

    最近希望使用opencv处理从realsense获取的深度图像,但是realsense的深度图是单通道16位的,而opencv的显示函数默认接收的数据类型都是uint8,实际使用存在一些问题 open ...

  3. 使用opencv将16位深度图转灰度图

    使用opencv将16位深度图转灰度图,默认深度图每个像素以uint16_t来保存. #include <string> #include "opencv2/core/core. ...

  4. 色彩深度、位深度、8位图像、16位图像、24位图像

    在数字图像处理中,平时所说的1位图像.8位图像.16位图像.24位图像.32位图像等,其中的"位"是指图像中每一个像素点的色彩深度,或位深度. 在处理数字图像中的颜色时,计算机实际 ...

  5. (阿里/百度/腾讯)云服务器建站全过程(Ubuntu Server 16.04.1 LTS 64位)

    (阿里/百度/腾讯)云服务器建站全过程(Ubuntu Server 16.04.1 LTS 64位) 注:这是作者利用周末时间,研究了一下云服务器的建站过程,以下是整理出来的学习笔记,仅供参考,如果有 ...

  6. opencv如何把16位图像转换为8位图像

    一.opencv自带的方法: Mat src16,tmp; Mat dst8 = Mat::zeros(src16.size(), CV_8U); normalize(src16, tmp, 0, 2 ...

  7. 【OpenCV 】Remapping 重映射¶

    目录 1.1目标 1.2 理论 1.3 代码 1.4 运行结果 1.1目标 展示如何使用OpenCV函数 remap 来实现简单重映射. 1.2 理论 把一个图像中一个位置的像素放置到另一个图片指定位 ...

  8. opencv Remap 图像的映射

    重映射是什么意思? 把一个图像中一个位置的像素放置到另一个图片指定位置的过程. 为了完成映射过程, 有必要获得一些插值为非整数像素坐标,因为源图像与目标图像的像素坐标不是一一对应的. 我们通过重映射来 ...

  9. [OpenCV] cv.remap() 重映射学习笔记/map1 map2易混点

    文章目录 一.背景 二.Notes (一)更新几个小例子方面理解remap 1. 利用remap 进行 copy 2.进行翻转 学习remap的时候发现map1和map2的参数跟我的直观理解略有差别, ...

最新文章

  1. 还原淘宝首页最顶部的导航栏(含下拉菜单,图标等)
  2. 2020——网鼎杯 (青龙组)signal
  3. 玩转springboot:实现springboot自定义拦截器
  4. 一目了然“之IT运维可视化,让运维不再说难!
  5. Node搭建静态资源服务器时后缀名与响应头映射关系的Json文件
  6. JZOJ 3899. 【NOIP2014模拟】逻辑的连通性
  7. boost::multiprecision模块logged_adaptor相关的测试程序
  8. springmvc框架下Filter过滤器中过滤文件后 后续 controller为空的问题
  9. c语言猴子选大王指针,C语言描述怎么用循环队列实现猴子选大王
  10. 一只刚学竞价两周的菜鸟
  11. css3中的@font-face的用法(定义多个规则)
  12. 贾俊平统计学思维导图- 第六章 统计量及其抽样分布
  13. 最适合程序员敲代码用的显示器,包邮送!
  14. 一键禁用Win10自动更新,联想官方出品!!
  15. 机器学习实战(Machine Learning in Action)学习笔记————10.奇异值分解(SVD)原理、基于协同过滤的推荐引擎、数据降维...
  16. Assertion failed: Protocol wrong type for socket [10041] zeromq 4.3.1\src\ip.cpp:417)错误
  17. 单片机__LED点阵学习收获
  18. 论文阅读笔记《Principal characteristic networks for few-shot learning》
  19. 计算机网络——局域网(期末复习)
  20. 日语动词里的未然形、连用形、终止形、连体形、假定形、命令形、推量形各代表的意思

热门文章

  1. 刷脸自助登记 访客管理不再潦草应对!
  2. 从爆款单品到全屋智能 Aqara如何引领行业变革
  3. python迭代对象是什么意思_python的迭代对象
  4. php微信支付mch_id参数格式错误,再说一下微信支付踩到的坑 mch_id 参数格式错误...
  5. 2022秋招前端面试题(一)(附答案)
  6. MQTT学习笔记——Yeelink MQTT服务 使用mqtt.js和paho-mqtt
  7. Cannot mix different versions of joi schemas报错解决方案
  8. 计算机键盘打字基础知识,计算机基础知识:计算机键盘的使用
  9. linux里面查找替换命令,LINUX 查找替换命令 总结
  10. 动态内存分配实现冒泡排序