一、imread读入tiff图
imread函数原型:
cv::Mat imread(const string& filename, int flags = 1 );
filename:读取图像的路径
flags :读入图像的格式
flags枚举,具体如下:
enum
{
/* 8bit, color or not */
CV_LOAD_IMAGE_UNCHANGED =-1,
/* 8bit, gray */
CV_LOAD_IMAGE_GRAYSCALE =0,
/* ?, color */
CV_LOAD_IMAGE_COLOR =1,
/* any depth, ? */
CV_LOAD_IMAGE_ANYDEPTH =2,
/* ?, any color */
CV_LOAD_IMAGE_ANYCOLOR =4
};
CV_LOAD_IMAGE_UNCHANGED – 该标识已经弃用
CV_LOAD_IMAGE_GRAYSCALE – 将图像读入为灰度
CV_LOAD_IMAGE_COLOR – 将图像读入为彩色
CV_LOAD_IMAGE_ANYDEPTH – 若读入的图像的深度为16位或者32位,返回对应深度的图像,否则,就转换为8位图像再返回
CV_LOAD_IMAGE_ANYCOLOR - 若读入图像为3通道,返回3通道图像,否则,转为单通道图像返回
灰度图、RGB图、多通道图、单通道图等一般图像,其像素取值都是0~255的整型值,也就是常说的8bit(2^8=256)图。而tiff图的像素值为浮点型,即16bit(float)或32bit(double),如果采用灰度图、RGB图等整形图的格式读入,则无法读入tiff图。
在imread函数的flags枚举中,其CV_LOAD_IMAGE_UNCHANGED 、CV_LOAD_IMAGE_GRAYSCALE 、CV_LOAD_IMAGE_COLOR 、CV_LOAD_IMAGE_ANYCOLOR
均为整型图的读入项,只有CV_LOAD_IMAGE_ANYDEPTH
可读入浮点型,选择该项后,imread函数会自动创建一张CV_32F
类型的图像,然后填入数据。因而读取tiff图时flags应当设置为CV_LOAD_IMAGE_ANYDEPTH
或2
。
示例代码:
cv::Mat img = cv::imread(tiffPath, CV_LOAD_IMAGE_ANYDEPTH);
二、tiff图转换为灰度图
灰度图的数据类型必须是uint8,因而tiff图转换为灰度图的问题,即是将tiff的float像素值转化为0~255的整型值,然后写入一张CV_8U类型的灰度图即可。
假设tiff图最大深度值为z_max,最小深度值为z_min,得到tiff图深度区间
z_length = z_max - z_min
tiff像素值起始点归零值
bias = -z_min
转换间隔
grayStep = 255.0f / z_length
最终转换式
f(i,j) = (x(i,j) + bias) * grayStep
示例代码:
float bias = -z_min;
float z_length = z_max - z_min;
float grayStep = 255.0f / z_length;
cv::Mat gray(img.rows, img.cols, CV_8UC1);
for (size_t i = 0; i < img.rows; i++)
{
for (size_t j = 0; j < img.cols; j++)
{
int grayVal = (int)((img.at<float>(i, j) + bias)*grayStep);
gray.at<uchar>(i, j) = grayVal;
}
}
至于像素访问、赋值时的类型问题(即gray.at<uchar>(i, j)
),参考下表