1. 前言
在使用OpenCV进行颜色识别和追踪时,我们通常会将图片格式转为HSV格式。在转换为HSV格式过程中,吃到过一些教训。
在这里总结一下自己的教训。
同时,帮助我们加深理解一下HSV颜色格式。
2. HSV
使用OpenCV将图片的颜色转换为HSV格式,可以方便我们进行颜色追踪。而转换方法很简单。示例代码如下:
Mat dst = new Mat();
Imgproc.cvtColor(rgb, dst, Imgproc.COLOR_RGB2HSV_FULL); //将颜色转为HSV
在上面的代码中,rgb是我们将Android相机采集到的图片转换为Mat
后的结果。
如何转换可以参考https://zinyan.com/?p=345 这里就不介绍了。
当我们进行转换为HSV格式的时候,通常有两种选择:
Imgproc.COLOR_RGB2HSV_FULL
: 转换后的HSV数值中,H的值范围0~255, S的范围:0-255,V的范围:0-255Imgproc.COLOR_RGB2HSV
: 转换后的HSV数值中,H的值范围0~180, S的范围:0-255,V的范围:0-255
这个两种的区别就在于H的值的取值范围。
H(Hue)色调:从红色开始按照逆时针方向计算。红色为0。
S(Saturation)饱和度:简单理解就是颜色的鲜艳程度,也就是颜色与白色的混合程度。范围0到255,值越大颜色纯,值越小越颜色越淡。
V(Value)明度:指颜色的明暗程度。取值范围从0到255,明暗程度也就是从黑到白。比如暗红色和大红色。一个黑一个亮。就可以通过明度值进行调整。
当我们理解这个关系之后,就可以结合这个比较常见的图进行理解了。
PS:在网上找到个各种在线HSV色值,都是基于H:0~360,S:0-100,V:0-100。进行配置的。而在OpenCV中取值范围是不一样的。 openCV在取值转换中进行了变换。具体的转换可以通过下面的颜色计算进行了解。
我们经常得到的一些OpenCV 的HSV色卡表如下:
黑 | 灰 | 白 | 红 | 橙 | 黄 | 绿 | 青 | 蓝 | 紫 | ||
hmin | 0 | 0 | 0 | 0 | 156 | 11 | 26 | 35 | 78 | 100 | 125 |
hmax | 180 | 180 | 180 | 10 | 180 | 25 | 34 | 77 | 99 | 124 | 155 |
smin | 0 | 0 | 0 | 43 | 43 | 43 | 43 | 43 | 43 | 43 | |
smax | 255 | 43 | 30 | 255 | 255 | 255 | 255 | 255 | 255 | 255 | |
vmin | 0 | 221 | 221 | 46 | 46 | 46 | 46 | 46 | 46 | 46 | |
vmax | 46 | 220 | 255 | 255 | 255 | 255 | 255 | 255 | 255 | 255 |
我们如果想使用该颜色卡进行提取图片中的红色区域:
Mat dst = new Mat();
Imgproc.cvtColor(rgba, dst, Imgproc.COLOR_RGB2HSV_FULL); //将颜色转为HSV
//执行2值化
Mat mask1 = new Mat(dst.rows(), dst.cols(), CvType.CV_8UC1);
//过滤红色
Core.inRange(dst, new Scalar(0,43,46), new Scalar(10,255,255), mask1);
在上面的实例中,最终得到的mask1对就是一个单通道的从dst原图中得到的红色区域的对象。
我们如果直接显示mask的会得到一个黑白的图片。我们可以直接在这个图上获取轮廓等处理。
3. Scalar
在OpenCV中我们针对颜色进行配置的时候,不是使用Color对象。都是通过Scalar对象进行处理的。
而该对象存储的其实就是一个double val[]数组。
public Scalar(double v0, double v1, double v2, double v3) {
val = new double[] { v0, v1, v2, v3 };
}
public Scalar(double v0, double v1, double v2) {
val = new double[] { v0, v1, v2, 0 };
}
我们在使用Scalar进行传入参数时,参数的意义是根据我们的图片类型来决定的。
例如:
有一个Mat对象,是RGBA格式的。那么我们在针对该Mat进行颜色处理时传入的Scalar变量。传入的v0=R,v1=G,v2=B,v3=A。
如果Mat时HSV类型的。那么v0=H,v1=S,v2=V。
所以,当我们使用颜色的时候,根据自己的要处理的Mat对象的类型来传值。
4. 颜色计算
我们如果通过搜索会得到HSV颜色值得取值范围是:
H:0°~306° :是一个角度值。
S:0%~100% :是一个比例值。
V:0%~100%:也是一个比例值。
而各种在线调色板等等工具,也是按照上面的范围配置HSV。而我们在OpenCV中使用的HSV范围是不一样的。
所以我们需要进行转换。
HSV_FULL:中的H范围是0~255: 计算转换方式为: H*255/360=h
HSV :中的H的范围是0~180: 计算转换方式为:H/2=h
而两种格式的S和V的范围都是0~255.所以计算转换方式为:S/100*255=s
和 V/100*255=v
我们使用openCV HSV 值:[10,255,255] 转换为标准的HSV的结果就是:
H = 10*2=20
S = 255/255*100=100
V = 255/255*100=100
我们手动的进行一个转换就可以了。
评论区