OpenCV-Python-Tutorial[4]

参考:https://github.com/makelove/OpenCV-Python-Tutorial


ch31-Shi-Tomasi角点检测-适合于跟踪的图像特征

goodFeaturesToTrack.py

# -*- coding:utf-8 -*-
__author__ = 'play4fun'
"""
create time:15-10-29 上午7:52

使用 Shi-Tomasi 方法获取图像中 N 个最好的角点

 常情况下  入的应  是灰度图像。然后确定你想 检测到的 点数目。再 置 点的  水平 0 到 1 之 。它代 了 点的最低   低于 个数的所有 点 会 忽略。最 后在 置两个角点之间的最短欧式距离。

 所有低于  水平的 点  会 忽略。然后再把合格 点按 点     序排列。
 函数会 用 点   最 的 个 点 排序后的第一个  然后将它   最小 离之内 的 点  删掉。
 按着 样的方式最后 回 N 个最佳 点。

 以后会发现这个函数很适合在目标跟踪中使用
"""

import numpy as np
import cv2
from matplotlib import pyplot as plt

# filename = '../data/corner-detection.jpg'
filename = '../data/blox.jpg'
img = cv2.imread(filename)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

corners = cv2.goodFeaturesToTrack(gray, maxCorners=25, qualityLevel=0.01, minDistance=10)

# 返回的结果是 [[ 311., 250.]] 两层括号的数组。
corners = np.int0(corners)
for i in corners:
    x, y = i.ravel()
    cv2.circle(img, (x, y), 3, 255, -1)

plt.imshow(img), plt.show()

ch32-介绍SIFT

sift.py

# -*- coding: utf-8 -*-
# @Time    : 2017/7/13 下午2:23
# @Author  : play4fun
# @File    : sift.py
# @Software: PyCharm

"""
sift.py:尺度不变特征变换

关键点 极值点 定位

"""

import cv2
import numpy as np

img = cv2.imread('../data/home.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

sift = cv2.xfeatures2d.SIFT_create()
kp = sift.detect(gray, None)
img = cv2.drawKeypoints(gray, kp, img)

# 计算关键点描述符
# 使用函数 sift.compute() 来 计算 些关键点的描述符。例如
# kp, des = sift.compute(gray, kp)
kp, des = sift.detectAndCompute(gray,None)

cv2.imwrite('sift_keypoints.jpg', img)
cv2.imshow('sift_keypoints.jpg', img)
cv2.waitKey(0)

ch33-介绍SURF

surf.py

# -*- coding: utf-8 -*-
# @Time    : 2017/7/13 下午3:13
# @Author  : play4fun
# @File    : surf.py
# @Software: PyCharm

"""
surf.py:SURF加速稳健特征,加速版的SIFT

积分图像的一大特点是 计算图像中某个窗 口内所有像素和时,计算量的大小与窗口大小无关

"""
import cv2
import matplotlib.pyplot as plt

img = cv2.imread('../data/butterfly.jpg', 0)
# Create SURF object. You can specify params here or later. # Here I set Hessian Threshold to 400
# surf = cv2.SURF(400)
surf = cv2.xfeatures2d.SURF_create(400)

# Find keypoints and descriptors directly
kp, des = surf.detectAndCompute(img, None)
len(kp)  # 699

# 提高Hessian 的阈值
# Check present Hessian threshold
print(surf.getHessianThreshold())
# 400.0
# We set it to some 50000. Remember, it is just for representing in picture.
# In actual cases, it is better to have a value 300-500
surf.setHessianThreshold(50000)
# Again compute keypoints and check its number.
kp, des = surf.detectAndCompute(img, None)
print(len(kp))
# 47
img2 = cv2.drawKeypoints(img, kp, None, (255, 0, 0), 4)

plt.imshow(img2)
plt.show()

# 最后我们再看看关键点描述符的大小 如果是 64 维的就改成 128 维。

# Find size of descriptor
print(surf.descriptorSize())
# 64
# That means flag, "extended" is False.
print(surf.getExtended())
# False
# So we make it to True to get 128-dim descriptors.
# surf.extended = True
surf.setExtended(True)
kp, des = surf.detectAndCompute(img, None)
print(surf.descriptorSize())
# 128
print(des.shape)
# (47, 128)

# 接下来要做的就是匹配了 我们会在后讨论。

ch34-角点检测的FAST算法

fast.py

# -*- coding: utf-8 -*-
# @Time    : 2017/7/13 下午3:31
# @Author  : play4fun
# @File    : fast.py
# @Software: PyCharm

"""
fast.py:FAST 特征检测器

效果很好。但是从实时处理的角度来看
这些算法 不够快。
一个最好例子就是 SLAM 同步定位与地图构建
移动机器人 它们的计算资源非常有限。

"""

import numpy as np
import cv2
from matplotlib import pyplot as plt

img = cv2.imread('../data/blox.jpg', 0)

# Initiate FAST object with default values
fast = cv2.FastFeatureDetector_create()
# find and draw the keypoints
kp = fast.detect(img, None)
img2 = cv2.drawKeypoints(img, kp, None, color=(255, 0, 0))

# Print all default params
print("Threshold: ", fast.getThreshold())
print("nonmaxSuppression: ", fast.getNonmaxSuppression())
print("neighborhood: ", fast.getType())
print("Total Keypoints with nonmaxSuppression: ", len(kp))
cv2.imwrite('fast_true.png', img2)

# Disable nonmaxSuppression
fast.setNonmaxSuppression(0)
kp = fast.detect(img, None)
print("Total Keypoints without nonmaxSuppression: ", len(kp))

img3 = cv2.drawKeypoints(img, kp, None, color=(255, 0, 0))
cv2.imwrite('fast_false.png', img3)

#结果如下。第一幅图是使用了 非最大值抑制的结果
# 第二幅没有使用非最大值抑制。

ch35-BRIEF

brief.py

# -*- coding: utf-8 -*-
# @Time    : 2017/7/13 下午3:38
# @Author  : play4fun
# @File    : brief.py
# @Software: PyCharm

"""
brief.py:
算法使用的是已经平滑后的图像

非常重要的一点是 BRIEF 是一种特征描述符 它不提供查找特征的方法。 所以我们不得不使用其他特征检测器 比如 SIFT 和 SURF 等。
原始文献推荐 使用 CenSurE 特征检测器  种算法很快。而且 BRIEF 算法对 CenSurE 关键点的描述效果 比 SURF 关键点的描述更好。

简单来  BRIEF 是一种对特征点描述符运算和匹 的快速方法。 这种算法可以实现很高的识别率,除非出现平面内的大旋 。

"""

import numpy as np
import cv2
from matplotlib import pyplot as plt

img = cv2.imread('../data/blox.jpg', 0)

# Initiate FAST detector
star = cv2.xfeatures2d.StarDetector_create()
# Initiate BRIEF extractor
brief = cv2.xfeatures2d.BriefDescriptorExtractor_create()

# find the keypoints with STAR
kp = star.detect(img, None)
# compute the descriptors with BRIEF
kp, des = brief.compute(img, kp)

print(brief.descriptorSize())
print(des.shape)

ch36-ORB

orb.py

# -*- coding: utf-8 -*-
# @Time    : 2017/7/13 下午3:45
# @Author  : play4fun
# @File    : orb.py
# @Software: PyCharm

"""
orb.py:
SIFT 和 SURF 算法是有专利保护的 如果你 使用它们 就可能要花钱 。但是 ORB 不需要

ORB 基本是 FAST 关 点检测和 BRIEF 关 点描 器的结合体 并
 很多修改增强了性能。 先它使用 FAST 找到关 点 然后再使用 Harris  点检测对 些关 点  排序找到其中的前 N 个点。它也使用 字塔从而产 生尺度不变性特征。

 数据的方差大的一个好处是 使得特征更容易分辨。

对于描述符,ORB使用BRIEF描述符。但我们已经看到,这个BRIEF的表现在旋转方面表现不佳。因此,ORB所做的是根据关键点的方向来“引导”。
对于在位置(xi,yi)的n个二进制测试的任何特性集,定义一个包含这些像素坐标的2 n矩阵。然后利用补丁的方向,找到旋转矩阵并旋转S,以得到引导(旋转)版本s。

ORB将角度进行离散化,以增加2/30(12度),并构造一个预先计算过的简短模式的查找表。只要键点的方向是一致的,就会使用正确的点集来计算它的描述符。

BRIEF有一个重要的属性,即每个比特的特性都有很大的方差,而平均值接近0.5。但是一旦它沿着键点方向移动,它就会失去这个属性并变得更加分散。高方差使特征更有区别,因为它对输入的响应不同。另一个可取的特性是让测试不相关,因为每个测试都将对结果有所贡献。为了解决所有这些问题,ORB在所有可能的二进制测试中运行一个贪婪的搜索,以找到那些既有高方差又接近0.5的,同时又不相关的。结果被称为rBRIEF。

对于描述符匹配,在传统的LSH上改进的多探测LSH是被使用的。这篇文章说,ORB比冲浪快得多,而且比冲浪还好。对于全景拼接的低功率设备,ORB是一个不错的选择。

"""

import numpy as np
import cv2
from matplotlib import pyplot as plt

img = cv2.imread('../data/blox.jpg', 0)

# Initiate ORB detector
orb = cv2.ORB_create()
# find the keypoints with ORB
kp = orb.detect(img, None)
# compute the descriptors with ORB
kp, des = orb.compute(img, kp)

# draw only keypoints location,not size and orientation
img2 = cv2.drawKeypoints(img, kp, None, color=(0, 255, 0), flags=0)

plt.imshow(img2), plt.show()

ch37-特征匹配

37.2-对ORB描述符进行蛮力匹配.py

# -*- coding: utf-8 -*-
# @Time    : 2017/7/13 下午4:00
# @Author  : play4fun
# @File    : 37.2-对ORB描述符进行蛮力匹配.py
# @Software: PyCharm

"""
37.2-对ORB描述符进行蛮力匹配.py:
匹配器对象是什么
matches = bf.match(des1, des2) 返回值是一个 DMatch对象列表
DMatch 对 具有下列属性
• DMatch.distance - 描 符之 的 离。 小 好。
• DMatch.trainIdx - 目标图像中描 符的索引。
• DMatch.queryIdx - 查 图像中描 符的索引。
• DMatch.imgIdx - 目标图像的索引。
"""

import numpy as np
import cv2
import matplotlib.pyplot as plt

img1 = cv2.imread('../data/box.png', 0)  # queryImage
img2 = cv2.imread('../data/box_in_scene.png', 0)  # trainImage

# Initiate ORB detector
orb = cv2.ORB_create()
# find the keypoints and descriptors with ORB
kp1, des1 = orb.detectAndCompute(img1, None)
kp2, des2 = orb.detectAndCompute(img2, None)

# create BFMatcher object
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
# Match descriptors.
matches = bf.match(des1, des2)

# Sort them in the order of their distance.
matches = sorted(matches, key=lambda x: x.distance)
# Draw first 10 matches.
# img3 = cv2.drawMatches(img1, kp1, img2, kp2, matches[:10], flags=2)  # 前10个匹配
img3 = cv2.drawMatches(img1, kp1, img2, kp2, matches[:10], None,flags=2)  # 前10个匹配

plt.imshow(img3), plt.show()

37.4-SIFT_match.py

# -*-coding:utf8-*-#
__author__ = 'play4fun'
"""
create time:15-11-9 下午1:28
对 SIFT 描述符进行蛮力匹配和比值测试 
"""

import numpy as np
import cv2
from matplotlib import pyplot as plt

img1 = cv2.imread('../data/box.png', 0)
# queryImage
img2 = cv2.imread('../data/box_in_scene.png', 0)  # trainImage
# Initiate SIFT detector
# sift = cv2.SIFT()
sift = cv2.xfeatures2d.SIFT_create()


# find the keypoints and descriptors with SIFT
kp1, des1 = sift.detectAndCompute(img1, None)
kp2, des2 = sift.detectAndCompute(img2, None)

# BFMatcher with default params
bf = cv2.BFMatcher()
matches = bf.knnMatch(des1, des2, k=2)

# Apply ratio test
# 比值测试,首先获取与 A距离最近的点 B (最近)和 C (次近),
# 只有当 B/C 小于阀值时(0.75)才被认为是匹配,
# 因为假设匹配是一一对应的,真正的匹配的理想距离为0
good = []
for m, n in matches:
    if m.distance < 0.75 * n.distance:
        good.append([m])

# cv2.drawMatchesKnn expects list of lists as matches.
# img3 = np.ndarray([2, 2])
# img3 = cv2.drawMatchesKnn(img1, kp1, img2, kp2, good[:10], img3, flags=2)

# cv2.drawMatchesKnn expects list of lists as matches.
img3 = cv2.drawMatchesKnn(img1,kp1,img2,kp2,good,None,flags=2)

plt.imshow(img3), plt.show()

37.5-FLANN匹配器.py

# -*- coding: utf-8 -*-
# @Time    : 2017/7/13 下午4:22
# @Author  : play4fun
# @File    : 37.5-FLANN匹配器.py
# @Software: PyCharm

"""
37.5-FLANN匹配器.py:
FLANN 是快速最近邻搜索包 Fast_Library_for_Approximate_Nearest_Neighbors 的简称。
它是一个对大数据集和高维特征进行最近邻搜索的算法的集合
 而且这些算法 已经被优化 了。
 在面对大数据集时它的效果 好于 BFMatcher

"""



import numpy as np
import cv2
from matplotlib import pyplot as plt

img1 = cv2.imread('../data/box.png', 0)  # queryImage
img2 = cv2.imread('../data/box_in_scene.png', 0)  # trainImage

# Initiate SIFT detector
# sift = cv2.SIFT()
sift = cv2.xfeatures2d.SIFT_create()

# find the keypoints and descriptors with SIFT
kp1, des1 = sift.detectAndCompute(img1, None)
kp2, des2 = sift.detectAndCompute(img2, None)

# FLANN parameters
FLANN_INDEX_KDTREE = 0
index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5)
search_params = dict(checks=50)  # or pass empty dictionary

flann = cv2.FlannBasedMatcher(index_params, search_params)
matches = flann.knnMatch(des1, des2, k=2)
# Need to draw only good matches, so create a mask
matchesMask = [[0, 0] for i in range(len(matches))]

# ratio test as per Lowe's paper
for i, (m, n) in enumerate(matches):
    if m.distance < 0.7 * n.distance:
        matchesMask[i] = [1, 0]

draw_params = dict(matchColor=(0, 255, 0),
                   singlePointColor=(255, 0, 0),
                   matchesMask=matchesMask,
                   flags=0)

img3 = cv2.drawMatchesKnn(img1, kp1, img2, kp2, matches, None, **draw_params)

plt.imshow(img3, ), plt.show()

ch38-使用特征匹配和单应性查找对象

findHomography.py

# -*- coding: utf-8 -*-
# @Time    : 2017/7/13 下午5:13
# @Author  : play4fun
# @File    : findHomography.py
# @Software: PyCharm

"""
findHomography.py:联合使用特征提取和 calib3d 模块中的 findHomography 在复杂图像中查找已知对象
"""

import numpy as np
import cv2
from matplotlib import pyplot as plt

MIN_MATCH_COUNT = 10
img1 = cv2.imread('../data/box.png', 0)  # queryImage
img2 = cv2.imread('../data/box_in_scene.png', 0)  # trainImage

# Initiate SIFT detector
sift = cv2.xfeatures2d.SIFT_create()
# find the keypoints and descriptors with SIFT
kp1, des1 = sift.detectAndCompute(img1, None)
kp2, des2 = sift.detectAndCompute(img2, None)

FLANN_INDEX_KDTREE = 0
index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5)
search_params = dict(checks=50)
flann = cv2.FlannBasedMatcher(index_params, search_params)
matches = flann.knnMatch(des1, des2, k=2)

# store all the good matches as per Lowe's ratio test.
good = []
for m, n in matches:
    if m.distance < 0.7 * n.distance:
        good.append(m)
'''
现在我们 置只有存在 10 个以上匹 时才去查找目标 MIN_MATCH_COUNT=10   否则显示 告消息  现在匹 不   
如果找到了 够的匹  我们 提取两幅图像中匹 点的坐标。把它们传 入到函数中 算  变换。一旦我们找到 3x3 的变换矩  就可以使用它将查  图像的四个 点 四个  变换到目标图像中去了。然后再绘制出来。
'''

if len(good) > MIN_MATCH_COUNT:
    # 获取关 点的坐标
    src_pts = np.float32([kp1[m.queryIdx].pt for m in good]).reshape(-1, 1, 2)
    dst_pts = np.float32([kp2[m.trainIdx].pt for m in good]).reshape(-1, 1, 2)

    # 第三个参数 Method used to computed a homography matrix. The following methods are possible: #0 - a regular method using all the points
    # CV_RANSAC - RANSAC-based robust method
    # CV_LMEDS - Least-Median robust method
    # 第四个参数取值范围在 1 到 10  绝一个点对的 值。原图像的点经 变换后点与目标图像上对应点的 差 #    差就 为是 outlier
    #  回值中 M 为变换矩 。
    M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)
    matchesMask = mask.ravel().tolist()
    # 获得原图像的高和宽
    h, w = img1.shape
    # 使用得到的变换矩 对原图像的四个   变换 获得在目标图像上对应的坐标
    pts = np.float32([[0, 0], [0, h - 1], [w - 1, h - 1], [w - 1, 0]]).reshape(-1, 1, 2)
    dst = cv2.perspectiveTransform(pts, M)
    # 原图像为灰度图
    img2 = cv2.polylines(img2, [np.int32(dst)], True, 255, 3, cv2.LINE_AA)
else:
    print("Not enough matches are found - %d/%d" % (len(good), MIN_MATCH_COUNT))
    matchesMask = None

# 最后我再绘制 inliers 如果能成功的找到目标图像的话  或者匹配的关  点 如果失败。
draw_params = dict(matchColor=(0, 255, 0),  # draw matches in green color
                   singlePointColor=None,
                   matchesMask=matchesMask,  # draw only inliers
                   flags=2)

img3 = cv2.drawMatches(img1, kp1, img2, kp2, good, None, **draw_params)

plt.imshow(img3, 'gray'), plt.show()
# 复杂图像中被找到的目标图像被标记成白色

ch39-视频分析-Meanshift和Camshift

Camshift.py

# -*- coding: utf-8 -*-
# @Time    : 2017/7/13 下午5:56
# @Author  : play4fun
# @File    : Camshift.py
# @Software: PyCharm

"""
Camshift.py:
"""

import numpy as np
import cv2

cap = cv2.VideoCapture('../data/slow.flv')
# take first frame of the video
ret, frame = cap.read()

# setup initial location of window
r, h, c, w = 250, 90, 400, 125  # simply hardcoded the values
track_window = (c, r, w, h)
# set up the ROI for tracking
roi = frame[r:r + h, c:c + w]
hsv_roi = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv_roi, np.array((0., 60., 32.)), np.array((180., 255., 255.)))
roi_hist = cv2.calcHist([hsv_roi], [0], mask, [180], [0, 180])
cv2.normalize(roi_hist, roi_hist, 0, 255, cv2.NORM_MINMAX)
# Setup the termination criteria, either 10 iteration or move by atleast 1 pt
term_crit = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 1)

while True:
    ret, frame = cap.read()
    if ret is True:
        hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
        dst = cv2.calcBackProject([hsv], [0], roi_hist, [0, 180], 1)
        # apply meanshift to get the new location
        ret, track_window = cv2.CamShift(dst, track_window, term_crit)
        # Draw it on image
        pts = cv2.boxPoints(ret)
        pts = np.int0(pts)
        print('len pts:', len(pts),pts)
        img2 = cv2.polylines(frame, [pts], True, (255, 0, 0), 2)

        cv2.imshow('img2', img2)
        k = cv2.waitKey(1)  # & 0xff
        if k == 27:
            break
            # else:
            #     cv2.imwrite(chr(k) + ".jpg", img2)
    else:
        break
cv2.destroyAllWindows()
cap.release()

Meanshift.py

# -*- coding: utf-8 -*-
# @Time    : 2017/7/13 下午5:27
# @Author  : play4fun
# @File    : Meanshift.py
# @Software: PyCharm

"""
Meanshift.py:

问题:我们的窗口的大小是固 定的
而汽车由远及近 在视觉上 是一个 渐变大的过程
固定的窗口是不 合适的。所以我们需要根据目标的大小和角度来对窗口的大小和角度进行修订

http://docs.opencv.org/3.2.0/db/df8/tutorial_py_meanshift.html
"""

import numpy as np
import cv2

cap = cv2.VideoCapture('../data/slow.flv')

# take first frame of the video
ret, frame = cap.read()
# setup initial location of window
r, h, c, w = 250, 90, 400, 125  # simply hardcoded the values
track_window = (c, r, w, h)
# set up the ROI for tracking
roi = frame[r:r + h, c:c + w]
hsv_roi = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV)
# 将低亮度的值忽略掉
mask = cv2.inRange(hsv_roi, np.array((0., 60., 32.)), np.array((180., 255., 255.)))
roi_hist = cv2.calcHist([hsv_roi], [0], mask, [180], [0, 180])

cv2.normalize(roi_hist, roi_hist, 0, 255, cv2.NORM_MINMAX)

# Setup the termination criteria, either 10 iteration or move by atleast 1 pt
term_crit = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 1)

while True:
    ret, frame = cap.read()
    if ret is True:
        hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
        dst = cv2.calcBackProject([hsv], [0], roi_hist, [0, 180], 1)
        # apply meanshift to get the new location
        ret, track_window = cv2.meanShift(dst, track_window, term_crit)

        # Draw it on image
        x, y, w, h = track_window
        print(track_window)
        img2 = cv2.rectangle(frame, (x, y), (x + w, y + h), 255, 2)
        cv2.imshow('img2', img2)


        k = cv2.waitKey(60)  # & 0xff
        if k == 27:
            break
            # else:
            #     cv2.imwrite(chr(k) + ".jpg", img2)
    else:
        break
cv2.destroyAllWindows()
cap.release()
#不正常

ch40-光流

40.3-Lucas-Kanade-光流calcOpticalFlowPyrLK.py

# -*- coding: utf-8 -*-
# @Time    : 2017/7/13 下午5:59
# @Author  : play4fun
# @File    : calcOpticalFlowPyrLK.py
# @Software: PyCharm

"""
calcOpticalFlowPyrLK.py:
由于目标对象或者摄像机的移动造成的图像对象在 续两帧图像中的移动 被称为光流。
它是一个 2D 向量场 可以用来显示一个点从第一帧图像到第二 帧图像之间的移动。
光 流在很多领域中都很有用
• 由运动重建结构
• 视频压缩
• Video Stabilization 等
"""

import numpy as np
import cv2

cap = cv2.VideoCapture('../data/slow.flv')

# params for ShiTomasi corner detection
feature_params = dict(maxCorners=100,
                      qualityLevel=0.3,
                      minDistance=7,
                      blockSize=7)
# Parameters for lucas kanade optical flow
# maxLevel 为使用的图像金字塔层数
lk_params = dict(winSize=(15, 15),
                 maxLevel=2,
                 criteria=(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))
# Create some random colors
color = np.random.randint(0, 255, (100, 3))

# Take first frame and find corners in it
ret, old_frame = cap.read()
old_gray = cv2.cvtColor(old_frame, cv2.COLOR_BGR2GRAY)
p0 = cv2.goodFeaturesToTrack(old_gray, mask=None, **feature_params)
# Create a mask image for drawing purposes
mask = np.zeros_like(old_frame)

while True:
    ret, frame = cap.read()
    frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    # calculate optical flow能够获取点的新位置
    p1, st, err = cv2.calcOpticalFlowPyrLK(old_gray, frame_gray, p0, None, **lk_params)
    # Select good points
    good_new = p1[st == 1]
    good_old = p0[st == 1]
    # draw the tracks
    for i, (new, old) in enumerate(zip(good_new, good_old)):
        a, b = new.ravel()
        c, d = old.ravel()
        mask = cv2.line(mask, (a, b), (c, d), color[i].tolist(), 2)
        frame = cv2.circle(frame, (a, b), 5, color[i].tolist(), -1)
    img = cv2.add(frame, mask)
    cv2.imshow('frame', img)

    k = cv2.waitKey(30) #& 0xff
    if k == 27:
        break
    # Now update the previous frame and previous points
    old_gray = frame_gray.copy()
    p0 = good_new.reshape(-1, 1, 2)

cv2.destroyAllWindows()
cap.release()

40.4-OpenCV中的稠密光流.py

# -*- coding: utf-8 -*-
# @Time    : 2017/7/13 下午6:08
# @Author  : play4fun
# @File    : 40.4-OpenCV中的稠密光流.py
# @Software: PyCharm

"""
40.4-OpenCV中的稠密光流.py:
"""

import cv2
import numpy as np

cap = cv2.VideoCapture("../data/vtest.avi")
# cap = cv2.VideoCapture("../data/slow.flv")
ret, frame1 = cap.read()

prvs = cv2.cvtColor(frame1, cv2.COLOR_BGR2GRAY)
hsv = np.zeros_like(frame1)
hsv[..., 1] = 255

while True:
    ret, frame2 = cap.read()
    next = cv2.cvtColor(frame2, cv2.COLOR_BGR2GRAY)
    flow = cv2.calcOpticalFlowFarneback(prvs, next, None, 0.5, 3, 15, 3, 5, 1.2, 0)
    mag, ang = cv2.cartToPolar(flow[..., 0], flow[..., 1])
    hsv[..., 0] = ang * 180 / np.pi / 2
    hsv[..., 2] = cv2.normalize(mag, None, 0, 255, cv2.NORM_MINMAX)
    bgr = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)

    cv2.imshow('frame2', frame2)
    cv2.imshow('flow', bgr)
    k = cv2.waitKey(1) & 0xff
    if k == 27:
        break
    elif k == ord('s'):
        cv2.imwrite('opticalfb.png', frame2)
        cv2.imwrite('opticalhsv.png', bgr)
    prvs = next

cap.release()
cv2.destroyAllWindows()
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值