我有一个名为BlobTracking的类,它使用cvBlob库从blob掩码中提取blob。 我调用函数cvb :: cvLabel(& segmentated,labelImg,blobs); blob存储在类变量cvb :: CvBlobs blobs中(已经尝试将变量设置为public和private) (CvBlobs的定义:typedef std :: map CvBlobs;)
我有另一个名为OF_Object的类。在BlobTracking类中,我存储了OF_Objects: Blobtracking.h
struct VectInfo {
OF_Object oF_Object;
int index;
int size;
};
typedef std::map<OF_ID,VectInfo> OF_Objects;
class BlobTracking
{
private:
OF_Objects oF_Objects; ...
}
当在blob跟踪类的函数过程中,在其中一个OF_Objects中我调用函数
我从BlobTracking类调用blobOfPoint,blobOfPoint的所有3个变量都是BlobTracking类的私有变量。
问题是在函数blobOfPoint中,当我在Xcode上调试时,我看到变量blob并且例如有一个元素。但迭代器bi = blobs.begin();指向其他地方。
我在这里放了函数blobOfPoint以及BlobTracking的过程,我在行中记下了blobOfPoint的调用。 我还发布了一个显示xCode调试的打印屏幕:
打印变量blob值的屏幕: https://dl.dropboxusercontent.com/u/26082578/SS01.png
变量迭代器的值打印屏幕bi = blobs.begin(): https://dl.dropboxusercontent.com/u/26082578/SS02.png
bool OF_Object::blobOfPoint(Point2f &point,cvb::CvBlobs &blobs, BlobPolygons &blobPolygons)
{
bool found= false;
if(oF_BlobsFP.size()>0)
{
OF_BlobsFP::iterator it=oF_BlobsFP.begin();
while(!(found = poinInBlob(point,*blobs.find(it->first)->second,blobPolygons)) && it!=oF_BlobsFP.end())
it++;
}
问题出现在这个迭代器中,你可以在Xcode的打印屏幕中看到!!
cvb::CvBlobs::iterator bi=blobs.begin();
cvb::CvBlob test=*bi->second;
if(!found)
{
while(!(found = poinInBlob(point,*bi->second,blobPolygons)) && bi!=blobs.end())
bi++;
}
if(found)
{
OF_BlobsFP::iterator it = oF_BlobsFP.find(bi->first);
//If doesn't exist
if(it==oF_BlobsFP.end())
{
oF_BlobsFP.insert(std::pair<cvb::CvLabel,vector<Point2f> >(bi->first, vector<Point2f>()));
it = oF_BlobsFP.find(bi->first);
}
it->second.push_back(point);
}
return found;
}
Blob跟踪流程
void BlobTracking::process(const cv::Mat &prevInput, cv::Mat &img_input, const cv::Mat &img_mask, cv::Mat &img_output)
{
if(img_input.empty() || img_mask.empty())
return;
cv::Mat mask(img_input.size(), CV_8UC1);
IplImage segmentated =IplImage(img_mask);
IplConvKernel* morphKernel = cvCreateStructuringElementEx(5, 5, 1, 1, CV_SHAPE_RECT, NULL);
cvMorphologyEx(&segmentated, &segmentated, NULL, morphKernel, CV_MOP_OPEN, 1);
if(showBlobMask)
cvShowImage("Blob Mask", &segmentated);
IplImage* labelImg = cvCreateImage(img_input.size(), IPL_DEPTH_LABEL, 1);
unsigned int result = cvb::cvLabel(&segmentated, labelImg, blobs);
//cvb::cvFilterByArea(blobs, 500, 1000000);
cvb::cvFilterByArea(blobs, minArea, maxArea);
blobPolygons.clear();
cvb::CvBlobs::iterator bi=blobs.begin();
while(bi!=blobs.end())
{
blobPolygons.insert(std::pair<cvb::CvLabel,cvb::CvContourPolygon *>(bi->first,cvb::cvConvertChainCodesToPolygon(&bi->second->contour)));
bi++;
}
nBlobs=blobs.size();
if(nBlobs=0)
oF_Objects.clear();
else{
//If there are objects
if(points[0].size()>0&&oF_Objects.size()>0)
{
//Compute optical Flow
calcOpticalFlowPyrLK(prevInput, img_input, points[0], points[1], status, err, winSize,3, termcrit, 0);
objOfBlobs.clear();
OF_Objects::iterator it=oF_Objects.begin();
int i=0;
//Associate each point of each object with a Blob
while(it!=oF_Objects.end())
{
it->second.oF_Object.clearOF_BlobsFP();
int index=it->second.index;
int oldSize=it->second.size;
it->second.index=i;
int nPointsWithoutBlob=0, newSize=0;
while(oldSize>0)
{
//If point calculated and is inside of a Blob
此处调用该函数:
if(status[index]&&it->second.oF_Object.blobOfPoint(points[1][index],blobs,blobPolygons)){
points[0][i] = points[1][index];
newSize++;
i++;
//circle(img_input, points[1][i], 3, Scalar(0,255,0), -1, 8);
}
oldSize--;
index ++;
}
it->second.oF_Object.setnPointsWithoutBlob(nPointsWithoutBlob);
it->second.size=newSize;
//Update new objects to see which ones finished,which ones had a significant increase in size and which ones splitted
if(!it->second.oF_Object.updateOF_Object(blobs))
oF_Objects.erase(it);
else
{
//Add the information to which blob(s) is the object associated
OF_ID oF_ID=it->second.oF_Object.getID();
//If not splitted just add the first blob in the list
if(!it->second.oF_Object.splitStatus())
{
cvb::CvLabel bLabel= it->second.oF_Object.getBlobLabel();
std::map<cvb::CvLabel,vector<OF_ID> >::iterator it2 = objOfBlobs.find(bLabel);
if(it2==objOfBlobs.end())
{
objOfBlobs.insert(std::pair<cvb::CvLabel,vector<OF_ID> >(bLabel, vector<OF_ID>()));
it2 = objOfBlobs.find(bLabel);
}
it2->second.push_back(oF_ID);
}
else{
//If splitted, add all objects in the list
OF_BlobsFP::iterator it3 =it->second.oF_Object.getOF_BlobsFP().begin();
while(it3!=it->second.oF_Object.getOF_BlobsFP().end())
{
cvb::CvLabel bLabel= it3->first;
std::map<cvb::CvLabel,vector<OF_ID> >::iterator it4 = objOfBlobs.find(bLabel);
if(it4==objOfBlobs.end())
{
objOfBlobs.insert(std::pair<cvb::CvLabel,vector<OF_ID> >(bLabel, vector<OF_ID>()));
it4 = objOfBlobs.find(bLabel);
}
it4->second.push_back(oF_ID);
it3++;
}
}
}
it++;
}
points[1].resize(i);
points[0].resize(i);
//Check Merged Blobs
std::map<cvb::CvLabel,vector<OF_ID> >::iterator it5 = objOfBlobs.begin();
while(it5!=objOfBlobs.end())
{
if(int s=it5->second.size()>0)
{
int i=0;
while(s>0)
{
OF_ID oF_ID=it5->second.at(i);
OF_Object *pOF=&(oF_Objects.find(oF_ID)->second.oF_Object);
pOF->setMergeStatus(true);
pOF->setUpdateStatus(false);
i++;
s--;
}
}
it5++;
}
//Check for objects to recalculate new features
it=oF_Objects.begin();
std::set<OF_ID> ofToUpdate;
while(it!=oF_Objects.end())
{
if(it->second.oF_Object.getUpdateStatus()){
if(it->second.oF_Object.newFeatures(blobs, img_input))
ofToUpdate.insert(it->first);
it->second.oF_Object.setUpdateStatus(false);
}
it++;
}
//if there were objects with new features, copy not updated points to a new vector and add new ones to the end
if(ofToUpdate.size()>0){
it=oF_Objects.begin();
int k=0;
while(it!=oF_Objects.end())
{
//if object not with new features
if(ofToUpdate.find(it->first)==ofToUpdate.end())
{
int index=it->second.index;
int size=it->second.size;
it->second.index=k;
while(size>0)
{
points[1][k] = points[0][index];
k++;
size--;
index ++;
}
}
it++;
}
points[1].resize(k);
points[0].resize(k);
swap(points[1], points[0]);
std::set<OF_ID>::iterator it5 = ofToUpdate.begin();
while(it5!=ofToUpdate.end())
{
OF_ID ofId=*it5;
oF_Objects.find(ofId)->second.index=k;
vector<Point2f> &oF_Points = oF_Objects.find(ofId)->second.oF_Object.getOF_BlobsFP().begin()->second;
int size=oF_Points.size();
oF_Objects.find(ofId)->second.size=size;
int i=0;
while(size>0)
{
points[0].push_back(oF_Points[i]);
i++;
k++;
size--;
}
it5++;
}
}
}
}
//Check for blobs without OF_Objects and create new objects for them
cvb::CvBlobs::iterator it = blobs.begin();
int k=points[0].size();
while(it!=blobs.end())
{
if(objOfBlobs.find(it->first)==objOfBlobs.end())
{
OF_Object objct = OF_Object(img_input,it->first,blobs,last_OF_ID);
last_OF_ID++;
VectInfo vctInfo= {.oF_Object=objct,.index=k,.size=objct.getNTFeatures()};
oF_Objects.insert(std::pair<OF_ID,VectInfo >(objct.getID(), vctInfo));
vector<Point2f> &oF_Points = objct.getOF_BlobsFP().begin()->second;
int size=objct.getNTFeatures();
int i=0;
while(size>0)
{
points[0].push_back(oF_Points[i]);
i++;
k++;
size--;
}
}
it++;
}
// if(!blobs.empty()){
// for(std::map<cvb::CvLabel,cvb::CvBlob*>::iterator it = blobs.begin() ; it != blobs.end(); it++)
// {
// //std::cout << (*it).first << " => " << (*it).second << std::endl;
// cvb::CvID id = (*it).first;
// cvb::CvBlob* blob = (*it).second;
// createMask(mask, *blob);
// }
// }
if(drawFeatures)
{
for(int m=0;m<points[0].size();m++)
{
circle(img_output, points[0][m], 3, Scalar(0,255,0), -1, 8);
}
}
cvReleaseImage(&labelImg);
cvReleaseStructuringElement(&morphKernel);
firstTime = false;
}