文章目录

  • opencv色域转换
  • 色域转换的本质
  • 捕获指定区域(采用获取指定范围的掩码实现捕获)
  • cv.inRange()函数获取指定数据的范围——也就是掩饰掉我们需要的数据之外的数据
  • 图像与cv.bitwise_and(),实现掩码与原图像融合
  • 通过色域选定实现对象追踪
  • 实现思路
  • 代码实例(实现蓝色追踪)
  • 效果

opencv色域转换

将会使用cv.cvtColor()函数实现图像色域的转换,它的参数如下

  • 第一个参数为输入图像
  • 第二个参数为转换色域的选择——一般在色域追踪中,可能将opencv默认的BGR转换位HSV会查找更简单一些。(虽然opencv默认色域是RGB;但是,实质上它是采用的BGR存储的,所以我们在处理数据时,按照BGR来处理就好)
  • 第三个参数为色域通道数设置——默认为0,意味着原图形默认的通道数

至于输出图像,采用返回值的方式来实现就好。

img = cv.imread('1.png', 1)
hsv = cv.cvtColor(img , cv.COLOR_BGR2HSV)   # COLOR_BGR2HSV是指将图像色域转换为HSV

色域转换的本质

其本质我认为主要是对数据的等权重数据转换吧——就比如,我们常常举例说明一样,都是为了问题的简便。

捕获指定区域(采用获取指定范围的掩码实现捕获)

cv.inRange()函数获取指定数据的范围——也就是掩饰掉我们需要的数据之外的数据

主要参数:

  • 第一个参数:输入数组(需要提取指定范围的图像数组)
  • 第二个参数:查找满足条件的下限值
  • 第三个参数:查找满足条件的上限值——由二、三参数可以得到我们搜索的数据范围

至于输出掩码——我们采用就收返回值的方式获取。
对于色域判断,我们通常是把某个色域的上下限取出来,然后放入inRange中作为判断条件。然后得到的掩码——就是只包含这个区域的图像信息的数组。

lower_blue = np.array([110, 50, 50])
upper_blue = np.array([130, 255, 255])  # 设置色域范围
mask = cv.inRange(hsv, lower_blue, upper_blue)  # 返回一个满足指定色域外的其它区域值置0的掩码(图像)

官方函数功能的说明:(我就不多说了,就提两句)
该函数在一维时,就直接将在lowerb和upperb的数据保留,其它舍去——置零
——可类推多维度,见下面文档
补充: 如果是图像色域范围的筛选,那么满足为就为阈值(全1位),否则就为0

The function checks the range as follows:

For every element of a single-channel input array:   % 0 表示下标,对应维度
dst(I) = lowerb(I)0≤src(I)0≤upperb(I)0  

For two-channel arrays:
dst(I) = lowerb(I)0≤src(I)0≤upperb(I)0∧lowerb(I)1≤src(I)1≤upperb(I)1
and so forth.
That is, dst (I) is set to 255 (all 1 -bits) if src (I) is within the specified 1D, 2D, 3D, ... box and 0 otherwise.

通过以上步骤,已经可以操作色域的转换,实现问题的一些简化,又可以通过,对满足指定色域的图像范围的读取/获取。那么接着我们就应该让满足条件的图像区域呈现我们实际的图像了——这里就要用到图像的与,实现图像的混合了。

图像与cv.bitwise_and(),实现掩码与原图像融合

主要参数:

  • 第一参数:输入图像1(输入数组1/标量)
  • 第二参数:输入图像2(另一个数组/标量)
  • 第三参数:输出数组——通常按返回值获取输出数组
  • 第四参数:与操作的掩码输入——8位单通道数组,用于指定要更改的输出数组的元素[对应维度]。

实例:(简单理解可以是:输入图像1与输入图像2的按位与,而当mask不等于0时,就是将mask添加到图像混合中,作为与的元素)

res = cv.bitwise_and(frame, frame, mask=mask)  # 用图像与操作,实现掩码原图像混合

上面采用原图混合(本来是无任何变化的),由于掺入mask实现了指定位置/范围的与/即图像修改。
【除掩码外的另外两个传入参数是必须要有的,如果只是对掩码处理,不妨就传入一个相同的图像~】

通过色域选定实现对象追踪

实现思路

  1. 进行色域转换——直接处理BGR与处理HSV,我们选择后者——因为后者更容易表现颜色,换句话说更好被处理。
  2. 获取指定色域的范围——list类型——用numpy创建数组
  3. 使用inRange获取指定区域的掩码
  4. 把掩码掺入到实际的图像中——这里采用图像混合中常用的bitwise_and

代码实例(实现蓝色追踪)

import cv2 as cv
import numpy as np


if __name__ == "__main__":
    cap = cv.VideoCapture(0)  # 默认摄像设备

    while True:
        _, frame = cap.read()  # 读取设备帧图像——frame为图像

        hsv = cv.cvtColor(frame, cv.COLOR_BGR2HSV)  # 转换色域——因为HSV更容易在图像中查找色彩区域
        # 也可通过cvtColor获取不同色域下的颜色值——比如,传入一个BGR(对应cv.COLOR_BGR2HSV)的色值,然后得到HSV下的该色色值
        lower_blue = np.array([110, 50, 50])
        upper_blue = np.array([130, 255, 255])  # 设置需要的色域范围

        mask = cv.inRange(hsv, lower_blue, upper_blue)  # 返回一个满足指定色域外的其它区域值置0的掩码
        res = cv.bitwise_and(frame, frame, mask=mask)  # 用图像与操作,实现掩码与原图像的混合

        cv.imshow('imag', frame)  # 显示原图像
        cv.imshow('mask', mask)  # 显示掩码图像
        cv.imshow('res', res)  # 显示混合图像——也就是追踪图像
        if cv.waitKey(5) & 0xFF == 27:
            break
    cv.destroyAllWindows()

效果

说明:图中噪点写成噪声了,很抱歉,请谅解。

opencv求图像rgb均值 opencv提取rgb_opencv求图像rgb均值


至于如何除噪声,我会在后边单独整理后发出,但是可以有很多滤波方式来消噪——消除噪点。