侧边栏壁纸
  • 累计撰写 416 篇文章
  • 累计创建 65 个标签
  • 累计收到 145 条评论

目 录CONTENT

文章目录

OpenCV HSV颜色格式

Z同学
2023-06-14 / 0 评论 / 4 点赞 / 520 阅读 / 1,322 字
温馨提示:
本文最后更新于 2023-06-14,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

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-255
  • Imgproc.COLOR_RGB2HSV: 转换后的HSV数值中,H的值范围0~180, S的范围:0-255,V的范围:0-255

这个两种的区别就在于H的值的取值范围。

H(Hue)色调:从红色开始按照逆时针方向计算。红色为0。

S(Saturation)饱和度:简单理解就是颜色的鲜艳程度,也就是颜色与白色的混合程度。范围0到255,值越大颜色纯,值越小越颜色越淡。

V(Value)明度:指颜色的明暗程度。取值范围从0到255,明暗程度也就是从黑到白。比如暗红色和大红色。一个黑一个亮。就可以通过明度值进行调整。

当我们理解这个关系之后,就可以结合这个比较常见的图进行理解了。

image-1686727951913

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=sV/100*255=v

我们使用openCV HSV 值:[10,255,255] 转换为标准的HSV的结果就是:

H = 10*2=20
S = 255/255*100=100
V = 255/255*100=100

我们手动的进行一个转换就可以了。

4

评论区