OpenCV---xx3(色彩物块识别)

利用Opencv在Python中进行颜色检测

我们将在本文章中尝试来检测和跟踪特定的颜色对象

HSV颜色空间

HSV颜色空间为(色相,饱和度,明度)颜色模型
其可以更紧密的与人的视觉感知颜色属性方式保持一致
因此使用Opencv跟踪某颜色 必须使用HSV模型来进行定义

在opencv的HSV颜色空间
H(色彩/色度) 的取值范围 为[0,179]
S(饱和度) [0,255]
V(亮度) [0,255]

颜色识别

对于某张图片 我们可以较为容易的得到其BGR值
我们要将其转为HSV模型

绿: R65 G193 B 144
红: R255 G102 B60
蓝: R54 G101 B217
将BGR转为HSV
np.uint8([[[b,g,r]]])
hsv_color = cv.cvtColor()    

代码详细

import cv2 as cv
import numpy as np

# 掩膜获得函数
def mask_range(bgr_img):
    """
    掩膜获得函数
    :return: 三个颜色的mask b, g, r
    """
    # BGR 颜色空间
    hsv_img = cv.cvtColor(bgr_img, cv.COLOR_BGR2HSV)

    green_color = np.uint8([[[144, 193, 65]]])
    blue_color = np.uint8([[[217, 101, 54]]])
    red_color = np.uint8([[[60, 102, 254]]])

    # HSV 颜色空间
    green_hsv = cv.cvtColor(green_color, cv.COLOR_BGR2HSV)
    blue_hsv = cv.cvtColor(blue_color, cv.COLOR_BGR2HSV)
    red_hsv = cv.cvtColor(red_color, cv.COLOR_BGR2HSV)

    g_hue = green_hsv[0, 0, 0]
    b_hue = blue_hsv[0, 0, 0]
    r_hue = red_hsv[0, 0, 0]
    g_bot_bound = np.array([g_hue - 10, 120, 100], dtype=np.uint8)
    g_up_bound = np.array([g_hue + 10, 255, 255], dtype=np.uint8)
    b_bot_bound = np.array([b_hue - 10, 120, 100], dtype=np.uint8)
    b_up_bound = np.array([b_hue + 10, 255, 255], dtype=np.uint8)
    r_bot_bound = np.array([r_hue - 5, 120, 100], dtype=np.uint8)
    r_up_bound = np.array([r_hue + 10, 255, 255], dtype=np.uint8)

    blue_mask = cv.inRange(hsv_img, b_bot_bound, b_up_bound)
    green_mask = cv.inRange(hsv_img, g_bot_bound, g_up_bound)
    red_mask = cv.inRange(hsv_img, r_bot_bound, r_up_bound)

    return blue_mask, green_mask, red_mask



# 预处理函数
def pre_processing(first_mask):
    # 先腐蚀 再膨胀 去除噪音
    first_mask = cv.GaussianBlur(first_mask, (9, 9), 12, 12)
    second_mask = cv.morphologyEx(first_mask, 0, (9, 9), iterations=2)
    res_mask = cv.morphologyEx(second_mask, 1, (9, 9))

    return res_mask


# 轮廓检测函数 找到最大的 且满足面积大于一定值的轮廓
def get_cont(res_mask):
    # 仅检测最外层轮廓,最少点
    cnts, hierarchy = cv.findContours(res_mask, 0, 2)
    cnts_area = []
    for i in cnts:
        cnts_area.append(cv.contourArea(i))

    res_cnts = None
    if len(cnts_area) != 0:
        if max(cnts_area) > 3600:
            max_cnts = cnts[cnts_area.index(max(cnts_area))]
            res_cnts = [max_cnts]
    return res_cnts


# 拿到轮廓中心点
def get_center(img_cnts):
    cnts = img_cnts[0]
    mean_x = np.mean(cnts[:, 0, 0])
    mean_y = np.mean(cnts[:, 0, 1])
    center = (int(mean_x), int(mean_y))
    return center


# 在中心点处 画出一个圈展示
def detect_color(color_mask, show_img):
    process_mask = pre_processing(color_mask)
    cnts = get_cont(process_mask)

    if cnts is not None:
        center = get_center(cnts)
        cv.circle(show_img, center, 50, (255, 255, 255), 5)
        cv.circle(show_img, center, 5, (0, 0, 255), 5)
    cv.imshow('color_cnt', show_img)


if __name__ == '__main__':
    video_obj = cv.VideoCapture(0)
    mode = 'b'



    # 读取摄像头
    while video_obj.isOpened():
        _, img = video_obj.read()
        gray_img = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
        b_mask, g_mask, r_mask = mask_range(img)
        com_list = {'r': r_mask, 'g': g_mask,
                    'b': b_mask}
        com = cv.waitKey(1)

    # 三种颜色检验
        if com == ord('r'):
            mode = 'r'
            print('当前模式: 红色检测')
        elif com == ord('g'):
            mode = 'g'
            print('当前模式: 绿色检测')
        elif com == ord('b'):
            mode = 'b'
            print('当前模式: 蓝色检测')

        detect_color(com_list[mode], img)

        if com == ord('q'):
            break

    video_obj.release()
    cv.destroyAllWindows()
posted @ 2022-04-12 09:36  cc学习之路  阅读(585)  评论(0)    收藏  举报