camshift一般使用颜色直方图进行匹配,而红外视频为灰度图像,一般彩色RGB到灰度图像转换公式如下:
#include "opencv2/video/tracking.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include
#include
using namespace cv;
using namespace std;
Mat image;
bool backprojMode = false;
bool selectObject = false;
int trackObject = 0;
bool showHist = true;
Point origin;
Rect selection;
int vmin = 10, vmax = 256, smin = 30;
static void onMouse(int event, int x, int y, int, void*)
{
if (selectObject)
{
selection.x = MIN(x, origin.x);
selection.y = MIN(y, origin.y);
selection.width = std::abs(x - origin.x);
selection.height = std::abs(y - origin.y);
selection &= Rect(0, 0, image.cols, image.rows);
}
switch (event)
{
case CV_EVENT_LBUTTONDOWN:
origin = Point(x, y);
selection = Rect(x, y, 0, 0);
selectObject = true;
break;
case CV_EVENT_LBUTTONUP:
selectObject = false;
if (selection.width > 0 && selection.height > 0)
trackObject = -1;
break;
}
}
static void help()
{
cout << "\nThis is a demo that shows mean-shift based tracking\n"
"You select a color objects such as your face and it tracks it.\n"
"This reads from video camera (0 by default, or the camera number the user enters\n"
"Usage: \n"
" ./camshiftdemo [camera number]\n";
cout << "\n\nHot keys: \n"
"\tESC - quit the program\n"
"\tc - stop the tracking\n"
"\tb - switch to/from backprojection view\n"
"\th - show/hide object histogram\n"
"\tp - pause video\n"
"To initialize tracking, select the object with mouse\n";
}
const char* keys =
{
"{1| | 0 | camera number}"
};
int main(int argc, const char** argv)
{
help();
VideoCapture cap;
VideoCapture capture("C:/Users/Administrator/Desktop/camshift/camshift/Debug/example.mp4");
Rect trackWindow;
int hsize = 16;
float hranges[] = { 0, 180 };
const float* phranges = hranges;
CommandLineParser parser(argc, argv, keys);
int camNum = parser.get("1");
cap.open(camNum);
if (!cap.isOpened())
{
help();
cout << "***Could not initialize capturing...***\n";
cout << "Current parameter's value: \n";
parser.printParams();
return -1;
}
namedWindow("Histogram", 0);
namedWindow("CamShift Demo", 0);
namedWindow("CamShift", 0);
setMouseCallback("CamShift Demo", onMouse, 0);
createTrackbar("Vmin", "CamShift Demo", &vmin, 256, 0);
createTrackbar("Vmax", "CamShift Demo", &vmax, 256, 0);
createTrackbar("Smin", "CamShift Demo", &smin, 256, 0);
Mat frame, hsv, hue, mask, hist, histimg = Mat::zeros(200, 320, CV_8UC3), backproj;
bool paused = false;
for (;;)
{
if (!paused)
{
capture >> frame;
if (frame.empty())
break;
}
frame.copyTo(image);
/////////
//cvtColor(frame, test, COLOR_GRAY2BGR);
Mat test(image.rows, image.cols, CV_8UC3);//RGB图像
Mat test_grey;
cvtColor(image, test_grey, COLOR_BGR2GRAY);
int tmp = 0;
Mat img;
cvtColor(image, img, COLOR_BGR2GRAY);
Mat img_color(image.rows, image.cols, CV_8UC3);//构造RGB图像
#define IMG_B(img,y,x)img.at(y,x)[0]
#define IMG_G(img,y,x)img.at(y,x)[1]
#define IMG_R(img,y,x)img.at(y,x)[2]
uchar tmp2 = 0;
for (int y = 0; y(y, x);
if (tmp2 <= 51)
{
IMG_B(img_color, y, x) = 255;
IMG_G(img_color, y, x) = tmp2 * 5;
IMG_R(img_color, y, x) = 0;
}
else if(tmp2 <= 102)
{
tmp2 -= 51;
IMG_B(img_color, y, x) = 255 - tmp2 * 5;
IMG_G(img_color, y, x) = 255;
IMG_R(img_color, y, x) = 0;
}
else if(tmp2 <= 153)
{
tmp2 -= 102;
IMG_B(img_color, y, x) = 0;
IMG_G(img_color, y, x) = 255;
IMG_R(img_color, y, x) = tmp2 * 5;
}
else if(tmp2 <= 204)
{
tmp2 -= 153;
IMG_B(img_color, y, x) = 0;
IMG_G(img_color, y, x) = 255 - uchar(128.0*tmp2 / 51.0 + 0.5);
IMG_R(img_color, y, x) = 255;
}
else
{
tmp2 -= 204;
IMG_B(img_color, y, x) = 0;
IMG_G(img_color, y, x) = 127 - uchar(127.0*tmp2 / 51.0 + 0.5);
IMG_R(img_color, y, x) = 255;
}
}
}
imshow("CamShift", image);
image = img_color;
////////
if (!paused)
{
cvtColor(image, hsv, COLOR_BGR2HSV);
if (trackObject)
{
int _vmin = vmin, _vmax = vmax;
inRange(hsv, Scalar(0, smin, MIN(_vmin, _vmax)),
Scalar(180, 256, MAX(_vmin, _vmax)), mask);
int ch[] = { 0, 0 };
hue.create(hsv.size(), hsv.depth());
mixChannels(&hsv, 1, &hue, 1, ch, 1);
if (trackObject < 0)
{
Mat roi(hue, selection), maskroi(mask, selection);
calcHist(&roi, 1, 0, maskroi, hist, 1, &hsize, &phranges);
normalize(hist, hist, 0, 255, CV_MINMAX);
trackWindow = selection;
trackObject = 1;
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, CV_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);
}
}
calcBackProject(&hue, 1, 0, hist, backproj, &phranges);
backproj &= mask;
RotatedRect trackBox = CamShift(backproj, trackWindow,
TermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 10, 1));
if (trackWindow.area() <= 1)
{
int cols = backproj.cols, rows = backproj.rows, r = (MIN(cols, rows) + 5) / 6;
trackWindow = Rect(trackWindow.x - r, trackWindow.y - r,
trackWindow.x + r, trackWindow.y + r) &
Rect(0, 0, cols, rows);
}
if (backprojMode)
cvtColor(backproj, image, COLOR_GRAY2BGR);
ellipse(image, trackBox, Scalar(0, 0, 255), 3, CV_AA);
}
}
else if (trackObject < 0)
paused = false;
if (selectObject && selection.width > 0 && selection.height > 0)
{
Mat roi(image, selection);
bitwise_not(roi, roi);
}
imshow("CamShift Demo", image);
imshow("Histogram", histimg);
char c = (char)waitKey(10);
if (c == 27)
break;
switch (c)
{
case 'b':
backprojMode = !backprojMode;
break;
case 'c':
trackObject = 0;
histimg = Scalar::all(0);
break;
case 'h':
showHist = !showHist;
if (!showHist)
destroyWindow("Histogram");
else
namedWindow("Histogram", 1);
break;
case 'p':
paused = !paused;
break;
default:
;
}
}
return 0;
}