前言

文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理。

作者: 李秋键

PS:如有需要Python学习资料的小伙伴可以加点击下方链接自行获取

http://note.youdao.com/noteshare?id=3054cce4add8a909e784ad934f956cef

开始前的准备

借助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()

其最终演示效果如图所示:

至此,动态物体检测代码基本实现。其中的拓展功能可以按照自己的需求进行修改、

01-07 04:45
查看更多