惊!Python能够检测动态的物体颜色!
程序员文章站
2022-05-21 14:47:47
前言 文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理。 作者: 李秋键 PS:如有需要Python学习资料的小伙伴可以加点击下方链接自行获取 http://note.youdao.com/noteshare?id=3054cce4a ......
文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理。
作者: 李秋键
ps:如有需要python学习资料的小伙伴可以加点击下方链接自行获取
开始前的准备
借助python和opencv通过图片相减的方法找到动态物体,然后根据像素值的大小判断其中的均值颜色。
首先我们使用的库有cv2,numpy,collections,time。其中导入模块的代码如下:
import cv2
import numpy as np
import collections
import time
下面是读取摄像头:
camera = cv2.videocapture(0)
做一些开始前的准备,包括循环次数,摄像头内容读入,保存上一帧的图片作为对比作差找到动态物体,然后定义框架的长和宽。
firstframe = none a=0 ret0,frame0 = camera.read() cv2.imwrite("1.jpg",frame0) x, y, w, h = 10,10,100,100
下面是定义颜色的部分代码,比如定义的黑色,可以参照hsv表进行拓展,如图所示
然后可以知道黑色的最低值为0,0,0,最大值为180,255,46然后建立数组存储颜色数据,通过字典达到映射效果。
1 # 处理图片 2 def get_color(frame): 3 print('go in get_color') 4 hsv = cv2.cvtcolor(frame, cv2.color_bgr2hsv) 5 maxsum = -100 6 color = none 7 color_dict = getcolorlist() 8 for d in color_dict: 9 mask = cv2.inrange(frame, color_dict[d][0], color_dict[d][1]) 10 cv2.imwrite(d + '.jpg', mask) 11 binary = cv2.threshold(mask, 127, 255, cv2.thresh_binary)[1] 12 binary = cv2.dilate(binary, none, iterations=2) 13 img, cnts, hiera = cv2.findcontours(binary.copy(), cv2.retr_external, cv2.chain_approx_simple) 14 sum = 0 15 for c in cnts: 16 sum += cv2.contourarea(c) 17 if sum > maxsum: 18 maxsum = sum 19 color = d 20 return color
图像处理
紧接着是图像处理,其中包括转为灰度图,读取颜色字典,然后腐化膨胀操作。
1 # 处理图片 2 def get_color(frame): 3 print('go in get_color') 4 hsv = cv2.cvtcolor(frame, cv2.color_bgr2hsv) 5 maxsum = -100 6 color = none 7 color_dict = getcolorlist() 8 for d in color_dict: 9 mask = cv2.inrange(frame, color_dict[d][0], color_dict[d][1]) 10 cv2.imwrite(d + '.jpg', mask) 11 binary = cv2.threshold(mask, 127, 255, cv2.thresh_binary)[1] 12 binary = cv2.dilate(binary, none, iterations=2) 13 img, cnts, hiera = cv2.findcontours(binary.copy(), cv2.retr_external, cv2.chain_approx_simple) 14 sum = 0 15 for c in cnts: 16 sum += cv2.contourarea(c) 17 if sum > maxsum: 18 maxsum = sum 19 color = d 20 return color
图片相减的办法
然后是图片相减找到动态物体的代码,每循环5次保存一次图片,时间是很短的不用担心。然后通过absdiff函数对图片像素值作差找到动态物体,接着讲像素值相减非零的部分用矩形框圈出来。
1 while true: 2 ret, frame = camera.read() 3 if not ret: 4 break 5 gray = cv2.cvtcolor(frame, cv2.color_bgr2gray) 6 gray = cv2.gaussianblur(gray, (21, 21), 0) 7 a=a+1 8 if a%5==0: 9 cv2.imwrite("1.jpg", frame) 10 firstframe=cv2.imread("1.jpg") 11 firstframe= cv2.cvtcolor(firstframe, cv2.color_bgr2gray) 12 firstframe= cv2.gaussianblur(firstframe, (21, 21), 0) 13 framedelta = cv2.absdiff(firstframe, gray) 14 thresh = cv2.threshold(framedelta, 25, 255, cv2.thresh_binary)[1] 15 thresh = cv2.dilate(thresh, none, iterations=2) 16 # cnts= cv2.findcontours(thresh.copy(),cv2.retr_external,cv2.chain_approx_simple) 17 18 x, y, w, h = cv2.boundingrect(thresh) 19 frame = cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 0, 255), 2) 20 cv2.imshow("frame", frame)
因为保存图片是每隔5次进行一次,在某个瞬间可能保存的图片不存在等原因,所以需要通过try的方法避免错误,最终的演示效果文末有。
1 try: 2 ret0, frame0 = camera.read() 3 cropped = frame0[y:y+h,x:x+w ] # 裁剪坐标为[y0:y1, x0:x1] 4 cv2.imwrite("3.jpg", cropped) 5 6 frame1 = cv2.imread(filename) 7 print(get_color(frame1)) 8 # plt.title(label[model.predict_classes(image)], fontproperties=myfont) 9 imgzi = cv2.puttext(frame, get_color(frame1), (30, 30), cv2.font_hershey_complex, 1.2, 10 (255, 255, 255), 2) 11 cv2.imwrite("2.jpg", imgzi) 12 cv2.imshow("frame", cv2.imread("2.jpg")) 13 except: 14 pass 15 16 key = cv2.waitkey(1) & 0xff 17 18 if key == ord("q"): 19 break 20 21 camera.release()