我一直在修改我一直关注的教程:
https://www.youtube.com/watch?v=RS_uQGOQIdg
本教程介绍如何通过相机使用OpenCV进行多个对象跟踪,但是在Windows上。我在我的Pi中做到了这一点并且工作正常,它应该如何。现在,我正在努力使其适应我正在工作的项目。
我正在进行的这个项目旨在追踪农场中鸡的运动,并根据它们的坐标我们将分析白天的运动,并用许多其他因素(温度,水分,食物)研究它们的行为等等。)
不同之处在于,现在我想每隔10分钟跟踪我的Raspicam拍摄的照片,以减少处理和不必要的数据。对我来说问题是我不太了解C ++,所以我需要你的帮助,因为我被卡住了。
有一个校准模式,它是我可以查找我想要跟踪的颜色的模块,当它开启时我可以正常跟踪鸡(它们的坐标出现在图像中) 。由于我已经知道这些颜色,我不再需要它,所以我把它关掉了。当我这样做时,跟踪停止工作。这是你的主要文件,现在对旧代码进行了评论,你可以看到我一直在努力调整的内容:
//objectTrackingTutorial.cpp
#include <sstream>
#include <string>
#include <iostream>
#include <vector>
#include "Chicken.h"
//initial min and max HSV filter values.
//these will be changed using trackbars
int H_MIN = 0;
int H_MAX = 256;
int S_MIN = 0;
int S_MAX = 256;
int V_MIN = 0;
int V_MAX = 256;
//default capture width and height
const int FRAME_WIDTH = 640;
const int FRAME_HEIGHT = 480;
//max number of objects to be detected in frame
const int MAX_NUM_OBJECTS=50;
//minimum and maximum object area
const int MIN_OBJECT_AREA = 20*20;
const int MAX_OBJECT_AREA = FRAME_HEIGHT*FRAME_WIDTH/1.5;
//names that will appear at the top of each window
const string windowName = "Original Image";
const string windowName1 = "HSV Image";
const string windowName2 = "Thresholded Image";
const string windowName3 = "After Morphological Operations";
const string trackbarWindowName = "Trackbars";
void on_trackbar( int, void* )
{//This function gets called whenever a
// trackbar position is changed
}
string intToString(int number){
std::stringstream ss;
ss << number;
return ss.str();
}
void createTrackbars(){
//create window for trackbars
namedWindow(trackbarWindowName,0);
//create memory to store trackbar name on window
char TrackbarName[50];
sprintf( TrackbarName, "H_MIN", H_MIN);
sprintf( TrackbarName, "H_MAX", H_MAX);
sprintf( TrackbarName, "S_MIN", S_MIN);
sprintf( TrackbarName, "S_MAX", S_MAX);
sprintf( TrackbarName, "V_MIN", V_MIN);
sprintf( TrackbarName, "V_MAX", V_MAX);
//create trackbars and insert them into window
//3 parameters are: the address of the variable that is changing when the trackbar is moved(eg.H_LOW),
//the max value the trackbar can move (eg. H_HIGH),
//and the function that is called whenever the trackbar is moved(eg. on_trackbar)
// ----> ----> ---->
createTrackbar( "H_MIN", trackbarWindowName, &H_MIN, H_MAX, on_trackbar );
createTrackbar( "H_MAX", trackbarWindowName, &H_MAX, H_MAX, on_trackbar );
createTrackbar( "S_MIN", trackbarWindowName, &S_MIN, S_MAX, on_trackbar );
createTrackbar( "S_MAX", trackbarWindowName, &S_MAX, S_MAX, on_trackbar );
createTrackbar( "V_MIN", trackbarWindowName, &V_MIN, V_MAX, on_trackbar );
createTrackbar( "V_MAX", trackbarWindowName, &V_MAX, V_MAX, on_trackbar );
}
void drawObject(vector<Chicken> TheChickens,Mat &frame){
for(int i =0; i<TheChickens.size(); i++){
cv::circle(frame,cv::Point(TheChickens.at(i).getXPos(),TheChickens.at(i).getYPos()),10,cv::Scalar(0,0,255));
cv::putText(frame,intToString(TheChickens.at(i).getXPos())+ " , " + intToString(TheChickens.at(i).getYPos()),cv::Point(TheChickens.at(i).getXPos(),TheChickens.at(i).getYPos()+20),1,1,Scalar(0,255,0));
cv::putText(frame,TheChickens.at(i).getType(),cv::Point(TheChickens.at(i).getXPos(),TheChickens.at(i).getYPos()-30),1,2,TheChickens.at(i).getColour());
}
}
void morphOps(Mat &thresh){
//create structuring element that will be used to "dilate" and "erode" image.
//the element chosen here is a 3px by 3px rectangle
Mat erodeElement = getStructuringElement( MORPH_RECT,Size(3,3));
//dilate with larger element so make sure object is nicely visible
Mat dilateElement = getStructuringElement( MORPH_RECT,Size(8,8));
erode(thresh,thresh,erodeElement);
erode(thresh,thresh,erodeElement);
dilate(thresh,thresh,dilateElement);
dilate(thresh,thresh,dilateElement);
}
void trackFilteredObject(Mat threshold,Mat HSV, Mat &Image){
vector <Chicken> chickens;
Mat temp;
threshold.copyTo(temp);
//these two vectors needed for output of findContours
vector< vector<Point> > contours;
vector<Vec4i> hierarchy;
//find contours of filtered image using openCV findContours function
findContours(temp,contours,hierarchy,CV_RETR_CCOMP,CV_CHAIN_APPROX_SIMPLE );
//use moments method to find our filtered object
double refArea = 0;
bool objectFound = false;
if (hierarchy.size() > 0) {
int numObjects = hierarchy.size();
//if number of objects greater than MAX_NUM_OBJECTS we have a noisy filter
if(numObjects<MAX_NUM_OBJECTS){
for (int index = 0; index >= 0; index = hierarchy[index][0]) {
Moments moment = moments((cv::Mat)contours[index]);
double area = moment.m00;
//if the area is less than 20 px by 20px then it is probably just noise
//if the area is the same as the 3/2 of the image size, probably just a bad filter
//we only want the object with the largest area so we safe a reference area each
//iteration and compare it to the area in the next iteration.
if(area>MIN_OBJECT_AREA){
Chicken chicken;
chicken.setXPos(moment.m10/area);
chicken.setYPos(moment.m01/area);
chickens.push_back(chicken);
objectFound = true;
}else objectFound = false;
}
//let user know you found an object
if(objectFound ==true){
//draw object location on screen
drawObject(chickens,Image);}
}else putText(Image,"TOO MUCH NOISE! ADJUST FILTER",Point(0,50),1,2,Scalar(0,0,255),2);
}
}
void trackFilteredObject(Chicken theChicken,Mat threshold,Mat HSV, Mat &Image){
std::cout << "Trackfilteredobject called";
vector <Chicken> chickens;
Mat temp;
threshold.copyTo(temp);
//these two vectors needed for output of findContours
vector< vector<Point> > contours;
vector<Vec4i> hierarchy;
//find contours of filtered image using openCV findContours function
findContours(temp,contours,hierarchy,CV_RETR_CCOMP,CV_CHAIN_APPROX_SIMPLE );
//use moments method to find our filtered object
double refArea = 0;
bool objectFound = false;
// Problem here, hierarchy size equals 0
if (hierarchy.size() >0) {
std::cout << "First if";
int numObjects = hierarchy.size();
//if number of objects greater than MAX_NUM_OBJECTS we have a noisy filter
if(numObjects<MAX_NUM_OBJECTS){
std::cout << "Second if";
for (int index = 0; index >= 0; index = hierarchy[index][0]) {
std::cout <<"Inside Loop";
Moments moment = moments((cv::Mat)contours[index]);
double area = moment.m00;
//if the area is less than 20 px by 20px then it is probably just noise
//if the area is the same as the 3/2 of the image size, probably just a bad filter
//we only want the object with the largest area so we safe a reference area each
//iteration and compare it to the area in the next iteration.
if(area>MIN_OBJECT_AREA){
Chicken chicken;
chicken.setXPos(moment.m10/area);
chicken.setYPos(moment.m01/area);
chicken.setType(theChicken.getType());
chicken.setColour(theChicken.getColour());
chickens.push_back(chicken);
std::cout << "Chicken Found!";
objectFound = true;
}else objectFound = false;
}
//let user know you found an object
if(objectFound ==true){
//draw object location on screen
drawObject(chickens,Image);}
}else putText(Image,"TOO MUCH NOISE! ADJUST FILTER",Point(0,50),1,2,Scalar(0,0,255),2);
}
}
int main(int argc, char* argv[])
{
//if we would like to calibrate our filter values, set to true.
bool calibrationMode = false;
//Matrix to store each frame of the webcam feed
//Mat cameraFeed;
Mat threshold;
Mat HSV;
if(calibrationMode){
//create slider bars for HSV filtering
createTrackbars();
}
Mat Image = imread("image0117.jpg", 1);
//video capture object to acquire webcam feed
//VideoCapture capture;
//open capture object at location zero (default location for webcam)
//capture.open(0);
//set height and width of capture frame
//capture.set(CV_CAP_PROP_FRAME_WIDTH,FRAME_WIDTH);
//capture.set(CV_CAP_PROP_FRAME_HEIGHT,FRAME_HEIGHT);
//start an infinite loop where webcam feed is copied to cameraFeed matrix
//all of our operations will be performed within this loop
while(1){
//store image to matrix
//capture.read(cameraFeed);
//convert frame from BGR to HSV Colorspace
cvtColor(Image,HSV,CV_BGR2HSV);
if(calibrationMode==true){
//if in calibration mode, we track objects based on the HSV slider values.
cvtColor(Image,HSV,CV_BGR2HSV);
inRange(HSV,Scalar(H_MIN,S_MIN,V_MIN),Scalar(H_MAX,S_MAX,V_MAX),threshold);
morphOps(threshold);
imshow(windowName2,threshold);
trackFilteredObject(threshold,HSV,Image);
}else{
//create some temp Color objects so that
//we can use their member functions/information
Chicken chicken1("chicken1");
std::cout << "Chicken Created! \n";
//first find chickens
cvtColor(Image,HSV,CV_BGR2HSV);
inRange(HSV,chicken1.getHSVmin(),chicken1.getHSVmax(),threshold);
morphOps(threshold);
trackFilteredObject(chicken1,threshold,HSV,Image);
}
//show frames
//imshow(windowName2,threshold);
imshow(windowName,Image);
//imshow(windowName1,HSV);
//delay 30ms so that screen can refresh.
//image will not appear without this waitKey() command
waitKey(0);
}
return 0;
}
鸡类:
#include "Chicken.h"
Chicken::Chicken()
{
//set values for default constructor
setType("null");
setColour(Scalar(0,0,0));
}
Chicken::Chicken(string name){
setType(name);
if(name=="chicken1"){
//TODO: use "calibration mode" to find HSV min
//and HSV max values
setHSVmin(Scalar(0,0,48));
setHSVmax(Scalar(115,256,48));
//BGR value for Chicken:
setColour(Scalar(0,250,0));
}
}
Chicken::~Chicken(void)
{
}
int Chicken::getXPos(){
return Chicken::xPos;
}
void Chicken::setXPos(int x){
Chicken::xPos = x;
}
int Chicken::getYPos(){
return Chicken::yPos;
}
void Chicken::setYPos(int y){
Chicken::yPos = y;
}
Scalar Chicken::getHSVmin(){
return Chicken::HSVmin;
}
Scalar Chicken::getHSVmax(){
return Chicken::HSVmax;
}
void Chicken::setHSVmin(Scalar min){
Chicken::HSVmin = min;
}
void Chicken::setHSVmax(Scalar max){
Chicken::HSVmax = max;
}
标题文件:
#pragma once
#include <string>
#include <opencv/cv.h>
#include <opencv/highgui.h>
using namespace std;
using namespace cv;
class Chicken
{
public:
Chicken();
~Chicken(void);
Chicken(string name);
int getXPos();
void setXPos(int x);
int getYPos();
void setYPos(int y);
Scalar getHSVmin();
Scalar getHSVmax();
void setHSVmin(Scalar min);
void setHSVmax(Scalar max);
string getType(){return type;}
void setType(string t){type = t;}
Scalar getColour(){
return Colour;
}
void setColour(Scalar c){
Colour = c;
}
private:
int xPos, yPos;
string type;
Scalar HSVmin, HSVmax;
Scalar Colour;
};
这就是我工作的形象:
https://www.dropbox.com/s/k7r0p6cha3duomi/image0117.jpg
我希望有人可以帮助我,我在C ++方面的知识很简短:/
谢谢!