使用OpenCV编写图像窗宽窗位动态调节程序

本节介绍基于OpenCV编写图像窗宽窗位动态调节程序,主要实现两个进度条分别控制窗宽、窗位,将高位编码图像转化为可供显示的uint8数据类型。此处给出思路和许多功能模块的调用方法,完整代码可以在恰当的时机放出。

图像读取

对于一般图像来说读取图像只需简单调用函数,但注意这里我们读取的不是寻常8位三通道/单通道图像,而是16位图像,因此最好这样:

frame = imread("exp2_2.png", IMREAD_UNCHANGED);//无更改式读取原图

之后我们建立一个空间存放转换后的图像

Mat show_frame = Mat::zeros(frame.rows, frame.cols, CV_8UC1);

OpenCV中矩阵类型与内部数据类型对应关系

通式:CV_<bit_depth>(S|U|F)C<number_of_channels>

如果看不懂的话:

这个对应关系非常重要!

矩阵类型常量代号内部元素的数据类型
8位无符号整型单通道矩阵CV_8UC1uchar
8位无符号整型3通道矩阵CV_8UC3Vec3b、内部uchar
16位整型单通道矩阵CV_16SC1short
16位无符号整型单通道矩阵CV_16UC1ushort
32位浮点型单通道矩阵CV_32FC1float
64位浮点型三通道矩阵CV_64FC3Vec3b、double

OpenCV矩阵逐像素访问方法

在本程序中我们需要对图像矩阵内数据逐一遍历并操作,那么如何访问矩阵内特定元素呢,这里我们介绍at()方法,调用方式为:

对于单通道图像:

图像变量名.at<元素类型>(行,列)

对于多通道图像:

图像变量名.at<元素类型>(行,列)[通道]

注意上述元素类型,必须与图像矩阵的类型相对应,对应方式见上一节

例如对于正常的三通道RGB图像,我们可以这样调用元素:
 

uchar a = img.at<Vec3b>(y, x)[c]//y为行,x为列,c为通道,得到的结果是uchar类型

 但对于正常的单通道灰度图,我们要写

uchar a = img.at<uchar>(y, x)//y为行,x为列,得到的结果是uchar类型

但对于其他特殊图像,比如16位无符号单通道图像,我们要这样写:

ushort a = img.at<ushort>(y, x)//y为行,x为列,得到的结果是ushort类型

一定要注意元素类型与矩阵类型的对应性,16位无符号整型单通道矩阵(CV_16UC1)内的元数类型为ushort,写成其他类型,OpenCV在内存中会多读或少读字节,自然得不到正确的值。

把上述语句放在两层for循环中就能遍历图像了 

 OpenCV中饱和截断方法

在本文设计的任务“窗宽窗位调整”中,要对输入图像逐像素做这样的映射,必然涉及小于0或超出255的像素值的转换,可以使用OpenCV自带工具,如

saturate_cast<uchar>(a);

可以把变量a的值饱和截断,转换成uchar类型,类似Python中numpy.clip()方法

窗宽窗位变换函数

有了以上知识,本题思路已经很明确了

  • 使用合适的方法打开高位特殊图像
  • 建立8UC1类型空Mat
  • 逐像素访问图像,将原有像素值线性变换,使用(L-W/2,0)和(L+W/2,255)拟合变换曲线
  • 对变换后结果饱和截断,存入8UC1的Mat
  • 显示新Mat

当然为了展示效果,我们可以把上述步骤放在while循环里面,加上两个滑动条调节窗宽窗位,每次循环过程中根据窗宽窗位计算显示结果。

 

 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值