当前位置:   article > 正文

备赛笔记:Opencv学习:颜色识别_opencv颜色识别

opencv颜色识别

OpenCV颜色识别一般要以下步骤:
1 颜色空间转换,将BGR转换为HSV,用色调区分颜色
2 按照阈值滤出所识别的颜色
3 消除噪点,平滑边界
3 提取连续域,提取要识别的颜色

1 HSV
H:色调,用角度度量,范围0°到360°,从红色开始逆时针方向计算。红色为0°,红绿蓝间隔120°,互补色差180°。
S:饱和度,范围0到1,代表光谱色占颜色比例。0时颜色只有灰度,1时颜色为纯光谱色
V:明度,范围0到1,代表颜色明亮程度。0为黑色,1为白色
在这里插入图片描述
在这里插入图片描述

腐蚀(erosion)和膨胀(dilation)
腐蚀和膨胀作用:
1 消除噪声
2 分割独立图像元素
3 寻找极大值或极小值区域
膨胀:
将图像和任意寻找内涵进行卷积,提取覆盖区域的最大像素值。这一操作会使亮区扩展
腐蚀:
和膨胀正好相反,提取覆盖区域最下像素值1,这一操作让亮区变细,暗区变大

提取连通域:
两种像素邻接关系会构成连通域:4邻接(上下左右),和8邻接(包括对角线)
在这里插入图片描述
opencv里寻找连通域函数findContours()

·语法格式:
image,contours,hierarchy = cv2.findContours(image,mode,method)
式中返回值为:
·image: 与函数参数中的原始图像image一致。
·contours: 返回的轮廓。
·hierarchy: 图像的拓扑信息(轮廓层次)。
式中参数为:
·mode: 轮廓检索模式。
·method: 轮廓的近似方法。
参数mode:

cv2.RETR_EXTERNAL 只检测外轮廓

cv2.RETR_LIST检测的轮廓不建立等级关系

cv2.RETR_CCOMP建立两个等级的轮廓

cv2.RETR_TREE建立一个等级树结构的轮廓

参数method:

cv2.CHAIN_APPROX_NONE存储所有的轮廓点

cv2.CHAIN_APPROX_SIMPLE压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标,例如一个矩形轮廓只需4个点来保存轮廓信息

(具体算法实现可以去了解union-find算法)

颜色识别程序实现

import cv2
import numpy as np

cap = cv2.VideoCapture(0)
red_min = np.array([0, 128, 46])
red_max = np.array([5, 255, 255])
red2_min = np.array([156, 128, 46])
red2_max = np.array([180, 255, 255])
yellow_min = np.array([15, 128, 46])
yellow_max = np.array([50, 255, 255])

while True:
    ret,frame = cap.read()
    x,y = frame.shape[0:2]
    small_frame = cv2.resize(frame, (int(y / 2), int(x / 2)))
    cv2.imshow('small', small_frame)
    
    src = small_frame.copy()
    res = src.copy()
    hsv = cv2.cvtColor(src, cv2.COLOR_BGR2HSV)
    mask_red1 = cv2.inRange(hsv, red_min, red_max)
    mask_red2 = cv2.inRange(hsv, red2_min, red2_max)
    mask_yellow = cv2.inRange(hsv, yellow_min, yellow_max)
    mask = cv2.bitwise_or(mask_red1, mask_red2)
    mask = cv2.bitwise_or(mask, mask_yellow)
    res = cv2.bitwise_and(src, src, mask=mask)
    h, w = res.shape[:2]
    blured = cv2.blur(res, (5, 5))
    ret, bright = cv2.threshold(blured, 10, 255, cv2.THRESH_BINARY)
    gray = cv2.cvtColor(bright, cv2.COLOR_BGR2GRAY)
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
    opened = cv2.morphologyEx(gray, cv2.MORPH_CLOSE, kernel)
    closed = cv2.morphologyEx(opened, cv2.MORPH_CLOSE, kernel)
    contours, hierarchy = cv2.findContours(closed, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    cv2.drawContours(src, contours, -1, (255, 0, 0), 2)
    cv2.imsow("result", src)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
cap.release()
cv2.destroyAllWindows()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

1 red_min = np.array([0, 128, 46])
red_max = np.array([5, 255, 255])
red2_min = np.array([156, 128, 46])
red2_max = np.array([180, 255, 255])
yellow_min = np.array([15, 128, 46])
yellow_max = np.array([50, 255, 255])
我们要识别两种红色和一种黄色。这里列出它们的阈值上下限作为图像二值化的取值范围

2 hsv = cv2.cvtColor(src, cv2.COLOR_BGR2HSV)
把图像转化为hsv类型

3 mask_red1 = cv2.inRange(hsv, red_min, red_max)
mask_red2 = cv2.inRange(hsv, red2_min, red2_max)
mask_yellow = cv2.inRange(hsv, yellow_min, yellow_max)
mask = cv2.bitwise_or(mask_red1, mask_red2)
mask = cv2.bitwise_or(mask, mask_yellow)
res = cv2.bitwise_and(src, src, mask=mask)
图像二值化,提取满足阈值范围的像素
cv2.inRange(图像,阈值下限,阈值上限):将阈值范围内像素设为255,阈值之外像素设为0
cv2.bitwise_or(图像1,图像2):图像或运算实现叠加
cv2.bitwise_and(图像1,图像2):图像与运算实现叠加

4 kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
opened = cv2.morphologyEx(gray, cv2.MORPH_CLOSE, kernel)
closed = cv2.morphologyEx(opened, cv2.MORPH_CLOSE, kernel)
提取连续开闭区间用于降噪:

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
设置卷积核,第一个参数代表卷积核形状,有MORPH_RECT(矩形),MORPH_ELLIPSE(椭圆),MORPH_CROSS(十字形),第二个参数代表卷积核行和列

cv2.morphologyEx(要处理图像,处理方式,卷积核)
opened = cv2.morphologyEx(gray, cv2.MORPH_CLOSE, kernel)
开运算,先腐蚀后膨胀,可以消除小黑点,平滑边界。

closed = cv2.morphologyEx(opened, cv2.MORPH_CLOSE, kernel)
闭运算,先膨胀后腐蚀,可以消除小黑洞

5 contours, hierarchy = cv2.findContours(closed, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(src, contours, -1, (255, 0, 0), 2)
提取连续域,得到区间

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/369927
推荐阅读
相关标签
  

闽ICP备14008679号