Python-OpenCV-视频处理

摄像头采集

# 使用照相机

# 参数为电脑的摄像头,0为第一个,1为第二个,以此类推

capture = cv2.VideoCapture(0)

# 使用cv2.VideoWriter_fourcc()确定编/解码的类型

fourcc = cv2.VideoWriter_fourcc(*'XVID')

'''

1.设置要保存的具体文件名;

2.编/解码的类型

3.视频的帧速率

4.视频的长度和宽度

''' 

out=cv2.VideoWriter('test.avi',fourcc, 20, (640,480))

# 使用照相机,等待1ms,若有按键按下,则退出循环,否则再次进入循环

while True:

    # frame 是返回的捕获到的帧,如果没有帧被捕获,则该值为空

    # retval 表示捕获是否成功,如果成功则该值为 True,不成功则为 False

    retval, frame = capture.read()

    cv2.imshow("camera", frame)

    key = cv2.waitKey(1)

    if key != -1:

        break

    else:

        out.write(frame)

# 释放写对象

out.release()

# 释放摄像头对象

capture.release()

# 关闭所有已打开的窗口

cv2.destroyAllWindows()

视频处理

边缘检测示例代码:

# 提取摄像头

cap = cv2.VideoCapture('test.avi')

# 使用cv2.VideoWriter_fourcc()确定编/解码的类型

'''

VideoWriter_fourcc()常见的编码参数

cv2.VideoWriter_fourcc('M', 'P', '4', 'V')  # MPEG-4编码 .mp4 可指定结果视频的大小

cv2.VideoWriter_fourcc('X','2','6','4')     # MPEG-4编码 .mp4 可指定结果视频的大小

cv2.VideoWriter_fourcc('I', '4', '2', '0')  # 该参数是YUV编码类型,文件名后缀为.avi 广泛兼容,但会产生大文件

cv2.VideoWriter_fourcc('P', 'I', 'M', 'I')  # 该参数是MPEG-1编码类型,文件名后缀为.avi

cv2.VideoWriter_fourcc('X', 'V', 'I', 'D')  # 该参数是MPEG-4编码类型,文件名后缀为.avi,可指定结果视频的大小

cv2.VideoWriter_fourcc('T', 'H', 'E', 'O')  # 该参数是Ogg Vorbis,文件名后缀为.ogv

cv2.VideoWriter_fourcc('F', 'L', 'V', '1')  # 该参数是Flash视频,文件名后缀为.flv

'''

fourcc = cv2.VideoWriter_fourcc(*'XVID')

# 获取读入视频的宽和高

width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))

height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

'''

1.设置要保存的具体文件名;

2.编/解码的类型

3.视频的帧速率

4.视频的长度和宽度

5.彩色(true)还是灰色(false)

''' 

out=cv2.VideoWriter('test_边缘检测.avi',fourcc, 20, (width, height),False)



while(cap.isOpened()):

    ret, frame = cap.read()

    if frame is None:

        break

    else:

        cv2.imshow('frame', frame)

        # 边缘检测

        img_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

        img_canny = cv2.Canny(img_gray, 100, 200)

        cv2.imshow('img_canny', img_canny)

        out.write(img_canny)

        key = cv2.waitKey(5)

        if key != -1:

            break

cap.release()

cv2.destroyAllWindows()

角点检测示例代码:

def corner(img):

    # 先转成灰度图

    img_gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

    # 提取特征

    # 500为角点数目最大值;0.1为角点的品质因子;10为两个角点之间最短欧式距离

    corners = cv2.goodFeaturesToTrack(img_gray, 500, 0.1, 10)

    # 处理角点,使用红色实心圆(像素厚度为-1)标记

    for corner in corners:

        x, y = corner.ravel()

        cv2.circle(img, (int(x), int(y)), 3, (255, 0, 255), -1)

    return img

# 提取摄像头

cap = cv2.VideoCapture('test.mp4')

# 使用cv2.VideoWriter_fourcc()确定编/解码的类型

fourcc = cv2.VideoWriter_fourcc(*"mp4v")

# 获取读入视频的宽和高

width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))

height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

out=cv2.VideoWriter('test_角点检测.mp4',fourcc, 20, (width, height))

# 读取视频并处理

while(cap.isOpened()):

    ret, frame = cap.read()

    if frame is None:

        break

    else:

        cv2.imshow('frame', frame)

        img_corners=corner(frame)

        cv2.imshow('img_corners', img_corners)

        out.write(img_corners)

        key = cv2.waitKey(1)

        if key != -1:

            break

cap.release()

cv2.destroyAllWindows()

帧差法检测运动目标

帧差法:对视频图像序列中相邻两帧作差分运算,获得运动目标轮廓。

当视频中出现移动的物体时,帧与帧之间会出现差别,两帧相减,得到两帧图像亮度差的绝对值,判断其是否大于阈值来确定视频中有无物体运动。

帧差法简单、容易实现、时间复杂度较低且对快速移动的目标很敏感,但容易受到光照变化和背景的干扰。

cap = cv2.VideoCapture('test.avi')

# 创建一个椭圆形结构的核

kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (9, 4))

background = None

while True:

    _, frame = cap.read()

    if frame is None:

        break

    # 对帧进行预处理,先转灰度图,再进行高斯滤波

    # 用高斯滤波进行模糊处理,因为视频会因自然震动、光照变化或者摄像头本身等原因而产生噪声

    img_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    img_gs = cv2.GaussianBlur(img_gray, (21, 21), 0)

    # 将第一帧设置为整个输入的背景

    if background is None:

        background = img_gs

        continue

    # 将两幅图像作差,获取差分图,返回与输入数组相同大小和类型的输出数组

    img_diff = cv2.absdiff(background, img_gs)

    # 二值化

    _,img_thre = cv2.threshold(img_diff, 70, 255, cv2.THRESH_BINARY)

    img_erod = cv2.erode(img_thre, kernel, iterations=1)

    # 膨胀,对孔和缺陷进行处理

    img_dila = cv2.dilate(img_erod, kernel, iterations=1)

    # 查找图像轮廓

    '''

    返回值:

        contours:返回的轮廓信息,每个轮廓都是由若干个点所构成的。

        hierarchy:图像的拓扑信息(轮廓层次)。图像内的轮廓可能位于不同的位置。

            比如,一个轮廓在另一个轮廓的内部。在这种情况下,我们将外部的轮廓称为父轮廓,内部的轮廓称为子轮廓。按照上述关系分类,一幅图像中所有轮廓之间就建立了父子关系。

            根据轮廓之间的关系,就能够确定一个轮廓与其他轮廓是如何连接的。

            比如,确定一个轮廓是某个轮廓的子轮廓,或者是某个轮廓的父轮廓。上述关系被称为层次(组织结构),返回值 hierarchy 就包含上述层次关系。

            每个轮廓 contours[i]对应 4 个元素来说明当前轮廓的层次关系。其形式为:[Next,Previous,First_Child,Parent]

                Next:后一个轮廓的索引编号。

                Previous:前一个轮廓的索引编号。

                First_Child:第 1 个子轮廓的索引编号。

                Parent:父轮廓的索引编号。

    参数:

        image:8位单通道二值图像。

        mode:轮廓检索模式。

            cv2.RETR_EXTERNAL:只检测外轮廓。

            cv2.RETR_LIST:对检测到的轮廓不建立等级关系。

            cv2.RETR_CCOMP:检索所有轮廓并将它们组织成两级层次结构。

                上面的一层为外边界,下面的一层为内孔的边界。如果内孔内还有一个连通物体,那么这个物体的边界仍然位于顶层。

            cv2.RETR_TREE:建立一个等级树结构的轮廓。

        method:轮廓的近似方法,决定了如何表达轮廓,可以为如下值:

            cv2.CHAIN_APPROX_NONE:存储所有的轮廓点,相邻两个点的像素位置差不超过 1,即 max(abs(x1-x2),abs(y2-y1))=1。

            cv2.CHAIN_APPROX_SIMPLE:压缩水平方向、垂直方向、对角线方向的元素,只保留该方向的终点坐标。例如,在极端的情况下,一个矩形只需要用 4 个点来保存轮廓信息。

            cv2.CHAIN_APPROX_TC89_L1:使用 teh-Chinl chain 近似算法的一种风格。

            cv2.CHAIN_APPROX_TC89_KCOS:使用 teh-Chinl chain 近似算法的一种风格。

    '''

    contours, hierarchy = cv2.findContours(img_dila.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    for contour in contours:

        # cv2.contourArea()计算轮廓内面积。对于矩形区域,只显示大于给定阈值的轮廓,一些微小的变化也就不会显示。对于光照不变和噪声低的摄像头可不设定轮廓最小尺寸的阈值

        if cv2.contourArea(contour) > 360:

            # 返回包围轮廓的矩形的边界信息(左上角顶点坐标值及矩形宽和高)

            (x, y, w, h) = cv2.boundingRect(contour)

            cv2.rectangle(frame, (x, y), (x+w, y+h), (0,0,255), 2)

cap.release()

cv2.destroyAllWindows()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值