前言
一些工业相机采集的图像是16位的,不方便进行图像处理。比如opencv处理的常常是8位灰度图像,而深度学习模型输入图像也往往是单通道或者三通道的。因此,对16位图像做位深度转换,从而方便后续的一系列操作,是很有必要的!
本文主要介绍用opencv+numpy实现16位图像转8位图像,做法是线性缩放
线性缩放
- 基本原理:将16bit图像的动态范围映射到0-255
- 公式:
matrix_16: 16bit图像矩阵
min: 16bit图像动态范围最小值
max: 16bit图像动态范围最大值
matrix_8: 8bit图像矩阵
matrix_8=255.0∗(matrix_16 - min)/(max - min) - 代码实现
import cv2
import numpy as np
def transfer_16bit_to_8bit(image_path):
image_16bit = cv2.imread(image_path, cv2.IMREAD_UNCHANGED)
min_16bit = np.min(image_16bit)
max_16bit = np.max(image_16bit)
# image_8bit = np.array(np.rint((255.0 * (image_16bit - min_16bit)) / float(max_16bit - min_16bit)), dtype=np.uint8)
# 或者下面一种写法
image_8bit = np.array(np.rint(255 * ((image_16bit - min_16bit) / (max_16bit - min_16bit))), dtype=np.uint8)
print(image_16bit.dtype)
print('16bit dynamic range: %d - %d' % (min_16bit, max_16bit))
print(image_8bit.dtype)
print('8bit dynamic range: %d - %d' % (np.min(image_8bit), np.max(image_8bit)))
image_path = './00003.tif'
transfer_16bit_to_8bit(image_path)
- 关键代码块
image_8bit = np.array(np.rint((255.0 * (image_16bit - min_16bit)) / float(max_16bit - min_16bit)), dtype=np.uint8)
# 或者下面一种写法
image_8bit = np.array(np.rint(255 * ((image_16bit - min_16bit) / (max_16bit - min_16bit))), dtype=np.uint8)
- 输出结果
uint16
16bit dynamic range: 80 - 1084
uint8
8bit dynamic range: 0 - 255
扩展
如果是使用单通道图像训练深度学习分类网络,可参考我的另一篇博客:ResNet训练单通道图像分类网络(Pytorch)