C++实现目标微小运动的检测和跟踪通过meanshift、camshift方法_百度文...

C++实现⽬标微⼩运动的检测和跟踪通过meanshift、camshift
⽅法
meanshift跟踪算法:
meanshift算法⽤于视觉跟踪时,将基于前⼀图像中的对象的颜⾊直⽅图在新图像中创建置信度图,并使⽤均值平移来到靠近对象旧位置的置信度图的峰值。 置信度图是新图像上的概率密度函数,为新图像的每个像素指定⼀个概率,该概率是前⼀图像中的对象中出现的像素颜⾊的概率。
meanshift跟踪算法步骤:
① 选择搜索窗⼝,包括窗⼝的初始位置、⼤⼩、形状(对称或歪斜,矩形或圆⼼)、类型(均匀、多项式、指数或⾼斯);
② 计算窗⼝的重⼼;
③ 将窗⼝的中⼼设置在计算出的重⼼处;
④ 返回②步,直到窗⼝位置不再变化。
计算⾊彩投影图(反向投影)
(1)为了减少光照变化对⽬标跟踪的影响,⾸先将图像从RGB颜⾊空间转换到HSV颜⾊空间;
(2)对H分量进⾏直⽅图统计,直⽅图代表了不同H分量取值出现的概率,或者说可以据此查出H分量的⼤⼩为x时的概率或像素个数,即,得到颜⾊概率查表;
(3)将图像中每个像素的值⽤其颜⾊出现的概率进⾏替换,由此得到颜⾊概率分布图;
以上三个步骤称之为反向投影,需要提醒的是,颜⾊概率分布图是⼀个灰度图像;
meanshift寻优
前⾯提到过meanShift算法是⼀种⾮参数概率密度估计⽅法,它通过不断迭代计算得到最优搜索窗⼝的位置和⼤⼩。
camshift跟踪算法
前⾯提到,camshift其实就是在视频序列的每⼀帧当中都运⽤meanShift,并将上⼀帧的meanshift结果作为下⼀帧的初始值,如此不断循环迭代,就可以实现⽬标的跟踪了。
meanshift:
#include "core/core.hpp"
#include "highgui/highgui.hpp"
#include "imgproc/imgproc.hpp"
#include "video/tracking.hpp"
#include<iostream>
using namespace cv;
using namespace std;
Mat image;
Mat rectImage;
Mat imageCopy; //绘制矩形框时⽤来拷贝原图的图像
bool leftButtonDownFlag = false; //左键单击后视频暂停播放的标志位
Point originalPoint; //矩形框起点
Point processPoint; //矩形框终点
Mat targetImageHSV;
int histSize = 200;
float histR[] = { 0,255 };
const float *histRange = histR;
int channels[] = { 0,1 };
Mat dstHist;
Rect rect;
vector<Point> pt; //保存⽬标轨迹
vector<Point> pt; //保存⽬标轨迹
void onMouse(int event, int x, int y, int flags, void* ustc); //⿏标回调函数
int main(int argc, char*argv[])
{
VideoCapture video;
image = video.open("D:/testimage/CXK.avi");
//VideoCapture video(0);
//double fps = (CAP_PROP_FPS); //获取视频帧率
//double pauseTime = 1000 / fps; //两幅画⾯中间间隔
namedWindow("⽬标跟踪", 0);
setMouseCallback("⽬标跟踪", onMouse);
while (ad(image))//(true)
{
int k = waitKey(30);
if (!leftButtonDownFlag) //判定⿏标左键没有按下,采取播放视频,否则暂停
{
//video >> image;
}
if (leftButtonDownFlag) //判定⿏标左键没有按下,采取播放视频,否则暂停
{
//while (waitKey(0) != 32)
waitKey(0);
}
//if (!image.data || waitKey(pauseTime) == 27)  //图像为空或Esc键按下退出播放
//{
// break;
//}
if (originalPoint != processPoint && !leftButtonDownFlag)
{
Mat imageHSV;
Mat calcBackImage;
cvtColor(image, imageHSV, COLOR_RGB2HSV);
calcBackProject(&imageHSV, 2, channels, dstHist, calcBackImage, &histRange);  //反向投影  TermCriteria criteria(TermCriteria::MAX_ITER + TermCriteria::EPS, 1000, 0.001);
meanShift(calcBackImage, rect, criteria);
Mat imageROI = imageHSV(rect);  //更新模板
targetImageHSV = imageHSV(rect);
calcHist(&imageROI, 2, channels, Mat(), dstHist, 1, &histSize, &histRange);
normalize(dstHist, dstHist, 0.0, 1.0, NORM_MINMAX);  //归⼀化
rectangle(image, rect, Scalar(0, 0, 255), 3);  //⽬标绘制
pt.push_back(Point(rect.x + rect.width / 2, rect.y + rect.height / 2));
for (int i = 0; i<pt.size() - 1; i++)
{
line(image, pt[i], pt[i + 1], Scalar(0, 255, 0), 2.5);
}
}
imshow("⽬标跟踪", image);
waitKey(100);
}
return 0;
}
//*******************************************************************//
//⿏标回调函数
void onMouse(int event, int x, int y, int flags, void *ustc)
{
if (event == EVENT_LBUTTONDOWN)
{
leftButtonDownFlag = true; //标志位
originalPoint = Point(x, y);  //设置左键按下点的矩形起点
processPoint = originalPoint;
}
if (event == EVENT_MOUSEMOVE && leftButtonDownFlag)
{
imageCopy = image.clone();
processPoint = Point(x, y);
if (originalPoint != processPoint)
{
//在复制的图像上绘制矩形
rectangle(imageCopy, originalPoint, processPoint, Scalar(0, 0, 255), 2);
}
imshow("⽬标跟踪", imageCopy);
}
if (event == EVENT_LBUTTONUP)
{
leftButtonDownFlag = false;
rect = Rect(originalPoint, processPoint);
rectImage = image(rect); //⼦图像显⽰
imshow("Sub Image", rectImage);
cvtColor(rectImage, targetImageHSV, COLOR_RGB2HSV);
imshow("targetImageHSV", targetImageHSV);
calcHist(&targetImageHSV, 2, channels, Mat(), dstHist, 1, &histSize, &histRange, true, false);  normalize(dstHist, dstHist, 0, 255, NORM_MINMAX);
imshow("dstHist", dstHist);
}
}
camshift:
#include<opencv2/opencv.hpp>
#include<opencv2/tracking.hpp>
using namespace cv;
int main()
{
VideoCapture capture;
Mat frame;
//保存⽬标轨迹
//保存⽬标轨迹
std::vector<Point> pt;
/
/capture.open(0);
frame = capture.open("D:/testimage/video/fish.mp4");
if (!capture.isOpened())
{
printf("can not open camera \n");
return -1;
}
namedWindow("input", WINDOW_AUTOSIZE);
namedWindow("output", WINDOW_AUTOSIZE);
dst指数
if (pty())
return -1;
Rect2d first = selectROI("output", frame);
Rect selectionROI;
selectionROI.width = first.width;
selectionROI.height = first.height;
selectionROI.x = first.x;
selectionROI.y = first.y;
printf("x= %d, y=%d, width=%d, height=%d", selectionROI.x, selectionROI.y, selectionROI.width, selectionROI.height);
Mat mask, hist, backproject;
int bins = 120;
Mat drawImg = Mat::zeros(300, 300, CV_8UC3);
while (ad(frame))
{
Mat hsvimage;
cvtColor(frame, hsvimage, CV_BGR2HSV);
inRange(hsvimage, Scalar(25, 43, 46), Scalar(35, 256, 256), mask);
Mat hue = Mat(hsvimage.size(), hsvimage.depth());
int channels[] = { 0, 0 };
mixChannels(&hsvimage, 1, &hue, 1, channels, 1);
//ROI直⽅图计算
Mat roi(hue, first);
Mat maskroi(mask, first);
float hrange[] = { 0, 180 };
const float* hranges = hrange;
//直⽅图
calcHist(&roi, 1, 0, maskroi, hist, 1, &bins, &hranges);
normalize(hist, hist, 0, 255, NORM_MINMAX);
int binw = ls / 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)*ws / 255);
rectangle(drawImg, Point(i*binw, ws), Point((i + 1)*binw, ws * val), Scalar(colorIndex.at<Vec3b>(0, i)), -1, 8, 0);  }
//计算直⽅图的反投影
calcBackProject(&hue, 1, 0, hist, backproject, &hranges);
backproject &= mask;
RotatedRect trackBox = CamShift(backproject, selectionROI, TermCriteria((TermCriteria::COUNT | TermCriteria::EPS), 10, 1));
Rect rect;
rect.x = x - trackBox.size.width / 2.0;
rect.y = y - trackBox.size.height / 2.0;
rect.width = trackBox.size.width;
rect.width = trackBox.size.width;
rect.height = trackBox.size.height;
rectangle(frame, rect, Scalar(255, 255, 0), 3);
pt.push_back(Point(rect.x + rect.width / 2, rect.y + rect.height / 2));  for (int i = 0; i<pt.size() - 1; i++)
{
line(frame, pt[i], pt[i + 1], Scalar(0, 255, 0), 2.5);
}
imshow("input", frame);
imshow("output", drawImg);
waitKey(10);
}
return 0;
}

本文发布于:2024-09-22 08:30:18,感谢您对本站的认可!

本文链接:https://www.17tex.com/tex/1/380017.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:图像   概率   跟踪   视频   位置   得到
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议