如果你的照片看上去灰蒙蒙的,缺少生机,那么hsv拉伸也许可以帮你的忙。hsv拉伸是一种可以提高图像鲜艳程度的图像增强方法,它能够让图像的颜色更加鲜活、艳丽,而且它的处理结果看上去很自然,比如源图中较暗的红色会变的鲜红,而不会像拉伸对比度那样把图像弄的难看失真,暗红色变的发紫发黑。
来个例子:
其基本原理如下:
1、 将源图像的(rgb)颜色空间映射到(hsv ),什么是HSV?
2、 对图像的s和v通道进行一次min-max normalize,h通道不变
所谓min-max normalize是指: dst(x,y) = [src(x,y) – min(src(x,y)) ] / [ (max(src(x,y)) – min(src(x,y)) ]
hsv拉伸处理后,图像不失真的关键因素就是h通道不变,即图像的色相与源图一致
3、 将新的(h s v)映射回(rgb)
下面是gimp给出的源码(只贴出关键部分)
typedef struct { //用来存放最大最小值的结构体 double shi; double slo; double vhi; double vlo; } AutostretchData; static void //找到最大最小值 find_max (guchar *src, gint bpp, AutostretchData *data) { double h, s, v; gimp_rgb_to_hsv4(src, &h, &s, &v); if (s > data->shi) data->shi = s; if (s < data->slo) data->slo = s; if (v > data->vhi) data->vhi = v; if (v < data->vlo) data->vlo = v; } static void //关键函数! autostretch_hsv_func (guchar *src, guchar *dest, gint bpp, AutostretchData *data) { double h, s, v; gimp_rgb_to_hsv4(src, &h, &s, &v); if (data->shi != data->slo) s = (s - data->slo) / (data->shi - data->slo); //关键语句 if (data->vhi != data->vlo) v = (v - data->vlo) / (data->vhi - data->vlo); //关键语句 gimp_hsv_to_rgb4(dest, h, s, v); if (bpp == 4) dest[3] = src[3]; } static void indexed_autostretch_hsv (gint32 image_ID) { guchar *cmap; AutostretchData data = {0.0, 1.0, 0.0, 1.0}; gint ncols, i; cmap = gimp_image_get_colormap (image_ID, &ncols); if (!cmap) { g_message (_("autostretch_hsv: cmap was NULL! Quitting...\n")); gimp_quit (); } for (i = 0; i < ncols; i++) { find_max (&cmap[i * 3], 3, &data); } for (i = 0; i < ncols; i++) { autostretch_hsv_func (&cmap[i * 3], &cmap[i * 3], 3, &data); } gimp_image_set_colormap (image_ID, cmap, ncols); }
这个教程的思路有些意思,但上面代码貌似是C的,如果有时间的话勇哥尝试一下用halcon或者EmguCV来实现这个思路。
2018/11/23追加:
今天有点时间,按照上面的思路用halcon实现了这种HSV拉伸效果。
原理同上文的介绍。下面放上代码。
read_image (Image201811221542879246434751, 'C:/Users/Administrator/Desktop/201811221542879246434751.png') decompose3(Image201811221542879246434751, Image1, Image2, Image3) trans_from_rgb(Image1, Image2, Image3, h, s, v, 'hsv') get_image_size(h, Width, Height) gen_rectangle1(Rec1, 0, 0,Height,Width) scale_image_max(s, s1) scale_image_max(v,v1) trans_to_rgb(h, s1, v1, ImageRed, ImageGreen, ImageBlue, 'hsv') compose3(ImageRed, ImageGreen, ImageBlue, MultiChannelImage)
结果如下:
halcon的图像变量如下, 以方便各位参看代码:
对于颜色通道不理解的童鞋,下面摘抄一段相关的解释:
三通道图像就是彩色图像,我们之前黑白相机或黑白电视机都是彩用的灰阶图像,即单通道图像,一般是2的8次方个灰阶,即256个灰阶。彩色图像采用RGB,红绿蓝三个通道来合成彩色图像。所以称之为三通道图像。或称为8位通道色。
我们可以把RGB三原色想像成油盐酱醋一样,任何美味都是通过这些调味品做出来的。任何颜色也是RGB三原色按一定的比例显示出来的。三个通道就像三个控制器,去调整三个颜色的比重。
Halcon有生成图像和合成图像的算子,例程如下。
gen_image_const(Image,'byte',512,512)//生成一个图像,用byte格式 gen_image_proto(Image,ImageCleared1,255)//生成第一通道图像 gen_image_proto(Image,ImageCleared2,0)//生成第二通道图像 gen_image_proto(Image,ImageCleared3,0)//生成第三通道图像 compose3(ImageCleared1,ImageCleared2,ImageCleared3,MultiImage)//合成三个通道图像。
我们分别创建三个通道的图像,其中R通道的灰阶为255,合成后,我们发现一张红色的图片。如果分别去更改三个通道的灰阶,我们可以看到不同颜色的图片。
需要注意的是,三个通道的图像可以来源于不同大小的图像,新合成后的图像大小与合成前可能会不一致。

