JavaScript图像处理(5) - 曲线操作(Curve Manipulation)
2013-11-17 03:53
363 查看
直方图均衡作为一个自动的方法虽然可以在大多数情况下获得不错的效果,但是很多时候也受限于其单一的功能而无法满足多样化的图像处理需求。尤其是在图像的艺术处理方面,直方图均衡往往并不能达到期望的效果——有时候我们需要增强图像中的高光或者是明亮的背景来突出主体,有时候又需要降低图像的整体对比度而提高某些区域的对比度来增强图像的视觉冲击力。在这些情况下,我们都需要能够直接操作图像的直方图,并且在一个不断尝试的过程中来逐步获得满意的效果。
操纵直方图最常用的方法之一就是曲线工具。曲线工具提供了一个通过修改像素值映射曲线来调整直方图的方法。对于RGB图像来说,像素值映射曲线是定义在[0, 255]之间的一个取值在[0,255]之间的函数:
I_new = f( I ) , 0 <= I <= 255
这个函数将每一个输入像素值映射到另外一个像素值上,从而达到直接修改图像的目的。这个曲线可以是应用于修改图像的亮度,也可以修改单个颜色通道。当用于调整图像的亮度时,它相当于引入了一个非线性的函数来对图像的亮度对比度进行调整,因为对于不同亮度的像素,进行调整时所用的参数是不一样的。相比起来,之前提到过的修改图像亮度对比度的方法(JavaScript图像处理(2)
- 亮度对比度调整)采用的则是线性调整的方法,因为图像中每一个像素采用的参数都是一样的。直方图均衡(JavaScript图像处理(3) - 直方图均衡,JavaScript图像处理(4)
- 自适应直方图均衡)也是一种非线性调整方法,而且是自动根据图像的统计特性进行调整的方法,其所采用的映射函数来自于图像像素亮度值的分布曲线。
具体来说,在利用曲线工具调整图像时,可以先根据曲线生成一个映射函数,将这个函数保存在一个查找表(Look-up Table)里面,调整图像时直接根据查找表来进行像素值替换或者是修改就可以了。下面的代码就是一个简单的实现:
下面是效果图。原图如下:
调整亮度后:
单独调整红色通道,注意蓝色和绿色通道的直方图没有改变:
单独调整绿色通道:
调整蓝色通道:
另一个例子:
原图
调整后:
操纵直方图最常用的方法之一就是曲线工具。曲线工具提供了一个通过修改像素值映射曲线来调整直方图的方法。对于RGB图像来说,像素值映射曲线是定义在[0, 255]之间的一个取值在[0,255]之间的函数:
I_new = f( I ) , 0 <= I <= 255
这个函数将每一个输入像素值映射到另外一个像素值上,从而达到直接修改图像的目的。这个曲线可以是应用于修改图像的亮度,也可以修改单个颜色通道。当用于调整图像的亮度时,它相当于引入了一个非线性的函数来对图像的亮度对比度进行调整,因为对于不同亮度的像素,进行调整时所用的参数是不一样的。相比起来,之前提到过的修改图像亮度对比度的方法(JavaScript图像处理(2)
- 亮度对比度调整)采用的则是线性调整的方法,因为图像中每一个像素采用的参数都是一样的。直方图均衡(JavaScript图像处理(3) - 直方图均衡,JavaScript图像处理(4)
- 自适应直方图均衡)也是一种非线性调整方法,而且是自动根据图像的统计特性进行调整的方法,其所采用的映射函数来自于图像像素亮度值的分布曲线。
具体来说,在利用曲线工具调整图像时,可以先根据曲线生成一个映射函数,将这个函数保存在一个查找表(Look-up Table)里面,调整图像时直接根据查找表来进行像素值替换或者是修改就可以了。下面的代码就是一个简单的实现:
// lut is the look up table defined by the input curve filters.curve = function(src, lut, channel) { switch( channel ) { case 'red': { return src.map(function(c0) { var c = new Color(lut[c0.r], c0.g, c0.b, c0.a); return c.round().clamp(); }); } case 'green': { return src.map(function(c0) { var c = new Color(c0.r, lut[c0.g], c0.b, c0.a); return c.round().clamp(); }); } case 'blue': { return src.map(function(c0) { var c = new Color(c0.r, c0.g, lut[c0.b], c0.a); return c.round().clamp(); }); } case 'brightness': default: { return src.map(function(c0) { var lev = Math.round((c0.r * 299 + c0.g * 587 + c0.b * 114) / 1000); var bias = 1e-6; // prevent divide by zero var ratio = lut[lev]/(lev + bias); var c = c0.mulc(ratio); return c.round().clamp(); }); } } };
下面是效果图。原图如下:
调整亮度后:
单独调整红色通道,注意蓝色和绿色通道的直方图没有改变:
单独调整绿色通道:
调整蓝色通道:
另一个例子:
原图
调整后:
相关文章推荐
- 【python图像处理】直线和曲线的拟合与绘制(curve_fit()详解)
- Javascript图像处理思路及实现代码
- PHP----图像处理类,可以完成对各种类型的图像进行缩放、加图片水印和剪裁的操作
- Matlab彩色图像处理基本操作
- OpenCV(4)-图像掩码操作(卷积)--平滑处理
- 一道图像处理的笔试题,算子操作图像后的输出图像
- HTML5/JavaScript 图像自动Gamma校正 — 打造图像处理类库第一步
- Python-Image基本的图像处理操作
- JavaScript图像处理(1) - 获取图像(Image Acquisition)
- 数字图像处理中的数学操作
- javascript图像处理框架
- VC环境下使用HALCON图像处理库的配置与基本操作
- 【VS开发】【图像处理】自动白平衡(AWB)算法---色温曲线
- BGRABitmap图像操作3:用鼠标在窗体画断续的曲线
- matla图像处理基本操作
- 帮助你操作数字和处理数字格式的javascript类库 - Numeral.js
- 帮助你操作数字和处理数字格式的javascript类库 - Numeral.js
- opencv图像处理基本操作
- [译]File API之JavaScript文件操作(3)- 进度事件和错误处理
- 基于PI+QT实现OpenCV图像处理操作(基本环境搭建)