今天,抽短暂时间实现了一个新的功能,那就是16位图像的读取以及伪彩色视觉效果增强。个人感觉各种语言还是C++好用,PY虽然很火,但是项目中执行效率是真的难受。 如果你真的了解opencv等,你会发现,opencv默认读取的是8位图像数据,如果需要读取16位深度的图像,你需要进行相应的处理。你会奇怪位深度对于一个图像有什么用,位深度用于指定图像中的每个像素可以使用的颜色信息数量。每个像素使用的信息位数越多,可用的颜色就越多,颜色表现就更逼真。例如,位深度为 1 的图像的像素有两个可能的值:黑色和白色。位深度为 8 的图像有 28(即 256)个可能的值。位深度为 8 的灰度模式图像有 256 个可能的灰色值。RGB 图像由三个颜色通道组成。8 位/像素的 RGB 图像中的每个通道有 256 个可能的值,这意味着该图像有 1600 万个以上可能的颜色值。有时将带有 8 位/通道 (bpc) 的 RGB 图像称作 24 位图像(8 位 x 3 通道 = 24 位数据/像素)。除了 8 位/通道的图像之外,Photoshop 还可以处理包含 16 位/通道或 32 位/通道的图像。包含 32 位/通道的图像也称作高动态范围 (HDR) 图像。 灰度是描述灰度图像内容的最直接的视觉特征。它指黑白图像中点的颜色深度,范围一般从0到255,白色为255,黑色为0,故黑白图像也称灰度图像。灰度图像矩阵元素的取值通常为[0,255],因此其数据类型一般为8位无符号整数,这就是人们通常所说的256级灰度。将灰度图像转换为彩色图像,称为灰度图像的伪彩色处理。伪彩色处理技术的实现方式有很多,如:灰度分割法、灰度级-彩色变换法、滤波法等等。以下采用的是灰度级-彩色变换法,这是将来自传感器的灰度图像送入三个不同特征的R、G、B变换器,然后将三种变换器的不同输出分别送到彩色显示器进行显示的技术。 你能在图像属性查看位深—> 了解这些之后,你可以进行opencv加载16位图像数据,其实,准确来说,不管以哪一种形式进行加载,对于人的视觉来说差距不是特别大,对于windows来说会进行优化,最后都转换为8位进行显示,参考我的代码,你能实现16位图像的读取。 这样的话输出的源文件的位深度就是16位,如果直接进行读取,获取到的就是8位深度。 接下来定义三个单通道RGB,定义为16位深度。参考我下面的代码: 那么,如何将16位数据进行伪彩色的转换呢,这是个问题,值得思考。 映射关系如下,其中R(x,y)、G(x,y)、B(x,y)分别表示R、G、B通道的颜色值,f(x,y)表示特定点灰度图像的灰度值,f是所选灰度图像的灰度值。但是,你得明白,这里的关系是8位图对应的转换。 我进行了简单的对应处理,这个很简单的,就是一个线性对应而已,但是你必须得知道,这个是不好的,但是是可以这么做的。 —->I did a simple correspondence, this is a very simple one, it’s just a linear correspondence, but you have to know, this is bad, but you can do it this way. 最后,就是三个通道的合并,使用函数merge()。 merge()函数:split()函数的逆向操作——将多个数组合并成一个多通道数组,将给定的这些孤立的单通道数组合并成一个多通道数组,从而创建一个由多个单通道阵列组成的多通道阵列。 原型:<1>C++: void merge(const Mat* mv, size_tcount, OutputArray dst); 变量介绍如下: Merge () function: the reverse of the split() function, which merges multiple arrays into a multichannel array, merges a given set of isolated single-channel arrays into a multichannel array to create a multichannel array consisting of multiple single-channel arrays. Prototype: <1>C++: void merge(const Mat* mv, size_tcount, OutputArray dst); Variables are introduced as follows: (1)The first parameter: mv, filling the array of input matrix or vector containers that need to be merged; (2)The second parameter: count, when mv is a blank C array, represents the number of input matrix, which must be greater than 1 obviously; (3)The third parameter: DST, the output matrix, has the same size and depth as mv[0], and the number of channels is the total number of channels in the matrix array. 结果: my main code: I hope I can help you,If you have any questions, please comment on this blog or send me a private message. I will reply in my free time.

Mat img = imread("./1.tif", cv::IMREAD_LOAD_GDAL | cv::IMREAD_ANYDEPTH); //------------------------------------------------------------- cout << "源文件位深度:"<<img.depth() << endl; //------------------------------------------------------------- //------------------------------------------------------------- Mat image(img.rows,img.cols,CV_16U); for (int i = 0;i < image.rows;i++) { for (int j = 0;j < image.cols;j++) { image.at<short>(i, j) = img.at<short>(i, j); //注意这里.at<>尖括号里的类型是16位图对应的short类型不是8位图对应的uchar类型 } } //------------------------------------------------
//------------------------------------------------ Mat R(image.rows,image.cols,CV_16U); Mat G(image.rows,image.cols,CV_16U); Mat B(image.rows,image.cols,CV_16U); R = image.clone(); G = image.clone(); B = image.clone(); cout << "R文件位深度:"<< R.depth() << endl; cout << "G文件位深度:"<< G.depth() << endl; cout << "B文件位深度:"<< B.depth() << endl; //------------------------------------------------



int rows = image.rows; int cols = image.cols; for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { int current = image.at<short>(i, j);//uchar 8位 if ( current >= 0 && current <= 16448) { R.at<short>(i, j) = 0; G.at<short>(i, j) = 4 * current; B.at<short>(i, j) = 65535; } else if (16448 < current && current <= 32896) { R.at<short>(i, j) = 0; G.at<short>(i, j) = 65535; B.at<short>(i, j) = (-4)*(current-32896); } else if (32896 < current && current <= 49344) { R.at<short>(i, j) = 4 * (current - 32896); G.at<short>(i, j) = 65535; B.at<short>(i, j) = 0; } else { R.at<short>(i, j) = 65535; G.at<short>(i, j) = (-4)*(current - 65535); B.at<short>(i, j) = 0; } } }
<2>C++: void merge(InputArrayofArrays mv,OutputArray dst);
第一个参数:mv,填需要被合并的输入矩阵 或 vector容器的阵列;
第二个参数:count,当mv为一空白C数组时,代表输入矩阵的个数,显然必须大于1;
第三个参数:dst,即输出矩阵,和mv[0]具有相同的尺寸和深度,并且通道的数量是矩阵阵列中通道的总数。
<2>C++: void merge(InputArrayofArrays mv,OutputArray dst);
Mat imgArray[3]; imgArray[0] = R; imgArray[1] = G; imgArray[2] = B; Mat newImg; merge(imgArray, 3, newImg); cout << "out文件位深度:"<< newImg.depth() << endl; imwrite("./16_24output.tif",newImg);


//--------------------------------------------------------------------- int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); /* 例如:一幅画的尺寸是1024*768,深度为16,则它的数据量为1.5M。 计算如下:102476816bit=(102476816)/8字节=[(102476816)/8]/1024KB={[(102476816)/8]/1024}/1024MB。 深度组合 输入深度(src.depth()) 输出深度(ddepth) CV_8U -1 / CV_16S / CV_32F / CV_64F CV_16U / CV_16S -1 / CV_32F / CV_64F CV_32F -1 / CV_32F / CV_64F CV_64F -1 / CV_64F 注意 当ddepth = -1时,输出图像将具有与源相同的深度。 */ /*depth 图像元素的位深度,可以是下面的其中之一: 位深度 取值范围 IPL_DEPTH_8U - 无符号8位整型 0--255 IPL_DEPTH_8S - 有符号8位整型 -128--127 IPL_DEPTH_16U - 无符号16位整型 0--65535 IPL_DEPTH_16S - 有符号16位整型 -32768--32767 IPL_DEPTH_32S - 有符号32位整型 0--65535 IPL_DEPTH_32F - 单精度浮点数 0.0--1.0 IPL_DEPTH_64F - 双精度浮点数 0.0--1.0 */ /* Mat_<uchar>对应的是CV_8U,Mat_<char>对应的是CV_8S, Mat_<int>对应的是CV_32S,Mat_<float>对应的是CV_32F, Mat_<double>对应的是CV_64F,对应的数据深度如下: • CV_8U - 8-bit unsigned integers ( 0..255 ) • CV_8S - 8-bit signed integers ( -128..127 ) • CV_16U - 16-bit unsigned integers ( 0..65535 ) • CV_16S - 16-bit signed integers ( -32768..32767 ) • CV_32S - 32-bit signed integers ( -2147483648..2147483647 ) • CV_32F - 32-bit floating-point numbers ( -FLT_MAX..FLT_MAX, INF, NAN ) • CV_64F - 64-bit floating-point numbers ( -DBL_MAX..DBL_MAX, INF, NAN ) */ /* #define CV_8U 0 #define CV_8S 1 #define CV_16U 2 #define CV_16S 3 #define CV_32S 4 #define CV_32F 5 #define CV_64F 6 #define CV_USRTYPE1 7 */ /* merge()函数:split()函数的逆向操作——将多个数组合并成一个多通道数组,将给定的这些孤立的单通道数组合并成一个多通道数组,从而创建一个由多个单通道阵列组成的多通道阵列。 原型:<1>C++: void merge(const Mat* mv, size_tcount, OutputArray dst); <2>C++: void merge(InputArrayofArrays mv,OutputArray dst); 变量介绍如下: 第一个参数:mv,填需要被合并的输入矩阵 或 vector容器的阵列; 第二个参数:count,当mv为一空白C数组时,代表输入矩阵的个数,显然必须大于1; 第三个参数:dst,即输出矩阵,和mv[0]具有相同的尺寸和深度,并且通道的数量是矩阵阵列中通道的总数。 */ //=================================================================================================== //=================================================================================================== //_8bit_24bit(); //=================================================================================================== //=================================================================================================== _16bit_48bit(); return a.exec(); }
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算
官方软件产品操作指南 (170)