目录
一、完成摄像头的调用
二、利用python调用opencv库函数对图像进行处理
2.1 图像处理大体流程
2.2 opencv调用函数的参数以及含义
2.2.1 ret, img = cap.read() 读取帧图像
2.2.2 cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 灰度图像
2.2.3 gray_diff_img = cv2.absdiff(gray_img, previous_img) 帧差法
2.2.4 cv2.threshold (src, thresh, maxval, type) 二值化处理
2.2.5 cv2.medianBlur(src, ksize) 中值滤波
2.2.6 np.ones(shape, dtype=None, order='C')
2.2.7 cv2.morphologyEx(src, op, kernel)
2.2.8 cv2.findContours(image,mode,method)
2.2.9 cv2.contourArea() 求轮廓面积
2.2.10 cv2.boundingRect() 返回轮廓框框坐标
2.2.11 cv2.rectangle() 坐标连线,框出轮廓
2.2.12 cv2.imshow() 窗口显示图像
三、处理代码
一、完成摄像头的调用
如果不会具体操作的请看
树莓派调用CSI摄像头进行实时监控
二、利用python调用opencv库函数对图像进行处理
2.1 图像处理大体流程
(1) 打开摄像头设备
(2) 图像进行帧处理(一帧一帧处理),while循环中,先读取摄像头一帧图像
(3) 灰度图像处理,判断上一帧图像是否为空。若为空,赋予一帧图像并进行图像灰度处理;若不为空,则也进行图像灰度处理。
(4) 帧差法,利用上一帧图像和这一帧图像作差值处理。
(5) 二值化图像处理,对进行帧差法后的图像作二值化处理。
(6) 中值滤波处理
(7) 闭运算,腐蚀,膨胀处理。
(8) 对运动图像进行轮廓检测,返回坐标集
(9) 利用坐标框选目标。
(10) 显示图像,将处理完的图像变为上一帧图像。
2.2 opencv调用函数的参数以及含义
2.2.1 ret, img = cap.read() 读取帧图像
cap 是你摄像头设备0捕获的摄像头图像数据( 例: cap = cv2.VideoCapture(0) );
read()是opencv库函数读取摄像头一帧图像,cap.read() 就是获取摄像头设备0读取的一帧图像;
img 就是摄像头设备0读取的一帧图像,图像格式为BGR;
ret 就是bool类型,读取成功返回True,失败则是Flase.
2.2.2 cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 灰度图像
img:传入转换的图片。
cv2.COLOR_BGR2GRAY:将格式为BGR的图片转换为灰度图片。
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) gray就是转换成功的灰度图片
2.2.3 gray_diff_img = cv2.absdiff(gray_img, previous_img) 帧差法
cv2.absdiff(a,b) : a,b均为一帧图像。
比较二帧图像不同之处(例如:运动检测时,只有运动的物体会运动,而背景则不动,cv2.absdiff(a,b)得到的是去除背景的运动物体的图片)。gray_diff_img则是二帧处理后的一帧图像。
2.2.4 cv2.threshold (src, thresh, maxval, type) 二值化处理
src:传入的一帧图像。
thresh:阈值(数值范围0-255,根据光照强度选择)
maxval:填充色(数值范围0-255,二值化图像一般都选255)
type:如下图
thresh_img = cv2.threshold(gray_diff_img, 40, 255, cv2.THRESH_BINARY)
得到的二值化图像thresh_img
2.2.5 cv2.medianBlur(src, ksize) 中值滤波
src 是需要处理的图像。
ksize 是滤波核的大小。滤波核大小是指在滤波处理过程中其邻域图像的高度和宽度。需要注意,核大小必须是比1大的奇数,比如3、5、7等。
例:mask_img = cv2.medianBlur(thresh_img, 3)
2.2.6 np.ones(shape, dtype=None, order='C')
shape:是一个int或一个int元组,用于定义数组的大小。
dtype:是一个可选参数,默认值为float。 它用于指定数组的数据类型,例如int。
order:该顺序定义是在内存中以行优先(C风格)还是列优先(Fortran风格)顺序存储多维数组。我们不用写,默认即可。
例:k = np.ones((3, 3), np.uint8)
大小为1的(1,1)的小矩阵为一个单位,构成3行3列大矩阵,类型为uint8。(具体干嘛用的,我也不是很清除,猜测大概就是表示图像大小)
2.2.7 cv2.morphologyEx(src, op, kernel)
src:是需要处理的图像。
op:
cv2.MORPH_OPEN:开运算,对图像先进行腐蚀再膨胀,等同于dilate(erode(src,kernal)),开运算对图像的边界进行平滑、去掉凸起等
cv2.MORPH_CLOSE:闭运算,对图像先进行膨胀在腐蚀,等同于erode(dilate(src,kernal)),闭运算用于填充图像内部的小空洞、填充图像的凹陷等
kernel:输入一个数组作为核,表示图像大小。(我也不是很懂)
例 close = cv2.morphologyEx(mask_img, cv2.MORPH_CLOSE, k)
2.2.8 cv2.findContours(image,mode,method)
image :代表输入的图片。注意输入的图片必须为二值图片。若输入的图片为彩色图片,必须先进行灰度化和二值化。
mode : 表示轮廓的检索模式,有4种:
cv2.RETR_EXTERNAL 表示只检测外轮廓。
cv2.RETR_LIST 检测的轮廓不建立等级关系。
cv2.RETR_CCOMP 建立两个等级的轮廓,上面的一层为外边界,里面的一层为内孔的边界信息。如果内孔内还有一个连通物体,这个物体的边界也在顶层。
cv2.RETR_TREE 建立一个等级树结构的轮廓。
method: 为轮廓的近似办法,有4种:
cv2.CHAIN_APPROX_NONE 存储所有的轮廓点,相邻的两个点的像素位置差不超过1,即max(abs(x1-x2),abs(y2-y1))<=1。
cv2.CHAIN_APPROX_SIMPLE 压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标,例如一个矩形轮廓只需4个点来保存轮廓信息。
cv2.CHAIN_APPROX_TC89_L1 和 cv2.CHAIN_APPROX_TC89_KCOS使用teh-Chinl chain 近似算法。
函数返回值contours:返回几个轮廓(返回几个运动物体框框),每个轮廓的单位是点集(即轮廓大小)
例:cnts = cv2.findContours(close_img,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
2.2.9 cv2.contourArea() 求轮廓面积
2.2.10 cv2.boundingRect() 返回轮廓框框坐标
x, y, w, h = cv2.boundingRect(c) ,x,y,w,h为轮廓的坐标长度,c为contours的子集
2.2.11 cv2.rectangle() 坐标连线,框出轮廓
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
图片,长方形框左上角坐标, 长方形框右下角坐标, 字体颜色,字体粗细
2.2.12 cv2.imshow() 窗口显示图像
cv2.imshow("name", img) "name" 为窗口名字,img为窗口显示图像。
三、处理代码
import cv2
import time
import numpy as np
def videos():
cap = cv2.VideoCapture(0)
cap.set(3, 640)
cap.set(4, 480)
cap.set(5,40)
img_num = 0
k = np.ones((3, 3), np.uint8)
while True:
ret, img = cap.read()
if not img_num:
previous = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray_diff = cv2.absdiff(gray, previous)
thresh = cv2.threshold(gray_diff, 40, 255, cv2.THRESH_BINARY)[1]
mask = cv2.medianBlur(thresh, 3)
close = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, k)
cnts = cv2.findContours(close,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)[0]
for c in cnts:
area = cv2.contourArea(c)
if area > 200:
x, y, w, h = cv2.boundingRect(c)
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.imshow("thresh_img", close)
cv2.imshow("Result", img)
img_num += 1
if cv2.waitKey(1) & 0xFF == ord('q'):
break
videos()
左上角因为阳光问题所以出现一点白。