Zi 字媒體
2017-07-25T20:27:27+00:00
fanfuhan OpenCV 教學090 ~ opencv-090-視頻分析(對象移動 偵測/抓取/標記/定位/分析/軌跡繪製)
資料來源: https://fanfuhan.github.io/
https://fanfuhan.github.io/2019/05/08/opencv-090/
GITHUB:https://github.com/jash-git/fanfuhan_ML_OpenCV
移動對象分析,我們可以繪製對象運行軌跡曲線,這個主要是根據移動對象窗口輪廓,獲取中心位置,然後使用中心位置進行替換即可得到。大致的程序步驟如下:
01.初始化路徑點尺寸
02.對每幀的預測輪廓提取中心位置添加到路徑數組
03.繪製路徑曲線
C++
#include "
#include
using namespace cv;
using namespace std;
Mat image;
bool selectObject = false;
int trackObject = 0;
bool showHist = true;
Point origin;
Rect selection;
int vmin = 10, vmax = 256, smin = 30;
int main(int argc, const char** argv)
{
// VideoCapture cap(0);
VideoCapture cap("D:/images/video/balltest.mp4");
Rect trackWindow;
int hsize = 16;
float hranges[] = { 0,180 };
const float* phranges = hranges;
if (!cap.isOpened())
{
printf("could not open camera...\n");
return -1;
}
namedWindow("Histogram", WINDOW_AUTOSIZE);
namedWindow("CamShift Demo", WINDOW_AUTOSIZE);
Mat frame, hsv, hue, mask, hist, histimg = Mat::zeros(200, 320, CV_8UC3), backproj;
bool paused = false;
cap.read(frame);
Rect selection = selectROI("CamShift Demo", frame, true, false);
vector tracking_path;
while (true)
{
bool ret = cap.read(frame);
if (!ret) break;
frame.copyTo(image);
cvtColor(image, hsv, COLOR_BGR2HSV);
int _vmin = vmin, _vmax = vmax;
inRange(hsv, Scalar(26, 43, 46), Scalar(34, 255, 255), mask);
int ch[] = { 0, 0 };
hue.create(hsv.size(), hsv.depth());
mixChannels(&hsv, 1, &hue, 1, ch, 1);
if (trackObject <= 0)
{
// Object has been selected by user, set up CAMShift search properties once
Mat roi(hue, selection), maskroi(mask, selection);
calcHist(&roi, 1, 0, maskroi, hist, 1, &hsize, &phranges);
normalize(hist, hist, 0, 255, NORM_MINMAX);
trackWindow = selection;
trackObject = 1; // Don't set up again, unless user selects new ROI
histimg = Scalar::all(0);
int binW = histimg.cols / hsize;
Mat buf(1, hsize, CV_8UC3);
for (int i = 0; i < hsize; i++)
buf.at(i) = Vec3b(saturate_cast(i*180. / hsize), 255, 255);
cvtColor(buf, buf, COLOR_HSV2BGR);
for (int i = 0; i < hsize; i++)
{
int val = saturate_cast(hist.at(i)*histimg.rows / 255);
rectangle(histimg, Point(i*binW, histimg.rows),
Point((i + 1)*binW, histimg.rows - val),
Scalar(buf.at(i)), -1, 8);
}
}
// Perform CA-MeanShift
calcBackProject(&hue, 1, 0, hist, backproj, &phranges);
backproj &= mask;
RotatedRect trackBox = CamShift(backproj, trackWindow,
TermCriteria(TermCriteria::EPS | TermCriteria::COUNT, 10, 1));
if (trackBox.center.x>0 && trackBox.center.y>0)
tracking_path.push_back(trackBox.center);
ellipse(image, trackBox, Scalar(0, 0, 255), 3, LINE_AA);
for (int i = 1; i < tracking_path.size(); i++) {
line(image, tracking_path[i - 1], tracking_path[i], Scalar(255, 0, 0), 2, 8, 0);
}
imshow("CamShift Demo", image);
imshow("Histogram", histimg);
char c = (char)waitKey(50);
if (c == 27)
break;
}
return 0;
}
Python
"""
视频分析(对象移动轨迹绘制)
"""
import cv2 as cv
import numpy as np
cap = cv.VideoCapture('images/balltest.mp4')
if not cap.isOpened():
print("could not read video")
exit(0)
# 读取第一帧
ret, frame = cap.read()
# 选择ROI区域
x, y, w, h = cv.selectROI("CAM Demo", frame, True, False)
track_window = (x, y, w, h)
# 获取ROI直方图
roi = frame[y:y + h, x:x + w]
hsv_roi = cv.cvtColor(roi, cv.COLOR_BGR2HSV)
mask = cv.inRange(hsv_roi, (26, 43, 46), (34, 255, 255))
roi_hist = cv.calcHist([hsv_roi], [0], mask, [180], [0, 180])
cv.normalize(roi_hist, roi_hist, 0, 255, cv.NORM_MINMAX)
# 搜索跟踪分析
tracking_path = []
term_crit = (cv.TERM_CRITERIA_EPS | cv.TERM_CRITERIA_COUNT, 10, 1)
while True:
ret, frame = cap.read()
if not ret:
break
hsv = cv.cvtColor(frame, cv.COLOR_BGR2HSV)
dst = cv.calcBackProject([hsv], [0], roi_hist, [0, 180], 1)
# 搜索更新roi区域,保持运行轨迹
track_box = cv.CamShift(dst, track_window, term_crit)
track_window = track_box[1]
pt = np.int32(track_box[0][0])
if pt[0] > 0 and pt[1] > 0:
tracking_path.append(pt)
# 绘制窗口
cv.ellipse(frame, track_box[0], (0, 0, 255), 3, 8)
# 绘制运动轨迹
if len(tracking_path) > 40:
tracking_path = tracking_path[-40:-1]
for i in range(1, len(tracking_path)):
cv.line(frame, (tracking_path[i-1][0], tracking_path[i-1][1]),
(tracking_path[i][0], tracking_path[i][1]), (255, 0, 0),
2, 8, 0)
cv.imshow("CAM Demo", frame)
k = cv.waitKey(50) & 0xff
if k == 27:
break
cv.destroyAllWindows()
cap.release()
寫了
5860316篇文章,獲得
23313次喜歡