37 #ifdef OPENCV_VERSION_3 39 _classifier->setTermCriteria(cv::TermCriteria(cv::TermCriteria::COUNT, 4, FLT_EPSILON));
41 _classifier->setCovarianceMatrixType(cv::ml::EM::COV_MAT_DIAGONAL);
43 _classifier = cv::EM(2, cv::EM::COV_MAT_DIAGONAL, cv::TermCriteria(cv::TermCriteria::COUNT , 4, FLT_EPSILON));
47 for (
unsigned int i = 0; i < 256; i++)
59 for (
unsigned int i = 0; i < 256; i++)
62 for (
unsigned int i = 0; i <
_samples.size(); i++) {
76 for (
unsigned int i = 0; i < 256; i++)
78 for (
unsigned int i = 0; i < 256; i++)
83 unsigned int histCount[256];
85 for (
unsigned int i = 0; i < 256; i++)
91 cv::Mat samples(n, 1, CV_64FC1);
93 for (
unsigned int i = 0; i < 256; i++) {
94 for (
unsigned int j = 0; j < histCount[i]; j++) {
95 samples.ptr<
double >(0)[idx] = i;
100 #ifdef OPENCV_VERSION_3 106 cv::Mat sampleAux(1, 1, CV_64FC1);
107 for (
unsigned int i = 0; i < 256; i++) {
108 sampleAux.ptr<
double >(0)[0] = i;
110 #ifdef OPENCV_VERSION_3 111 cv::Vec2f r =
_classifier->predict2(sampleAux, probs);
115 _prob[i] = exp(r[0]);
126 std::cerr <<
"Invalid markersize in ChromaticMask::setParams" << std::endl;
130 if (BC.size() == 0) {
131 std::cerr <<
"Invalid BoardConfiguration size in ChromaticMask::setParams" << std::endl;
136 markersize = cv::norm(BC[0][0]-BC[0][1]);
140 cv::Point3f
min, max;
141 min = max = BC[0][0];
142 for (
unsigned int i = 0; i < BC.size(); i++) {
143 for (
unsigned int j = 0; j < 4; j++) {
144 if (BC[i][j].x <= min.x && BC[i][j].y <= min.y)
146 if (BC[i][j].x >= max.x && BC[i][j].y >= max.y)
150 double pixSize = fabs(markersize / (BC[0][1].x - BC[0][0].x));
157 vector< cv::Point3f > corners;
158 corners.push_back(min);
159 corners.push_back(cv::Point3f(min.x, max.y, 0));
160 corners.push_back(max);
161 corners.push_back(cv::Point3f(max.x, min.y, 0));
163 setParams(mc, nc, threshProb, CP, BC, corners);
171 vector< cv::Point3f > corners) {
172 _classifiers.resize(mc * nc);
173 for (
unsigned int i = 0; i < _classifiers.size(); i++)
174 _classifiers[i].
setProb(threshProb);
178 _cell_neighbours.resize(mc * nc);
181 for (
unsigned int j = 0; j < nc; j++)
182 for (
unsigned int i = 0; i < mc; i++, idx_++) {
183 _centers.push_back(cv::Point2f(i + 0.5, j + 0.5));
184 for (
unsigned int nj = max(j - 1, (
unsigned int)0); nj <
min(mc, j + 1); nj++) {
185 for (
unsigned int ni = max(i - 1, (
unsigned int)0); ni < min(mc, i + 1); ni++) {
186 size_t tidx = nj * mc + ni;
187 _cell_neighbours[idx_].push_back(tidx);
193 _BD.getMarkerDetector().setThresholdParams(35, 7);
194 _BD.getMarkerDetector().enableErosion(
false);
196 _BD.setYPerpendicular(
false);
198 _BD.setParams(BC, CP);
200 _objCornerPoints = corners;
203 _pixelsVector.clear();
204 for (
unsigned int i = 0; i < CP.
CamSize.height / 2; i++)
205 for (
unsigned int j = 0; j < CP.
CamSize.width / 2; j++)
206 _pixelsVector.push_back(cv::Point2f(2 * j, 2 * i));
209 _cellMap = cv::Mat(CP.
CamSize.height, CP.
CamSize.width, CV_8UC1, cv::Scalar::all(0));
210 _canonicalPos = cv::Mat(CP.
CamSize.height, CP.
CamSize.width, CV_8UC2);
212 _cellCenters.resize(_classifiers.size());
213 for (
unsigned int i = 0; i < mc; i++) {
214 for (
unsigned int j = 0; j < nc; j++) {
215 _cellCenters[i * mc + j].x = ((2 * i + 1) * _cellSize) / 2.;
216 _cellCenters[i * mc + j].y = ((2 * j + 1) * _cellSize) / 2.;
221 pair< double, double >
AvrgTime(0, 0);
228 cv::projectPoints(_objCornerPoints, board.
Rvec, board.
Tvec, _CP.CameraMatrix, _CP.Distorsion, _imgCornerPoints);
231 cv::Point2f pointsRes[4], pointsIn[4];
232 for (
int i = 0; i < 4; i++)
233 pointsIn[i] = _imgCornerPoints[i];
234 pointsRes[0] = (cv::Point2f(0, 0));
235 pointsRes[1] = cv::Point2f(_cellSize * _mc - 1, 0);
236 pointsRes[2] = cv::Point2f(_cellSize * _mc - 1, _cellSize * _nc - 1);
237 pointsRes[3] = cv::Point2f(0, _cellSize * _nc - 1);
238 _perpTrans = cv::getPerspectiveTransform(pointsIn, pointsRes);
240 double tick = (double)cv::getTickCount();
242 vector< cv::Point2f > transformedPixels;
243 cv::perspectiveTransform(_pixelsVector, transformedPixels, _perpTrans);
245 AvrgTime.first += ((double)cv::getTickCount() - tick) / cv::getTickFrequency();
247 cout <<
"Time cc detection=" << 1000 *
AvrgTime.first /
AvrgTime.second <<
" milliseconds" << endl;
251 cv::Rect cellRect(0, 0, _mc, _nc);
252 for (
unsigned int i = 0; i < transformedPixels.size(); i++) {
254 transformedPixels[i].x /= _cellSize;
255 transformedPixels[i].y /= _cellSize;
256 if (!transformedPixels[i].inside(cellRect)) {
257 _cellMap.at< uchar >(_pixelsVector[i].y, _pixelsVector[i].x) = 0;
258 _cellMap.at< uchar >(_pixelsVector[i].y + 1, _pixelsVector[i].x) = 0;
259 _cellMap.at< uchar >(_pixelsVector[i].y, _pixelsVector[i].x + 1) = 0;
260 _cellMap.at< uchar >(_pixelsVector[i].y + 1, _pixelsVector[i].x + 1) = 0;
262 uchar cellNum = (
unsigned int)transformedPixels[i].y * _nc + (
unsigned int)transformedPixels[i].x;
263 _cellMap.at< uchar >(_pixelsVector[i].y, _pixelsVector[i].x) = 1 + cellNum;
264 _cellMap.at< uchar >(_pixelsVector[i].y + 1, _pixelsVector[i].x) = 1 + cellNum;
265 _cellMap.at< uchar >(_pixelsVector[i].y, _pixelsVector[i].x + 1) = 1 + cellNum;
266 _cellMap.at< uchar >(_pixelsVector[i].y + 1, _pixelsVector[i].x + 1) = 1 + cellNum;
276 calculateGridImage(board);
278 for (
unsigned int i = 0; i < _classifiers.size(); i++)
281 for (
unsigned int i = 0; i < in.rows; i++) {
282 for (
unsigned int j = 0; j < in.cols; j++) {
283 uchar idx = _cellMap.at< uchar >(i, j);
285 _classifiers[idx - 1].addSample(in.at< uchar >(i, j));
289 for (
unsigned int i = 0; i < _classifiers.size(); i++)
290 _classifiers[i].
train();
324 calculateGridImage(board);
328 for (
unsigned int i = 0; i < in.rows; i++) {
329 const uchar *in_ptr = in.ptr< uchar >(i);
330 const uchar *_cellMap_ptr = _cellMap.ptr< uchar >(i);
331 for (
unsigned int j = 0; j < in.cols; j++) {
332 uchar idx = _cellMap_ptr[j];
348 if (_classifiers[idx - 1].
classify(in.at< uchar >(i, j)))
349 _mask.at< uchar >(i, j) = 1;
357 cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
358 cv::morphologyEx(_mask, maskClose, CV_MOP_CLOSE, element);
366 int endx = r.x + r.width;
367 int endy = r.y + r.height;
368 endx =
min(endx, size.width);
369 endy =
min(endy, size.height);
370 r.width = endx - r.x;
371 r.height = endy - r.y;
379 _mask.create(_CP.CamSize.height, _CP.CamSize.width, CV_8UC1);
380 _maskAux.create(_CP.CamSize.height, _CP.CamSize.width, CV_8UC1);
381 _maskAux.setTo(cv::Scalar::all(0));
383 cv::projectPoints(_objCornerPoints, board.
Rvec, board.
Tvec, _CP.CameraMatrix, _CP.Distorsion, _imgCornerPoints);
385 cv::Point2f pointsRes[4], pointsIn[4];
386 for (
int i = 0; i < 4; i++)
387 pointsIn[i] = _imgCornerPoints[i];
389 pointsRes[0] = (cv::Point2f(0, 0));
390 pointsRes[1] = cv::Point2f(_mc - 1, 0);
391 pointsRes[2] = cv::Point2f(_mc - 1, _nc - 1);
392 pointsRes[3] = cv::Point2f(0, _nc - 1);
393 _perpTrans = cv::getPerspectiveTransform(pointsIn, pointsRes);
396 _perpTrans.convertTo(pT_32, CV_32F);
400 cv::Rect r = cv::boundingRect(_imgCornerPoints);
402 float *H = pT_32.ptr<
float >(0);
405 for (
unsigned int y = r.y; y < r.y + r.height; y += 2, ny++) {
406 const uchar *in_ptr = in.ptr< uchar >(y);
407 uchar *_mask_ptr = _maskAux.ptr< uchar >(y);
408 int startx = r.x + ny % 2;
409 for (
unsigned int x = startx; x < r.x + r.width; x += 2) {
411 float _inv_pointz = 1. / (x * H[6] + y * H[7] + H[8]);
412 point.x = _inv_pointz * (x * H[0] + y * H[1] + H[2]);
413 point.y = _inv_pointz * (x * H[3] + y * H[4] + H[5]);
415 c.x = int(point.x + 0.5);
416 c.y = int(point.y + 0.5);
417 if (c.x < 0 || c.x > _mc - 1 || c.y < 0 || c.y > _nc - 1)
419 size_t cell_idx = c.y * _mc + c.x;
420 float prob = 0.0, totalW = 0.0, dist, w;
422 for (
unsigned int k = 0; k < _cell_neighbours[cell_idx].size(); k++) {
423 dist = fabs(point.x - _centers[k].x) + fabs(point.y - _centers[k].y);
428 prob += w * _classifiers[_cell_neighbours[cell_idx][k]].getProb(in_ptr[x]);
439 cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
440 cv::morphologyEx(_maskAux, _mask, CV_MOP_CLOSE, element);
447 maskCells = _cellMap.mul(_mask);
449 for (
unsigned int i = 0; i < _classifiers.size(); i++)
452 for (
unsigned int i = 0; i < maskCells.rows; i++) {
453 uchar *maskCells_ptr = maskCells.ptr< uchar >(i);
454 const uchar *in_ptr = in.ptr< uchar >(i);
455 for (
unsigned int j = 0; j < maskCells.cols; j++) {
456 if (maskCells_ptr[j] != 0)
457 _classifiers[maskCells_ptr[j] - 1].addSample(in_ptr[j]);
461 for (
unsigned int i = 0; i < _classifiers.size(); i++)
463 _classifiers[i].train();
471 _mask.create(_CP.CamSize.height, _CP.CamSize.width, CV_8UC1);
472 _mask.setTo(cv::Scalar::all(0));
pair< double, double > AvrgTime(0, 0)
void classify(const cv::Mat &in, const aruco::Board &board)
void train(const cv::Mat &in, const aruco::Board &board)
void setParams(unsigned int mc, unsigned int nc, double threshProb, aruco::CameraParameters CP, aruco::BoardConfiguration BC, vector< cv::Point3f > corners)
void update(const cv::Mat &in)
void classify2(const cv::Mat &in, const aruco::Board &board)
EMClassifier(unsigned int nelements=200)
void calculateGridImage(const aruco::Board &board)
unsigned int numsamples()
cv::Rect fitRectToSize(cv::Rect r, cv::Size size)
Parameters of the camera.
This class defines a board with several markers. A Board contains several markers so that they are mo...