opencv-CAMshift对象跟踪

MeanShift算法介绍

在这里插入图片描述

CAMshift跟踪算法介绍

我们通常会传递直方图反投影图像和初始目标位置。当对象移动时,显然该移动会反映在直方图反投影图像中。结果,meanshift算法将窗口移动到最大密度的新位置。

  1. 连续自适应的Meanshift跟踪算法
  2. 窗口尺寸自动变化
  3. 适合变形目标检测
    在这里插入图片描述

代码演示


#include <opencv2/opencv.hpp>

#include <iostream>
#include <math.h>

using namespace cv;
using namespace std;

int smin = 15;
int vmin = 40;
int vmax = 256;
int bins = 16;
int main(int argc, char** argv) {
	VideoCapture capture;
	capture.open("D:/wv_demo.mp4");
	if (!capture.isOpened()) {
		printf("could not find video data file...\n");
		return -1;
	}
	namedWindow("CAMShift Tracking", WINDOW_AUTOSIZE);
	namedWindow("ROI Histogram", WINDOW_AUTOSIZE);

	bool firstRead = true;
	float hrange[] = { 0, 180 };
	const float* hranges = hrange;
	Rect selection;
	Mat frame, hsv, hue, mask, hist, backprojection;
	Mat drawImg = Mat::zeros(300, 300, CV_8UC3);
	while (capture.read(frame)) {
		if (firstRead) {
			Rect2d first = selectROI("CAMShift Tracking", frame);
			selection.x = first.x;
			selection.y = first.y;
			selection.width = first.width;
			selection.height = first.height;
			printf("ROI.x= %d, ROI.y= %d, width = %d, height= %d", selection.x, selection.y, selection.width, selection.height);
		}
		// convert to HSV
		cvtColor(frame, hsv, COLOR_BGR2HSV);
		inRange(hsv, Scalar(0, smin, vmin), Scalar(180, vmax, vmax), mask);
		hue = Mat(hsv.size(), hsv.depth());
		int channels[] = { 0, 0 };
		mixChannels(&hsv, 1, &hue, 1, channels, 1);

		if (firstRead) {
			// ROI 直方图计算
			Mat roi(hue, selection);
			Mat maskroi(mask, selection);
			calcHist(&roi, 1, 0, maskroi, hist, 1, &bins, &hranges);
			normalize(hist, hist, 0, 255, NORM_MINMAX);

			// show histogram
			int binw = drawImg.cols / bins;
			Mat colorIndex = Mat(1, bins, CV_8UC3);
			for (int i = 0; i < bins; i++) {
				colorIndex.at<Vec3b>(0, i) = Vec3b(saturate_cast<uchar>(i * 180 / bins), 255, 255);
			}
			cvtColor(colorIndex, colorIndex, COLOR_HSV2BGR);
			for (int i = 0; i < bins; i++) {
				int  val = saturate_cast<int>(hist.at<float>(i) * drawImg.rows / 255);
				rectangle(drawImg, Point(i * binw, drawImg.rows), Point((i + 1) * binw, drawImg.rows - val), Scalar(colorIndex.at<Vec3b>(0, i)), -1, 8, 0);
			}
		}

		// back projection
		calcBackProject(&hue, 1, 0, hist, backprojection, &hranges);
		// CAMShift tracking
		backprojection &= mask;
		RotatedRect trackBox = CamShift(backprojection, selection, TermCriteria((TermCriteria::COUNT | TermCriteria::EPS), 10, 1));

		// draw location on frame;
		ellipse(frame, trackBox, Scalar(0, 0, 255), 3, 8);

		if (firstRead) {
			firstRead = false;
		}
		imshow("CAMShift Tracking", frame);
		imshow("ROI Histogram", drawImg);
		char c = waitKey(50);// ESC
		if (c == 27) {
			break;
		}
	}

	capture.release();
	waitKey(0);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值