This repository has been archived by the owner. It is now read-only.
Permalink
Cannot retrieve contributors at this time
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
TrackerPlugin_EyeTracker/TrackerWorker.cpp
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
176 lines (144 sloc)
5.53 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "TrackerWorker.h" | |
using namespace cv; | |
TrackerWorker::TrackerWorker(QObject* parent) | |
: QObject(parent) | |
{ | |
qRegisterMetaType < QVector<float> >("QVectorFloat"); | |
rois.push_back(QRect(0,0,100,100)); | |
rois.push_back(QRect(0,0,100,100)); | |
thresholds.push_back(255); | |
thresholds.push_back(255); | |
areaConstraints.push_back(100); | |
areaConstraints.push_back(50000); | |
areaConstraints.push_back(100); | |
areaConstraints.push_back(50000); | |
} | |
void TrackerWorker::onFrameGrabbed(Mat src) | |
{ | |
bool isRoiStable = this->isRoiStable; //assure that roi is considered stable during this entire call | |
int pMinArea = areaConstraints.at(0); | |
int pMaxArea = areaConstraints.at(1); | |
int cMinArea = areaConstraints.at(2); | |
int cMaxArea = areaConstraints.at(3); | |
Point cCornea(0,0); | |
Point cPupil(0,0); | |
double pDiam = 0; | |
std::vector<Mat> rgb; | |
split(src, rgb); | |
/*Pupil*/ | |
Mat pMask; | |
Mat pRegion = rgb[0].rowRange(rois.at(0).y(),rois.at(0).y() + rois.at(0).height()).colRange(rois.at(0).x(),rois.at(0).x() + rois.at(0).width()); | |
if(isBrightPupil){ | |
cv::threshold(pRegion, pMask, thresholds.at(0), 1, THRESH_BINARY); | |
}else{ | |
cv::threshold(pRegion, pMask, thresholds.at(0), 1, THRESH_BINARY_INV); | |
} | |
RotatedRect pRect; | |
if(isRoiStable){ | |
std::vector<Vec4i> pHierarchy; | |
std::vector<std::vector<Point> > pContours; | |
std::vector<Point> pContour; | |
findContours(pMask, pContours, pHierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) ); | |
for(uint i=0;i<pContours.size();i++){ | |
if((contourArea(pContours[i])>=pMinArea) & (contourArea(pContours[i])<=pMaxArea)){ | |
pContour = pContours[i]; | |
for(uint j=0;j<pContour.size();j++){ | |
pContour.at(j) = pContour.at(j) + Point2i(rois.at(0).x(), rois.at(0).y()) ; | |
} | |
break; | |
} | |
} | |
if(pContour.size()>4){ | |
/*Determine centroid by fitting an ellipse*/ | |
pRect = fitEllipse(pContour); | |
cPupil = pRect.center; | |
pDiam = (pRect.boundingRect().height + pRect.boundingRect().width) / 2; | |
} | |
} | |
/*Corneal reflection*/ | |
Mat cRegion = rgb[1].rowRange(rois.at(1).y(),rois.at(1).y() + rois.at(1).height()).colRange(rois.at(1).x(),rois.at(1).x() + rois.at(1).width()); | |
Mat cMask; | |
cv::threshold(cRegion, cMask, thresholds.at(1), 1, THRESH_BINARY); | |
std::vector<Point> cContour; | |
if(isRoiStable){ | |
std::vector<Vec4i> cHierarchy; | |
std::vector<std::vector<Point> > cContours; | |
findContours(cMask, cContours, cHierarchy, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) ); | |
int numberOfContoursToAnalyze; | |
if(cContours.size() > MaxNumberContours){ | |
numberOfContoursToAnalyze = MaxNumberContours; | |
}else{ | |
numberOfContoursToAnalyze = cContours.size(); | |
} | |
for(uint i=0; i<numberOfContoursToAnalyze; i++){ | |
if((contourArea(cContours[i])>=cMinArea)&(contourArea(cContours[i])<cMaxArea)){ | |
cContour = cContours[i]; | |
for(uint j=0;j<cContour.size();j++){ | |
cContour.at(j) = cContour.at(j) + Point2i(rois.at(1).x(), rois.at(1).y()) ; | |
} | |
break; | |
} | |
} | |
if(cContour.size() > 4){ | |
/*Determine centroid with boundingRect*/ | |
Rect cRect = boundingRect(cContour); | |
cCornea.x = cRect.x + (cRect.width / 2); | |
cCornea.y = cRect.y + (cRect.height / 2); | |
} | |
} | |
/*Generate preview image*/ | |
Mat previewIm(src.size(), CV_8U, double(0)); | |
previewIm(Rect(rois.at(0).x(),rois.at(0).y(), rois.at(0).width(), rois.at(0).height())) = pMask*255; | |
previewIm(Rect(rois.at(1).x(),rois.at(1).y(), rois.at(1).width(), rois.at(1).height())) = cMask*127; | |
Mat outputIm; | |
if(showBinary){ | |
outputIm = Mat(src.size(), CV_8UC3); | |
cvtColor(previewIm, outputIm, CV_GRAY2RGB); | |
}else{ | |
outputIm = src.clone(); | |
} | |
if(isRoiStable){ | |
circle(outputIm, cPupil, 10, Scalar(0,255,0), -1, 8, 0); | |
circle(outputIm, cCornea, 10, Scalar(255,0,255), -1, 8, 0); | |
//std::vector<std::vector<Point> > pContourV = std::vector<std::vector<Point> >(1, pContour); | |
//drawContours(outputIm, pContourV, -1, Scalar(0,255,0), 2, 8); | |
if(cContour.size()){ | |
std::vector<std::vector<Point> > cContourV = std::vector<std::vector<Point> >(1, cContour); | |
drawContours(outputIm, cContourV, -1, Scalar(255,0,255), 2, 8); | |
} | |
ellipse(outputIm, pRect, Scalar(0,255,0), 10, 8); | |
std::vector<double> result; | |
result.push_back(cPupil.x); | |
result.push_back(cPupil.y); | |
result.push_back(cCornea.x); | |
result.push_back(cCornea.y); | |
result.push_back(pDiam); | |
emit(trackingResult(result)); | |
} | |
emit(trackingPreview(outputIm)); | |
} | |
void TrackerWorker::onThresholdChanged(int index, int value) | |
{ | |
thresholds.replace(index, value); | |
} | |
void TrackerWorker::onAreaConstraintsChanged(int index, int area) | |
{ | |
areaConstraints.replace(index, area); | |
} | |
void TrackerWorker::onRoiChanged(int index, QRect roi) | |
{ | |
rois.replace(index, roi); | |
} | |
void TrackerWorker::onShowBinary(bool showBinary) | |
{ | |
this->showBinary = showBinary; | |
} | |
void TrackerWorker::onBrightPupil(bool isBrightPupil) | |
{ | |
this->isBrightPupil = isBrightPupil; | |
} | |
void TrackerWorker::onDoTracking(bool doTracking) | |
{ | |
this->isRoiStable = doTracking; | |
qDebug()<<"TrackerWorker: Tracking is:" << doTracking; | |
} |