类型 | 算法 | 相关论文 |
---|---|---|
密集光流 | Gunnar-Farneback算法 | Two-Frame Motion Estimation Based on Polynomial Expansion |
# 略修改与注释
import numpy as np
import cv2 as cv
cap = cv.VideoCapture(cv.samples.findFile("test.mp4"))
ret, frame1 = cap.read()
prvs = cv.cvtColor(frame1, cv.COLOR_BGR2GRAY)
hsv = np.zeros_like(frame1)
hsv[..., 1] = 255
while(1):
ret, frame2 = cap.read()
if not ret:
print('No frames grabbed!')
break
next = cv.cvtColor(frame2, cv.COLOR_BGR2GRAY)
flow = cv.calcOpticalFlowFarneback(prvs, next, None, 0.5, 3, 15, 3, 5, 1.2, 0)# 计算光流(只需要前后帧和一些参数即可)
mag, ang = cv.cartToPolar(flow[..., 0], flow[..., 1])# 转为极坐标
# 用hsv矩阵 (480, 640, 3) 保存
hsv[..., 0] = ang*180/np.pi/2
hsv[..., 2] = cv.normalize(mag, None, 0, 255, cv.NORM_MINMAX)
bgr = cv.cvtColor(hsv, cv.COLOR_HSV2BGR)# 转为彩色图像
cv.imshow("original frame", frame2)
cv.imshow('optical vis', bgr)
k = cv.waitKey(30) & 0xff
# if k == 27:
# break
# elif k == ord('s'):
# cv.imwrite('opticalfb.png', frame2)
# cv.imwrite('opticalhsv.png', bgr)
prvs = next
cv.destroyAllWindows()
H参数表示色彩信息,即所处的光谱颜色的位置。该参数用一角度量来表示,红、绿、蓝分别相隔120度。互补色分别相差180度。
纯度S为一比例值,范围从0到1,它表示成所选颜色的纯度和该颜色最大的纯度之间的比率。S=0时,只有灰度。
V表示色彩的明亮程度,范围从0到1。有一点要注意:它和光强度之间并没有直接的联系。
#include
#include
#include
#include
#include
#include
#include //https://blog.csdn.net/weixin_44312186/article/details/89000922
using namespace cv;
using namespace std;
int main()
{
cv::namedWindow("ori", WINDOW_NORMAL);//WINDOW_NORMAL 用户可以改变这个窗口大小
cv::namedWindow("frame2", WINDOW_NORMAL);
VideoCapture capture(samples::findFile("C:\\Users\\admin\\Desktop\\flasktest\\train6001.mp4"));//https://docs.opencv.org/4.x/d6/dba/group__core__utils__samples.html#ga3a33b00033b46c698ff6340d95569c13
if (!capture.isOpened()) {
//error in opening the video input
cerr << "Unable to open file!" << endl;
return 0;
}
Mat frame1, prvs;// https://docs.opencv.org/4.x/d3/d63/classcv_1_1Mat.html
Mat _frame1;
capture >> _frame1;
cv::resize(_frame1, frame1, cv::Size(640, 480), 0, 0, cv::INTER_AREA);//https://stackoverflow.com/questions/17533101/resize-a-matrix-after-created-it-in-opencv
cvtColor(frame1, prvs, COLOR_BGR2GRAY);
while (true) {
Mat frame2, next;
Mat _frame2;
capture >> _frame2;
cv::resize(_frame2, frame2, cv::Size(640, 480), 0, 0, cv::INTER_AREA);
if (frame2.empty())
break;
cvtColor(frame2, next, COLOR_BGR2GRAY);
//计算光流
Mat flow(prvs.size(), CV_32FC2);
calcOpticalFlowFarneback(prvs, next, flow, 0.5, 3, 15, 3, 5, 1.2, 0);
// visualization
Mat flow_parts[2];
split(flow, flow_parts);
Mat magnitude, angle, magn_norm;
cartToPolar(flow_parts[0], flow_parts[1], magnitude, angle, true);
normalize(magnitude, magn_norm, 0.0f, 1.0f, NORM_MINMAX);
angle *= ((1.f / 360.f) * (180.f / 255.f));
//build hsv image
Mat _hsv[3], hsv, hsv8, bgr;
_hsv[0] = angle;
_hsv[1] = Mat::ones(angle.size(), CV_32F);
_hsv[2] = magn_norm;
merge(_hsv, 3, hsv);
hsv.convertTo(hsv8, CV_8U, 255.0);
cvtColor(hsv8, bgr, COLOR_HSV2BGR);
imshow("frame2", bgr);
imshow("ori", next);
int keyboard = waitKey(30);
if (keyboard == 'q' || keyboard == 27)
break;
prvs = next;
}
}
类型 | 算法 | 相关论文 |
---|---|---|
稀疏光流 | Lucas Kanade(LK)算法 | An iterative image registration technique with an application to stereo vision+Generalized Image Matching by the Method of Differences |
# 略修改与注释
import numpy as np
import cv2 as cv
import argparse
parser = argparse.ArgumentParser(description='This sample demonstrates Lucas-Kanade Optical Flow calculation. \
The example file can be downloaded from: \
https://www.bogotobogo.com/python/OpenCV_Python/images/mean_shift_tracking/slow_traffic_small.mp4')
# parser.add_argument('image', type=str, help='path to image file')
parser.add_argument('--image', type=str,default='test.mp4', help='path to image file')
args = parser.parse_args()
cap = cv.VideoCapture(args.image)
# params for ShiTomasi corner detection
feature_params = dict( maxCorners = 100,
qualityLevel = 0.3,
minDistance = 7,
blockSize = 7 )
# Parameters for lucas kanade optical flow
lk_params = dict( winSize = (15, 15),
maxLevel = 2,
criteria = (cv.TERM_CRITERIA_EPS | cv.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 = cv.cvtColor(old_frame, cv.COLOR_BGR2GRAY)
p0 = cv.goodFeaturesToTrack(old_gray, mask = None, **feature_params)
# Create a mask image for drawing purposes
mask = np.zeros_like(old_frame)
while(1):
ret, frame = cap.read()
if not ret:
print('No frames grabbed!')
break
frame_gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
# calculate optical flow
p1, st, err = cv.calcOpticalFlowPyrLK(old_gray, frame_gray, p0, None, **lk_params)
# Select good points
if p1 is not None:
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 = cv.line(mask, (int(a), int(b)), (int(c), int(d)), color[i].tolist(), 2)
frame = cv.circle(frame, (int(a), int(b)), 5, color[i].tolist(), -1)
img = cv.add(frame, mask)
cv.imshow('frame', img)
k = cv.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)
cv.destroyAllWindows()
官方介绍