附录3-opencv图像指定位置颜色识别

基于此篇文章做得简单的修改 OpenCV---颜色识别_opencv 颜色识别-CSDN博客

修改内容主要有两点

  1. 之前文章中只测量中心点一点的颜色,该文章会测量更大区域的颜色(也就是对区域内的颜色取均值)
  2. 之前文章文章只对 红黄绿蓝紫粉 六种颜色进行识别,该文章会对 赤橙黄绿青蓝紫粉黑白 十种颜色进行识别(不是特别精准)

目录

[1 hsv的基本了解](#1 hsv的基本了解)

[1.1 色调 H](#1.1 色调 H)

[1.2 饱和度 S](#1.2 饱和度 S)

[1.3 值 V](#1.3 值 V)

[2 hsv在opencv中的数字化](#2 hsv在opencv中的数字化)

[3 识别单张图像](#3 识别单张图像)

[4 摄像头识别](#4 摄像头识别)


1 hsv的基本了解

HSV分为三个参数。

  • H的意思是hue,翻译成中文是色调
  • S的意思是saturation,翻译成中文是饱和度
  • V的意思是value,翻译成中文是值

1.1 色调 H

色调 是分辨 赤橙黄绿青蓝紫 这些的。在我们的调色盘上来看可以理解为横坐标,比如我现在左上角的色调是0

右上角的色调是359

对于中间来讲不同的色调就是不同的颜色

1.2 饱和度 S

饱和度可以理解为 明亮度。在我们的调色盘来看可以理解为纵坐标。比如我左上角的饱和度是100

左下角的饱和度是0

越往下(饱和度越低)你可以理解为这个颜色就越浅

1.3 值 V

值可以理解为黑暗度。在调色盘上可以我们最右侧的这个条。当前我们的值是100

拉到最下,值就会变成0

可以理解为值越小,越暗。并且值的优先级高于饱和度

2 hsv在opencv中的数字化

opencv有opencv自己的数字化规则,注意千万不要用画图的这个值。在美术中画图的这三个值或许是正确的,但在opencv中不是

我们写这样一个代码,作用是把hsv的值转变为RGB值

python 复制代码
import cv2
import numpy as np

def nothing(x):
    pass

cv2.namedWindow("frame")
cv2.createTrackbar("H","frame",0,179,nothing)
cv2.createTrackbar("S","frame",0,255,nothing)
cv2.createTrackbar("V","frame",0,255,nothing)

img_hsv = np.zeros((250,500,3),np.uint8)

while True:
    h = cv2.getTrackbarPos("H","frame")
    s = cv2.getTrackbarPos("S","frame")
    v = cv2.getTrackbarPos("V","frame")

    img_hsv[:] = (h,s,v)
    img_bgr = cv2.cvtColor(img_hsv,cv2.COLOR_HSV2BGR)

    cv2.imshow("frame",img_bgr)
    key = cv2.waitKey(1)
    if key == 27:
        break

cv2.destroyAllWindows()

为了更好地找到对应关系,我们搞了个滚动条。我们发现0是红色

179的时候也是红色

  • 这里的179是测出来的,你可以将H的最大值设置为255,你发现179之后就是橘黄色了

那么我们现在其实可以和画图中的H值找到联系了,画图中H的下限是0,上限是359,一共360个值。opencv中的下限是0,上限是179,一共是180个值。那么我们合理推断一下,opencv的H值是画图中H值的一般。我们测试一下,果然是这样

S就是255对100,0对0

V也是255对100,0对0

综上所述opencv中的H值是画图中的 1/2

S值是画图中的 2.55 倍,V值是画图中的 2.55倍

颜色 画图中的H值 opencv中的H值
红色 0-15 and 325-359 0-8 and 163-179
橙色 15-50 8-25
黄色 50-70 25-35
绿色 70-155 35-78
青色 155-185 78-93
蓝色 185-255 93-128
紫色 255-300 128-150
粉色 300-325 150-163

需要注意的是我们这种判定的方式是有局限性的,因为我们只使用H值进行判断。

我们举一个反例,当H为120,S,V都为255时,我们看到这是一个明显的蓝色

当我们减低S值后,发现这个颜色就很像紫色了

如果你想要更加精准的判断,你可以把HSV的所有情况都搞一个区间,那样就比较麻烦,我目前的案例只对特征明显的颜色进行识别

如果判断黑色和白色,我们就不能通过H值进行判断了,我们简单弄一下,比如我们认为V值在20以下,就算黑色了

当然对于不同的H、S值也是有所不同,比如下面的颜色就更像是墨绿色

判断白色,比如我们认为S值在20以下就是白色了

3 识别单张图像

width_margin的意思是宽度边缘,height_margin的意思是高度边缘,如果乘0就代表没有边缘,我们检测的绿色框子区域内的颜色

python 复制代码
import cv2

frame = cv2.imread('white.png')
width = frame.shape[1]
height = frame.shape[0]

width_margin = int(width * 0)
height_margin = int(height * 0)

point_list = []
for i in range(width_margin,width-width_margin):
    for j in range(height_margin,height-height_margin):
        point_list.append((i,j))

# print(len(point_list))

imghsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

average_hue_value = 0
average_saturation_value = 0
average_value_value = 0
for i in point_list:
    average_hue_value = average_hue_value + imghsv[i[1],i[0]][0]
    average_saturation_value = average_saturation_value + imghsv[i[1],i[0]][1]
    average_value_value = average_value_value + imghsv[i[1],i[0]][2]

# print(average_hue_value)
average_hue_value = int(average_hue_value/len(point_list))
average_saturation_value = int(average_saturation_value/len(point_list))
average_value_value = int(average_value_value/len(point_list))

print(average_hue_value)
print(average_saturation_value)
print(average_value_value)

color = ''
if average_value_value < 20:
    color = 'black'
elif average_saturation_value < 20:
    color = 'white'
elif average_hue_value <= 8 or average_hue_value > 163:
    color = 'red'
elif average_hue_value > 8 and average_hue_value <= 25:
    color = 'orange'
elif average_hue_value > 25 and average_hue_value <= 35:
    color = 'yellow'
elif average_hue_value > 35 and average_hue_value <= 78:
    color = 'green'
elif average_hue_value > 78 and average_hue_value <= 93:
    color = 'cyan'
elif average_hue_value > 93 and average_hue_value <= 128:
    color = 'blue'
elif average_hue_value > 128 and average_hue_value <= 150:
    color = 'purple'
elif average_hue_value > 150 and average_hue_value <= 163:
    color = 'pink'

cv2.rectangle(frame, (width_margin, height_margin), (width-width_margin, height-height_margin), (0, 255, 0), 3)
cv2.putText(frame,color,(20,20),cv2.FONT_HERSHEY_SIMPLEX,1,(0,255,0),2)

cv2.imshow("capture", frame)
cv2.waitKey(0)
cv2.destroyAllWindows()

静态图像相对校准(当然需要是人类能识别出来的颜色,随便找一张没有主体颜色的图给人类,人类也是分不清的)

4 摄像头识别

对于摄像头来讲就没有这么准了,需要根据自己的摄像头对判断的数值区间再进行一些调整

python 复制代码
import cv2
import numpy as np

cap = cv2.VideoCapture(0)

width = 640
height = 480

width_margin = int(width * 0.4)
height_margin = int(height * 0.4)

point_list = []
for i in range(width_margin,width-width_margin):
    for j in range(height_margin,height-width_margin):
        point_list.append((i,j))

# print(point_list)
# print(len(point_list))

while True:
    ret, frame = cap.read()

    if ret:
        frame = cv2.resize(frame, (width, height))
        imghsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

        average_hue_value = 0
        average_saturation_value = 0
        average_value_value = 0
        for i in point_list:
            average_hue_value = average_hue_value + imghsv[i[1], i[0]][0]
            average_saturation_value = average_saturation_value + imghsv[i[1], i[0]][1]
            average_value_value = average_value_value + imghsv[i[1], i[0]][2]

        # print(average_hue_value)
        average_hue_value = int(average_hue_value / len(point_list))
        average_saturation_value = int(average_saturation_value / len(point_list))
        average_value_value = int(average_value_value / len(point_list))

        print('average_hue_value',average_hue_value)
        print('average_saturation_value',average_saturation_value)
        print('average_value_value',average_value_value)

        color = ''
        if average_value_value < 20:
            color = 'black'
        elif average_saturation_value < 20:
            color = 'white'
        elif average_hue_value <= 8 or average_hue_value > 163:
            color = 'red'
        elif average_hue_value > 8 and average_hue_value <= 25:
            color = 'orange'
        elif average_hue_value > 25 and average_hue_value <= 35:
            color = 'yellow'
        elif average_hue_value > 35 and average_hue_value <= 78:
            color = 'green'
        elif average_hue_value > 78 and average_hue_value <= 93:
            color = 'cyan'
        elif average_hue_value > 93 and average_hue_value <= 128:
            color = 'blue'
        elif average_hue_value > 128 and average_hue_value <= 150:
            color = 'purple'
        elif average_hue_value > 150 and average_hue_value <= 163:
            color = 'pink'

        cv2.rectangle(frame, (width_margin, height_margin), (width-width_margin, height-height_margin), (0, 255, 0), 3)
        cv2.putText(frame,color,(20,20),cv2.FONT_HERSHEY_SIMPLEX,1,(0,255,0),2)
        cv2.imshow("capture", frame)

    k = cv2.waitKey(1)
    if k == ord(' '):
        break
cap.release()
cv2.destroyAllWindows()
相关推荐
西猫雷婶3 小时前
python学opencv|读取图像(二十五)使用cv2.putText()绘制文字进阶-垂直镜像文字
开发语言·python·opencv
西猫雷婶4 小时前
python学opencv|读取图像(二十四)使用cv2.putText()绘制文字进阶-倾斜文字
开发语言·python·opencv
小李学AI4 小时前
基于YOLOv8的道路缺陷检测系统
人工智能·深度学习·神经网络·yolo·目标检测·机器学习·计算机视觉
youcans_5 小时前
【YOLO 项目实战】(12)红外/可见光多模态目标检测
人工智能·yolo·目标检测·计算机视觉·多模态
深蓝学院5 小时前
Visual CoT:解锁视觉链式思维推理的潜能
人工智能·计算机视觉·目标跟踪
AI追随者5 小时前
超越YOLO11!DEIM:先进的实时DETR目标检测
人工智能·深度学习·算法·目标检测·计算机视觉
卧式纯绿5 小时前
自动驾驶3D目标检测综述(六)
人工智能·算法·目标检测·计算机视觉·3d·目标跟踪·自动驾驶
KeyPan5 小时前
【机器学习:一、机器学习简介】
人工智能·数码相机·算法·机器学习·计算机视觉
湫ccc6 小时前
《Opencv》基础操作详解(4)
人工智能·opencv·计算机视觉
Jeo_dmy8 小时前
(二)当人工智能是一个函数,函数形式怎么选择?ChatGPT的函数又是什么?
人工智能·计算机视觉·chatgpt·推荐算法