• 基于OpenCV实现对图片及视频中感兴趣区域颜色识别


    基于OpenCV实现图片及视频中选定区域颜色识别

    近期,需要实现检测摄像头中指定坐标区域内的主体颜色,通过查阅大量相关的内容,最终实现代码及效果如下,具体的实现步骤在代码中都详细注释,代码还可以进一步优化,但提升有限。

    主要实现过程:按不同颜色的取值范围,对图像进行循环遍历,转换为灰度图,将本次遍历的颜色像素转换为白色,对白色部分进行膨胀处理,使其更加连续,计算白色部分外轮廓包围的面积累加求和,比较每种颜色围起来面积,保存最大值及其颜色,所有颜色遍历完后,返回最大值对应的颜色,显示在图像上

    如果有类似的颜色识别的任务,可参考以下代码修改后实现具体需求

    colorList.py

    import numpy as np
    import collections
    
    # 将rgb图像转换为hsv图像后,确定不同颜色的取值范围
    def getColorList():
        dict = collections.defaultdict(list)
    
        # black
        lower_black = np.array([0, 0, 0])
        upper_black = np.array([180, 255, 46])
        color_list_black = []
        color_list_black.append(lower_black)
        color_list_black.append(upper_black)
        dict['black'] = color_list_black
    
        # gray
        lower_gray = np.array([0, 0, 46])
        upper_gray = np.array([180, 43, 220])
        color_list_gray= []
        color_list_gray.append(lower_gray)
        color_list_gray.append(upper_gray)
        dict['gray'] = color_list_gray
    
        # white
        lower_white = np.array([0, 0, 221])
        upper_white = np.array([180, 30, 255])
        color_list_white = []
        color_list_white.append(lower_white)
        color_list_white.append(upper_white)
        dict['white'] = color_list_white
    
        # red
        lower_red = np.array([156, 43, 46])
        upper_red = np.array([180, 255, 255])
        color_list_red = []
        color_list_red.append(lower_red)
        color_list_red.append(upper_red)
        dict['red'] = color_list_red
    
        # red2
        lower_red = np.array([0, 43, 46])
        upper_red = np.array([10, 255, 255])
        color_list_red2 = []
        color_list_red2.append(lower_red)
        color_list_red2.append(upper_red)
        dict['red2'] = color_list_red2
    
        # orange
        lower_orange = np.array([11, 43, 46])
        upper_orange = np.array([25, 255, 255])
        color_list_orange = []
        color_list_orange.append(lower_orange)
        color_list_orange.append(upper_orange)
        dict['orange'] = color_list_orange
    
        # yellow
        lower_yellow = np.array([26, 43, 46])
        upper_yellow = np.array([34, 255, 255])
        color_list_yellow = []
        color_list_yellow.append(lower_yellow)
        color_list_yellow.append(upper_yellow)
        dict['yellow'] = color_list_yellow
    
        # green
        lower_green = np.array([35, 43, 46])
        upper_green = np.array([77, 255, 255])
        color_list_green = []
        color_list_green.append(lower_green)
        color_list_green.append(upper_green)
        dict['green'] = color_list_green
    
        # cyan
        lower_cyan = np.array([78, 43, 46])
        upper_cyan = np.array([99, 255, 255])
        color_list_cyan = []
        color_list_cyan.append(lower_cyan)
        color_list_cyan.append(upper_cyan)
        dict['cyan'] = color_list_cyan
    
        # blue
        lower_blue = np.array([100, 43, 46])
        upper_blue = np.array([124, 255, 255])
        color_list_blue = []
        color_list_blue.append(lower_blue)
        color_list_blue.append(upper_blue)
        dict['blue'] = color_list_blue
    
        # purple
        lower_purple = np.array([125, 43, 46])
        upper_purple = np.array([155, 255, 255])
        color_list_purple = []
        color_list_purple.append(lower_purple)
        color_list_purple.append(upper_purple)
        dict['purple'] = color_list_purple
    
        return dict
    
    if __name__ == '__main__':
        color_dict = getColorList()
        print(color_dict)
    
        num = len(color_dict)
        print('num=', num)
    
        for d in color_dict:
            print('key=', d)
            print('value=', color_dict[d][1])
    
    
    折叠

    image_color_realize.py

    import cv2
    import colorList
    
    # 实现对图片中目标区域颜色的识别
    def get_color(frame):
        print('go in get_color')
        hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
        maxsum = 0
        color = None
        color_dict = colorList.getColorList()
    
        # count = 0
    
        for d in color_dict:
            mask = cv2.inRange(hsv, color_dict[d][0], color_dict[d][1])  # 在后两个参数范围内的值变成255
            binary = cv2.threshold(mask, 127, 255, cv2.THRESH_BINARY)[1]  # 在灰度图片中,像素值大于127的都变成255,[1]表示调用图像,也就是该函数第二个返回值
    
            # cv2.imshow("0",binary)
            # cv2.waitKey(0)
            # count+=1
    
            binary = cv2.dilate(binary, None, iterations=2)  # 使用默认内核进行膨胀操作,操作两次,使缝隙变小,图像更连续
            cnts = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2]  # 获取该函数倒数第二个返回值轮廓
            sum = 0
            for c in cnts:
                sum += cv2.contourArea(c)  # 获取该颜色所有轮廓围成的面积的和
            # print("%s  , %d" %(d, sum ))
            if sum > maxsum:
                maxsum = sum
                color = d
                if color == 'red2':
                    color = 'red'
                elif color == 'orange':
                    color = 'yellow'
                elif color == 'purple' or color == 'blue' or color == 'cyan' or color == 'white' or color == 'green':
                    color = 'normal'
        return color
    
    if __name__ == '__main__':
        filename = "C:/Users/admin/Desktop/water_samples/live01.jpg"
        frame = cv2.imread(filename)
        # frame = frame[180:280, 180:380]  # [y:y+h, x:x+w] 注意x,y顺序
        color = get_color(frame)
    
        # 绘制文本
        cv2.putText(img=frame,text=color,org=(20,50),fontFace=cv2.FONT_HERSHEY_SIMPLEX,
                    fontScale=1.0,color=(0,255,0),thickness=2)
    
        # cv2.namedWindow('frame',cv2.WINDOW_NORMAL)  # 设置显示窗口可调节
        cv2.imshow('frame',frame)
        cv2.waitKey(0)
    
    折叠

    video_color_realize.py

    import cv2
    import xf_color
    
    
    # 对视频或摄像头获取的影像目标区域颜色进行识别
    
    cap = cv2.VideoCapture("C:/Users/admin/Desktop/water_samples/01.mp4")
    # cap = cv2.VideoCapture(0)
    cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1100)  # 这里窗口大小调节只对摄像头有效
    cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 750)
    
    while cap.isOpened():
        ret, frame0 = cap.read()
        # 对图像帧进行翻转(因为opencv图像和我们正常是反着的) 视频是正常的,摄像头是反转的
        # frame0 = cv2.flip(src=frame0, flipCode=2)
    
        # frame = frame[180:280, 180:380]  # [y:y+h, x:x+w]
        # frame = frame0[200:400, 100:300]  # 设置检测颜色的区域,四个顶点坐标
        frame = frame0
    
        # frame=cv2.resize(src=frame,dsize=(750,600))
        hsv_frame = cv2.cvtColor(src=frame, code=cv2.COLOR_BGR2HSV)
        # 获取读取的帧的高宽
        height, width, channel = frame.shape
        color = xf_color.get_color(hsv_frame)
        # 绘制文本
        cv2.putText(img=frame0, text=color, org=(20, 50), fontFace=cv2.FONT_HERSHEY_SIMPLEX,
                    fontScale=1.0, color=(0, 255, 0), thickness=2)
        cv2.imshow('frame', frame0)
        key = cv2.waitKey(1)
        if key == 27:
            break
    
    cap.release()
    cv2.destroyAllWindows()
    
    
    if __name__ == '__main__':
        print('Pycharm')
    
    折叠

    效果如下:

    示例图片1

    示例图片2

    示例图片3

  • 相关阅读:
    从0搭建Vue3组件库(七):使用 glup 打包组件库并实现按需加载
    MVVM模式根模块
    不是吧?30秒 就能学会一个python小技巧?!
    Lightsail VPS 实例在哪些方面胜过 EC2 实例?
    C语言 &=(按位与后赋值)^=(按位异或后赋值) |=(按位或后赋值)
    不同相机在不同高度拍的图片resize在同一尺度
    02 - 分析一个Android程序以及日志工具的使用
    TEMU自养号测评系统如何搭建,有哪些要求
    Arrays的用法(常见方法的使用)
    点亮LED灯三盏
  • 原文地址:https://www.cnblogs.com/wydilearn/p/16505887.html