fanfuhan OpenCV 教學090 ~ opencv-090-視頻分析(對象移動 偵測/抓取/標記/定位/分析/軌跡繪製)

fanfuhan OpenCV 教學090 ~ opencv-090-視頻分析(對象移動 偵測/抓取/標記/定位/分析/軌跡繪製)

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 <opencv2/opencv.hpp>"
#include <iostream>

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<Point> 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<Vec3b>(i) = Vec3b(saturate_cast<uchar>(i*180. / hsize), 255, 255);
			cvtColor(buf, buf, COLOR_HSV2BGR);

			for (int i = 0; i < hsize; i++)
			{
				int val = saturate_cast<int>(hist.at<float>(i)*histimg.rows / 255);
				rectangle(histimg, Point(i*binW, histimg.rows),
					Point((i + 1)*binW, histimg.rows - val),
					Scalar(buf.at<Vec3b>(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()

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *