虚谷号

 找回密码
 立即注册
搜索
热搜: 活动 交友
查看: 446402|回复: 224

当Yeelight遇上虚谷号#12 智能变色灯

  [复制链接]

16

主题

41

帖子

181

积分

注册会员

Rank: 2

积分
181
发表于 2019-3-20 10:08:53 | 显示全部楼层 |阅读模式
本帖最后由 linmiaoyan 于 2019-3-30 14:53 编辑

12智能变色灯
在摄像头前放置不同颜色的物体,灯泡自动改变颜色。

摄像头前物体是什么颜色?看起来问题很简单,但是让计算机来回答并不容易。当我们要判断某个物体是什么颜色的时候,往往会先找出这一物体的最主要颜色,再判断这一颜色和哪种颜色最接近。计算机虽然说不出天蓝、橘黄之类的色彩名词,但可以精确地分析出图像中某一个像素点的RGB值,即RGB三种颜色的具体组成,但一个物体往往不会是纯色的,所以要确定一张含有多种颜色的图像的“颜色”,需要确定一个算法。

算法一:将这个图像的所有像素点的RGB值分别相加,取出RGB三种颜色的平均值。如果担心计算的效率太低,可以均匀地取出部分像素,应该可以得到大致的颜色平均值。
简单的取色方法,通过对图像参数的计算得出结果,拥有高准确度。
算法二:利用滤镜功能,给这个图像加上RGB三种颜色遮罩,处理为黑白图片,然后通过计算分别得到图像的白色区域面积大小,换算为0-255之间的数值。
更加类似于机器学习,通过颜色字典的学习,机器能够“智能”的识别主要物体的颜色,在拥有大量数据的情况下,机器的识别能力能够大大提升。

以上两种方法可以相互结合,得到更好的识别效果

import cv2
import time
from yeelight import Bulb

bulb = Bulb("192.168.31.127")
bulb.turn_on()

#得到图片
def get_pic():
    cap=cv2.VideoCapture(0)
    sucess,img=cap.read()
    cv2.imwrite("image.jpg",img)
    cap.release()

#处理图片(裁剪 读取像素点的RGB值并取平均)
def get_color(frame):
    #读取图片像素点的步长,50则为50个像素点读取一次
    step=0
    red=0
    blue=0
    green=0
    print('开始处理')
    high, width, _ = frame.shape
    print('剪裁前行数%d,列数%d' % (high, width))
    # 裁剪坐标为[x0:x1,y0:y1],我们截取图像的中心部分
    frame=frame[int(high/4):int(high*3/4),int(width/4):int(width*3/4)]
    high, width, _ = frame.shape
    print('剪裁后行数%d,列数%d' % (high, width))
    #读取图片中所有像素点的RGB值
    frame1 = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    for i in frame1:
        #i中的数据类型是一整行的像素点[[0,0,0][0,0,0]]
        step+=1
        if (step==50):
            for point in i:
            #point中的数据类型是单个像素点
                red+=point[0]
                green+=point[1]
                blue+=point[2]
            times=0
    red=red/len(i)
    green=green/len(i)
    blue=blue/len(i)
    return red,green,blue


if __name__ == '__main__':
    while 1:
        get_pic()
        filename = r"image.jpg"
        frame = cv2.imread(filename)
        r,g,b=get_color(frame)
        print('r:',r)
        print('g:',g)
        print('b:',b)
        bulb.set_rgb(int(r),int(g),int(b))
        time.sleep(2)


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

16

主题

41

帖子

181

积分

注册会员

Rank: 2

积分
181
 楼主| 发表于 2019-3-20 10:11:35 | 显示全部楼层
本帖最后由 linmiaoyan 于 2019-3-30 11:46 编辑

算法二 添加遮罩
main.py主程序源代码

import cv2
from yeelight import Bulb
import time
import colorList

bulb = Bulb("192.168.31.39")
bulb.turn_on()
#得到图片
def get_pic():
    cap=cv2.VideoCapture(0)
    sucess,img=cap.read()
    cv2.imshow("img",img)
    cv2.imwrite("CachePhoto/image2.jpg",img)
    cv2.destroyAllWindows()
    cap.release()

#处理图片
def get_color(frame):
    print('开始处理')
    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
    maxsum = -100
    color = None
    color_dict = colorList.getColorList()
    for d in color_dict:
        mask = cv2.inRange(hsv, color_dict[d][0], color_dict[d][1])
        cv2.imwrite('CachePhoto/' + d +'.jpg', mask)
        binary = cv2.threshold(mask, 127, 255, cv2.THRESH_BINARY)[1]
        binary = cv2.dilate(binary, None, iterations=2)
        img, cnts, hiera = cv2.findContours(binary.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        sum = 0
        for c in cnts:
#计算轮廓面积,根据轮廓大小确定屏幕中的主要颜色
            sum += cv2.contourArea(c)  
        if sum > maxsum:
            maxsum = sum
            color = d
    return color

if __name__ == '__main__':
    while 1:
        #参数路径
        get_pic()
        filename = r"CachePhoto/image2.jpg"
#cv2库读取图片
        frame = cv2.imread(filename)
#得到RGB值
        rgb=get_color(frame)
        red=int(rgb[1:3],16)
        green=int(rgb[3:5],16)
        blue=int(rgb[5:7],16)
        bulb.set_rgb(red,green,blue)
        time.sleep(5)


回复

使用道具 举报

16

主题

41

帖子

181

积分

注册会员

Rank: 2

积分
181
 楼主| 发表于 2019-3-20 10:12:17 | 显示全部楼层
colorlist部分代码
# 定义字典存放颜色分量上下限
# 例如:{颜色: [min分量, max分量]}
# {'red': [array([160,  43,  46]), array([179, 255, 255])]}

def getColorList():
    dict = collections.defaultdict(list)

    # 黑色
    lower_black = np.array([0, 0, 0])
    upper_black = np.array([180, 255, 46])
    color_list = []
    color_list.append(lower_black)
    color_list.append(upper_black)
    dict['#131314'] = color_list

    # 红色
    lower_red = np.array([156, 43, 46])
    upper_red = np.array([180, 255, 255])
    color_list = []
    color_list.append(lower_red)
    color_list.append(upper_red)
    dict['#FF0900'] = color_list

········

    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])

回复

使用道具 举报

0

主题

2

帖子

6

积分

新手上路

Rank: 1

积分
6
发表于 2019-8-1 15:40:07 | 显示全部楼层
摄像头前物体是什么颜色?重庆时时彩 看起来问题很简单,但是让计算机来回答并不容易。当我们要判断某个物体是什么颜色的时候,往往会先找出这一物体的最主要颜色,幸运飞艇 再判断这一颜色和哪种颜色最接近。北京pk10 计算机虽然说不出天蓝、橘黄之类的色彩名词,但可以精确地分析出图像中某一个像素点的RGB值,即RGB三种颜色的具体组成,但一个物体往往不会是纯色的,所以要确定一张含有多种颜色的图像的“颜色”,需要确定一个算法。
回复

使用道具 举报

0

主题

3

帖子

18

积分

新手上路

Rank: 1

积分
18
发表于 2019-11-28 17:31:05 | 显示全部楼层
谢谢群主分享!感谢!
回复

使用道具 举报

0

主题

3

帖子

18

积分

新手上路

Rank: 1

积分
18
发表于 2019-11-28 18:16:59 | 显示全部楼层
请问楼主:colorlist部分代码  中省略的代码是可以自己按上面红色和黑色的代码模式自己添加其他颜色的代码吗?   小白不懂,求教。
回复

使用道具 举报

0

主题

14

帖子

166

积分

禁止发言

积分
166
发表于 2019-11-30 15:09:31 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

0

主题

14

帖子

140

积分

注册会员

Rank: 2

积分
140
发表于 2019-12-3 21:52:04 | 显示全部楼层
回复

使用道具 举报

16

主题

41

帖子

181

积分

注册会员

Rank: 2

积分
181
 楼主| 发表于 2019-12-15 21:54:29 | 显示全部楼层
binge9182 发表于 2019-11-28 18:16
请问楼主:colorlist部分代码  中省略的代码是可以自己按上面红色和黑色的代码模式自己添加其他颜色的代码 ...

是的,但是这种遮罩的算法太复杂了,不如第一种
回复

使用道具 举报

0

主题

19

帖子

222

积分

中级会员

Rank: 3Rank: 3

积分
222
发表于 2019-12-19 23:18:29 | 显示全部楼层
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

虚谷号

GMT+8, 2021-12-8 18:39 , Processed in 0.053085 second(s), 19 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表