【OpenCV 例程200篇】202. 查表快速替换(cv.LUT)

OpenCV 例程200篇 总目录
201. 图像的颜色空间转换
202. 查表快速替换(cv.LUT)
203. 伪彩色图像处理
204. 图像的色彩风格滤镜
205. 调节色彩平衡/饱和度/明度

文章目录

  • 【youcans 的 OpenCV 例程200篇】202. 查表快速替换(cv.LUT)
      • LUT 函数原型
      • LUT 究竟是什么?
      • 为什么要用 LUT?
      • LUT 用来干什么?
      • 例程 14.3:LUT 实现图像反转
      • 例程 14.4:LUT 实现颜色空间缩减
      • 例程 :LUT 实现分段线性灰度变换


【youcans 的 OpenCV 例程200篇】202. 查表快速替换(cv.LUT)

LUT 函数原型

函数 cv.LUT() 用来实现对图像中像素值的快速转换,称为查表函数(Look up table)。

cv.LUT(src, lut [, dst=None]) → dst

函数 cv.LUT() 根据查找表中的值,填充输出数组,由此实现对输入数组的数值转换。输出值与输入值的映射关系为:

dst(I)←lut[src(I)+d]d={0,src:cv_8U128,src:cv_8Sdst(I) \leftarrow lut[src(I) + d] \\ d = \begin{cases} 0,& src: cv\_8U \\ 128,& src: cv\_8S \end{cases} dst(I)lut[src(I)+d]d={0,128,src:cv_8Usrc:cv_8S

参数说明:

  • src:输入图像,nparray 数组,8位无符号/ 8位有符号整数格式
  • lut:查找表,256个元素
  • dst:输出图像,大小和通道数与 src 相同

注意事项:

  1. 输入图像为多通道彩色图像时,查找表 lut 可以是单通道,则查找表适用于输入图像的所有通道;查找表 lut 也可以与输入图像的通道数量相同,则查找表的各通道分别适用于输入图像的对应通道。
  2. 函数 cv.LUT() 本质上是查表替换,因此不仅可以用于灰度图像,也可以用于 RGB 彩色图像,还可以用于 HSV、YCrCb、LAB 等色彩空间的图像。

LUT 究竟是什么?

LUT 函数很简单,就是查表替换,用 lut 表中的值替换输入图像中对应的像素值。但还是需要详细解释这个查找表的内容和替换机制,否则很容易误解。

图像中每个像素的值称为像素值,灰度图像的像素值也称为灰度值。8 位灰度图像有 256 个灰度级,因此灰度值的取值范围是 [0,255]。

查找表 lut 是一个 256 个元素的一维数组,查找表中每个元素的值是新的像素值,用于替换像素值为该序号的像素的像素值。这句话很别扭,不好理解。

简单说,就是把输入图像中像素值为 0 的点用 lut[0] 替换,像素值为 i 的点用 lut[i] 替换,…,像素值为 255 的点用 lut[255] 替换。

因此,查找表就是一个简单的一对一或多对一的函数,定义了如何将原像素值转换为新的像素值。本质上查找表相当于一个字典,只是由于 key 对应于序号/地址可以被省略,因此只剩下一列 value。

输入图像为 8位有符号整数时,其像素值范围为 [-128,127],因此通过 d=128 进行调整。


为什么要用 LUT?

LUT 函数的核心在于查找表的映射关系。显然,这种映射关系是通过某种算法实现的,例如线性/非线性拉伸。

但是,既然已经有了映射关系,直接由输入图像的像素值计算输出值,不就得到输出图像了吗?为什么还要先由映射关系构造查找表,再用查找表进行像素替换?

是的,只要有了映射关系,就可以由输入图像的像素值计算输出值。但是,使用 LUT 查找表的速度远远快于对图像中逐个像素的映射变换。

对图像的每个像素,根据映射关系计算得到输出图像,要执行 height*width 次映射函数;而用 LUT 查找表,只要执行 256 次映射函数,再做 height*width 次替换操作。图像的像素点远远大于 256,因此相对于逐点计算,查找表用替换操作取代了大量的映射运算操作,极大地减小了计算量。

进一步地,查找表的替换操作是基于 numpy 的遍历查找和替换,而不是通过两重循环对逐个像素进行操作,进一步提高了运算速度。

LUT 用来干什么?

查找表在图像处理中主要用于像素点的映射运算,包括线性变换和非线性变换,处理速度极快。

查找表只能用于不涉及位置相关、邻域相关的操作,如:替换、取反、赋值、阈值、二值化、灰度变换、颜色缩减和直方图均衡化;不能用于位置相关、邻域相关的操作,如旋转、模糊。


例程 14.3:LUT 实现图像反转

图像反转(Invert)也称为反色变换,是像素颜色的逆转,将黑色像素点变白色,白色像素点变黑色,像素位置不变。

对于 8 位灰度图像,图像反转操作就是用 255 减掉像素值。

本例程以此比较循环操作与 LUT查表操作的运行速度。运行结果的差距是惊人的,虽然图像取反操作是最简单的运算,但用 for 循环实现的用时也竟然是 LUT 查表法的 1000倍。

    # 14.3 LUT 实现图像反转img = cv.imread("../images/imgGaia.tif")  # 读取彩色图像(BGR)h, w, ch = img.shape  # 图片的高度, 宽度 和通道数timeBegin = cv.getTickCount()imgInv = np.empty((w,h,ch), np.uint8)  # 创建空白数组for i in range(h):for j in range(w):for k in range(ch):imgInv[i][j][k] = 255 - img[i][j][k]timeEnd = cv.getTickCount()time = (timeEnd-timeBegin)/cv.getTickFrequency()print("图像反转(for 循环实现): {} s".format(round(time, 4)))timeBegin = cv.getTickCount()transTable = np.array([(255-i) for i in range(256)]).astype("uint8")invLUT = cv.LUT(img, transTable)timeEnd = cv.getTickCount()time = (timeEnd-timeBegin)/cv.getTickFrequency()print("图像反转(LUT 查表实现): {} s".format(round(time, 4)))plt.figure(figsize=(9, 6))plt.subplot(131), plt.title("img"), plt.axis('off')plt.imshow(cv.cvtColor(img, cv.COLOR_BGR2RGB))plt.subplot(132), plt.title("imgInv"), plt.axis('off')plt.imshow(cv.cvtColor(imgInv, cv.COLOR_BGR2RGB))plt.subplot(133), plt.title("invLUT"), plt.axis('off')plt.imshow(cv.cvtColor(invLUT, cv.COLOR_BGR2RGB))plt.tight_layout()plt.show()

运行结果:
图像反转(for 循环实现): 2.6839 s
图像反转(LUT 查表实现): 0.0027 s

在这里插入图片描述


例程 14.4:LUT 实现颜色空间缩减

颜色空间缩减是将图像的像素值除以某个参数,以得到较少的颜色种类,这是 LUT 的典型应用。

例如,8 位灰度图像对应着 255个灰度级,在某些印刷条件下可以将其缩减到 8个灰度级。这是一个简单的多对一的映射:
I[new]=(I[old]//32)∗32I[new] = (I[old]//32) * 32 I[new]=(I[old]//32)32
通常的做法是循环遍历所有像素点,逐一按该映射公式进行计算。

使用查表函数,只要预先对所有灰度级 0-255 建立对应表 table = [0,…0,32,…32,…,224,…224],用 LUT 查表替换就可以实现。

在本例程中,通过 for 循环实现的用时是 LUT 查表法的 4300倍。

另一方面,32级与 256级灰度的显示效果并没有显著的区别,而使用 8级灰度时则出现了明显的颜色偏差。

    # 14.4 颜色空间缩减img = cv.imread("../images/imgLena.tif")  # 读取彩色图像(BGR)gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)  # BGR -> Grayh, w = img.shape[:2]  # 图片的高度, 宽度timeBegin = cv.getTickCount()imgGray32 = np.empty((w,h), np.uint8)  # 创建空白数组for i in range(h):for j in range(w):imgGray32[i][j] = (gray[i][j]//8) * 8timeEnd = cv.getTickCount()time = (timeEnd-timeBegin)/cv.getTickFrequency()print("灰度级缩减(for 循环实现): {} s".format(round(time, 4)))timeBegin = cv.getTickCount()table32 = np.array([(i//8)*8 for i in range(256)]).astype("uint8")  # 32 levelsgray32 = cv.LUT(gray, table32)timeEnd = cv.getTickCount()time = (timeEnd-timeBegin)/cv.getTickFrequency()print("灰度级缩减(LUT 查表实现): {} s".format(round(time, 4)))table8 = np.array([(i//32)*32 for i in range(256)]).astype("uint8")  # 8 levelsgray8 = cv.LUT(gray, table8)plt.figure(figsize=(9, 6))plt.subplot(131), plt.axis('off'), plt.title("gray-256"), plt.imshow(gray, cmap='gray')plt.subplot(132), plt.axis('off'), plt.title("gray-32"), plt.imshow(gray32, cmap='gray')plt.subplot(133), plt.axis('off'), plt.title("gray-8"), plt.imshow(gray8, cmap='gray')plt.tight_layout()plt.show()
    # 14.4 颜色空间缩减img = cv.imread("../images/imgLena.tif")  # 读取彩色图像(BGR)gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)  # BGR -> Grayh, w = img.shape[:2]  # 图片的高度, 宽度timeBegin = cv.getTickCount()imgGray32 = np.empty((w,h), np.uint8)  # 创建空白数组for i in range(h):for j in range(w):imgGray32[i][j] = (gray[i][j]//8) * 8timeEnd = cv.getTickCount()time = (timeEnd-timeBegin)/cv.getTickFrequency()print("灰度级缩减(for 循环实现): {} s".format(round(time, 4)))timeBegin = cv.getTickCount()table32 = np.array([(i//8)*8 for i in range(256)]).astype("uint8")  # 32 levelsgray32 = cv.LUT(gray, table32)timeEnd = cv.getTickCount()time = (timeEnd-timeBegin)/cv.getTickFrequency()print("灰度级缩减(LUT 查表实现): {} s".format(round(time, 4)))table8 = np.array([(i//32)*32 for i in range(256)]).astype("uint8")  # 8 levelsgray8 = cv.LUT(gray, table8)plt.figure(figsize=(9, 6))plt.subplot(131), plt.axis('off'), plt.title("gray-256"), plt.imshow(gray, cmap='gray')plt.subplot(132), plt.axis('off'), plt.title("gray-32"), plt.imshow(gray32, cmap='gray')plt.subplot(133), plt.axis('off'), plt.title("gray-8"), plt.imshow(gray8, cmap='gray')plt.tight_layout()plt.show()

运行结果:
灰度级缩减(for 循环实现): 0.8667 s
灰度级缩减(LUT 查表实现): 0.0002 s

在这里插入图片描述


例程 :LUT 实现分段线性灰度变换

在例程 1.50, 1.51 中,分别给出了用 for 循环和用 LUT 实现的分段线性拉伸变换的灰度变换方法和例程。

详见:【OpenCV 例程200篇】40. 图像分段线性灰度变换

在这里插入图片描述


【本节完】

版权声明:
youcans@xupt 原创作品,转载必须标注原文链接:(https://blog.csdn.net/youcans/article/details/125278730)
Copyright 2022 youcans, XUPT
Crated:2022-6-14
欢迎关注 『youcans 的 OpenCV 例程 200 篇』 系列,持续更新中
欢迎关注 『youcans 的 OpenCV学习课』 系列,持续更新中

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/565429.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LaTex实战笔记 4-字体格式

LaTeX 中的字体有 5 种属性: 字体编码:正文字体编码,数学字体编码字体族:罗马字体,无衬线字体,打字机字体(等宽字体)等字体系列:粗细,宽度字体形状&#xff…

PHP在哪里执行_php文件放在哪运行

下载一个WampServer (集成环境)安装后,把要运行的放到安装目录下的www(我安装在D盘:D:\wamp\wamp\www),然后本机访问localhost/text.php(text.php是你要运行的php文件)。WampServer(推荐学习:PHP编程从入门到精通)WampServer是一款…

LaTex实战笔记 5-段落格式

2.1 换行和分段 通常 LATEX 会自动换行,也可以用\\ 或\newline 命令来强制换行。 开始一个段落,可以通过插入一个空行,也可以使用 \par 命令来强制分段。 连续两个换行符就是一个空行,可以将文字分段。但连续多个换行符&#xff…

【OpenCV 例程200篇】203. 伪彩色图像处理

OpenCV 例程200篇 总目录 201. 图像的颜色空间转换 202. 查表快速替换(cv.LUT) 203. 伪彩色图像处理 204. 图像的色彩风格滤镜 205. 调节色彩平衡/饱和度/明度 文章目录【youcans 的 OpenCV 例程200篇】203. 伪彩色图像处理什么是伪彩色图像?…

php post 丢失,php post大量数据时发现数据丢失问题解决方法,post数据丢失_PHP教程...

php post大量数据时发现数据丢失问题解决方法,post数据丢失解决办法:在php.ini中将max_input_vars调大改为5000就可以了原因追查:from的enctype”multipart/form-data”php版本5.6.6问题:部分POST数据接收不到追源代码发现是php中…

Jquery鼠标点击出现文字

点击鼠标左键出现文字效果。 原理解说 1.首先确定你是不是点的鼠标左键&#xff1b; 2.文字效果要出现在你鼠标点击的地方&#xff1b; 3.点击后文字出现一个由下往上的显示效果&#xff1b; 4.点击完成后固定时间内还得消失 效果演示 代码演示 <!DOCTYPE html> <h…

【OpenCV 例程200篇】204. 图像的色彩风格滤镜

OpenCV 例程200篇 总目录 201. 图像的颜色空间转换 202. 查表快速替换&#xff08;cv.LUT&#xff09; 203. 伪彩色图像处理 204. 图像的色彩风格滤镜 205. 调节色彩平衡/饱和度/明度 文章目录【youcans 的 OpenCV 例程200篇】204. 图像的色彩风格滤镜4. 图像的色彩风格滤镜4.1…

php文件夹重命名,PHP重命名和移动目录

PHP重命名目录使用PHP的rename()函数可以重命名目录。如果rename()函数执行成功&#xff0c;则返回true&#xff0c;否则返回false。复制代码PHP重命名目录示例-www.baike369.com$state rename(folder,folder2); // 将folder文件夹重命名为folder2文件夹if($state){echo 重命名…

【OpenCV 例程200篇】205. 调节色彩平衡/饱和度/明度

OpenCV 例程200篇 总目录 201. 图像的颜色空间转换 202. 查表快速替换&#xff08;cv.LUT&#xff09; 203. 伪彩色图像处理 204. 图像的色彩风格滤镜 205. 调节色彩平衡/饱和度/明度 文章目录【youcans 的 OpenCV 例程200篇】205. 调节色彩平衡/饱和度/明度4.3 自己调节色彩平…

自定义U盘图标

现在几乎人手一个U盘&#xff0c;作为很隐私的东西&#xff0c;U盘的使用场景却非常复杂&#xff0c;经常需要插入各种各样的设备… 那么如何让自己的U盘与众不同&#xff0c;在插入后给人留下深刻的印象呢&#xff1f; 今天就教给大家如何DIY自己的U盘图标。 1. 下载ico图标…

C站 APP 搜索工具使用体验与对比

文章目录0. 对比的 APP1. APP 首页布局2. 搜索页面的设计3. 关键词输入的过程4. 搜索结果的页面5. 搜索内容的展现6. 搜索结果的内容质量6.1 搜索内容质量评分6.2 对搜索内容评价的分析7. 小结0. 对比的 APP 垂直行业 APP&#xff1a;CSDN&#xff0c;稀土掘金&#xff0c;极客…

【OpenCV 例程200篇】206. Photoshop 色阶调整算法

OpenCV 例程200篇 总目录 201. 图像的颜色空间转换 202. 查表快速替换&#xff08;cv.LUT&#xff09; 203. 伪彩色图像处理 204. 图像的色彩风格滤镜 205. 调节色彩平衡/饱和度/明度 206. Photoshop 色阶调整算法 【youcans 的 OpenCV 例程200篇】206. Photoshop 色阶调整算法…

【OpenCV 例程200篇】207. Photoshop 色阶自动调整算法

OpenCV 例程200篇 总目录 201. 图像的颜色空间转换 202. 查表快速替换&#xff08;cv.LUT&#xff09; 203. 伪彩色图像处理 204. 图像的色彩风格滤镜 205. 调节色彩平衡/饱和度/明度 206. Photoshop 色阶调整算法 207. Photoshop 色阶自动调整算法 【youcans 的 OpenCV 例程20…

【OpenCV 例程200篇】208. Photoshop 对比度自动调整算法

OpenCV 例程200篇 总目录 【youcans 的 OpenCV 例程200篇】208. Photoshop 对比度自动调整算法 对比度是指图像中明暗区域最亮的白和最暗的黑之间不同亮度层级的测量&#xff0c;差异范围越大代表对比越大。 当对比率达到 120:1 就可以容易地显示生动、丰富的色彩&#xff0c;…

java设计模式 外观,精掌握Java设计模式之外观模式(10)

定义通俗地解释&#xff0c;当你打开灯的时候&#xff0c;你只需要嗯一下开关就好了&#xff0c;不需要关心灯泡亮起来的这个流程&#xff0c;同理&#xff0c;打开电脑的时候&#xff0c;嗯一下开机键就好了&#xff0c;也不需要关心电脑是先运行cpu还是内核之类的。这样能让用…

【OpenCV 例程200篇】209. HSV 颜色空间的彩色图像分割

OpenCV 例程200篇 总目录 【youcans 的 OpenCV 例程200篇】209. HSV 颜色空间的彩色图像分割 5.1 HSV 颜色空间的彩色图像分割 HSV 模型是针对用户观感的一种颜色模型。 HSV 颜色空间的各通道分别表示色调&#xff08;Hue&#xff09;、饱和度&#xff08;Saturation&#x…

【OpenCV 例程200篇】210. 绘制直线也会有这么多坑?

OpenCV 例程200篇 总目录 【youcans 的 OpenCV 例程200篇】210. 绘制直线也会有这么多坑&#xff1f; 我不是标题党。 绘制直线当然是最简单的绘图&#xff0c;能有什么坑呢&#xff1f;不信的同学可以直接跳到注意事项。就算你是 OpenCV 大神&#xff0c;如果这 10 个问题点…

PHP配置微信测试号,关于微信开发模式和测试账号

自己刚开始学习微信开发&#xff0c;请帮忙解惑1.微信公众号使用模式分为编辑模式和开发者模式 &#xff0c;两个是互斥的&#xff0c;也就是开启一个另一个就不能用现在我的理解 上边两个模式是由服务器的开启停用区分的&#xff0c;启用即为开发者模式另外&#xff0c;我想知…

【OpenCV 例程200篇】211. 绘制垂直矩形

OpenCV 例程200篇 总目录 【youcans 的 OpenCV 例程200篇】211. 绘制垂直矩形 7.1 绘图函数基本参数 OpenCV提供了绘图功能&#xff0c;可以在图像上绘制直线、矩形、圆、椭圆等各种几何图形。 函数 cv.line()、cv.rectangle()、cv.circle()、cv.polylines() 等分别用来在图…

php自动采集入库,Phpcms v9自动采集入库自动发布组件

Phpcms v9自动采集入库自动发布组件是思优CMSYOU技术团队在实际SEO运维运用总结研究出的自动采集入库自动发布文章的组件&#xff0c;实现自动通过Phpcms后台采集模块的采集规则采集文章、并自动入库到对应栏目、入口后自动更新生成内容页自身HTML、栏目页HTML、首页HTML&#…