附录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()
相关推荐
吃好睡好便好4 小时前
MATLAB中图像的读取、写入和显示
开发语言·图像处理·学习·计算机视觉·matlab
小保CPP7 小时前
OpenCV C++基于模糊数学的图像修复
c++·人工智能·opencv·计算机视觉
深圳市快瞳科技有限公司9 小时前
宠物行为识别:将日常行为转化为可量化的健康指标
人工智能·算法·计算机视觉·宠物
小保CPP10 小时前
OpenCV C++基于模糊数学的图像滤波
c++·人工智能·opencv·计算机视觉
m沐沐11 小时前
【计算机视觉】OpenCV 人脸检测与 Haar 级联分类器——原理、实现与实战案例
人工智能·pytorch·python·深度学习·opencv·计算机视觉·人脸检测
m沐沐11 小时前
【计算机视觉】OpenCV 物体跟踪——原理、算法与CSRT跟踪器实战
人工智能·python·深度学习·opencv·算法·计算机视觉·人脸识别
老猿AI洞察11 小时前
智能视觉检测平台——完整商业化项目全功能详解
人工智能·yolo·计算机视觉·视觉检测
一个王同学19 小时前
从零到一 | CV转多模态大模型 | week19 | 基于 FastAPI 和 vLLM 的多模态大模型部署
人工智能·深度学习·计算机视觉·fastapi·改行学it·vllm
szxinmai主板定制专家1 天前
RK3568+FPGA高速并行采集|半导体探针测试设备多通道同步数据采集系统设计
人工智能·嵌入式硬件·计算机视觉·fpga开发
韩师傅1 天前
重生之我成为模型 第三篇 · 我从来只给可能性,答案是你们翻译的
深度学习·机器学习·计算机视觉