opencv可以有多有趣
- 前言
- 内容
- 实现
- 成果
前言
这一段时间没怎么写博客,偶尔写一次也是比较正经的博客,感觉自己都不正常了。今天看课的时候突然来了灵感,那就整个烂活玩一玩。
先把视频中的人物边缘找出来,然后再在一张白色底板上绘制出来,再配以rgb的变化,会是什么样的!
来试试吧
内容
首先我们需要一个有人物的视频,建议使用哪些人物和背景区分度比较高的视频。
我么想要完成的功能就是在视频中把一个人的轮廓画出来,然后随着视频一起播放。
接下来就可以聊聊解决思路了。
第一步其实先把图像给整成灰度图,直接使用opencv的cvtColor函数即可
接下来为了方便提取人物的轮廓,我们需要做一下二值处理,这里使用的函数是threshold,这个函数中会设置一个的阈值,当像素值超过这个阈值时,会直接将像素值设置为我们预定的像素值,当小于阈值时,则会将像素值设置为0,这样就可以得到一个二值图像。如下图所示,可以看到轮廓很清晰了
相对于原视频,这个时候的图像已经很清楚的展示出了我们需要的内容,并且很容易就可以提取出轮廓
这之后,再将轮廓画在视频上就可以了,如下图
接下来就可以开始搞代码了
实现
完整代码如下
import numpy as npfrom 图像识别 import picutilsimport cv2# 读取视频cap = cv2.VideoCapture('xxx.mp4')# 设置标志位 超过5就变色m = 0while (1): m += 1 # 颜色数组的下标 l = 0 # 颜色数组 实现rgb变化效果 colos = [[0, 0, 255], [0, 255, 0], [255, 0, 0]] # frame存储每一帧的图像 ret, frame = cap.read() # 转换为灰度图 gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 二值处理 这里的阈值设置为130可能不是最好的,可以试着再改改 超过130就会变255,否则就是0,从而实现二值图像的生成 thresh = cv2.threshold(gray, 200, 255, cv2.THRESH_BINARY)[1] # 边缘检测,检测出边缘方便轮廓提取 edged = cv2.Canny(thresh, 75, 150) # 获取所有的轮廓,这里没有在进行处理,有兴趣可以提取出需要的 cnts = cv2.findContours(edged, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[0] # 选择较大的轮廓 real_cnts=[] for c in cnts: if cv2.arcLength(c,True)>30: real_cnts.append(c) # 设置一个白板图片,作为人物的背景板 back = np.zeros((480, 720, 3), dtype="uint8") + 255 # 展示5帧修改一次颜色数组的下标 l就是下标值 if m == 5: l = (l + 1) % 3 m=0 # 把轮廓绘制在白色的背景板上 cv2.drawContours(back, real_cnts, -1, colos[l], 3) cv2.imshow('frame', back) k = cv2.waitKey(60) & 0xff # 等待退出键,就可以直接退出 if k == 27: breakcap.release()cv2.destroyAllWindows()
成果
成果如下
刚接触opencv做的很粗糙