#include #include #include "HungarianAlgorithm.h" using namespace cv; using namespace std; // B = A( extractRows, extractCols ) // Require: // extractRows.size()==A.rows, extractCols.size()==A.cols // sum(extractRows)==B.rows, sum(extractCols)==B.cols void extractGrids(const Mat &A, const vector &extractRows, const vector &extractCols, Mat &B) { typedef float ValueType; ValueType *pt1 = (ValueType*)A.data, *pt2 = (ValueType*)B.data, *pt3, *pt4; const int step1 = A.step1(), rows = A.rows, cols = A.cols, step2 = B.step1(); vector::const_iterator it1, it2, it3 = extractRows.end(), it4 = extractCols.end(); for (it1 = extractRows.begin(); it1 != it3; pt1 += step1){ pt3 = pt1; if (*(it1++)){ pt4 = pt2; for (it2 = extractCols.begin(); it2 != it4; pt3++) if (*(it2++)) *(pt4++) = *pt3; pt2 += step2; } } } // B = A( extract ) // Require: // min(A.rows,A.cols) ==1 // if(A.rows)==1, then require: A.cols==extract.size(), B.rows==1, sum(extract)==B.cols // if(A.cols)==1, then require: A.rows==extract.size(), B.cols==1, sum(extract)==B.rows void extractDots(const Mat &A, const vector &extract, Mat &B) { assert(A.rows == 1 || A.cols == 1); typedef float ValueType; ValueType *pt1 = (ValueType*)A.data, *pt2 = (ValueType*)B.data; vector::const_iterator it = extract.begin(), it2 = extract.end(); if (A.rows == 1){ for (; it != it2; pt1++) if (*(it++)) *(pt2++) = *pt1; } else{ int step1 = A.step1(), step2 = B.step1(); for (; it != it2; pt1 += step1) if (*(it++)){ *pt2 = *pt1; pt2 += step2; } } } /* Initial Matlab code comes from: http://www.mathworks.com/matlabcentral/fileexchange/20652-hungarian-algorithm-for-linear-assignment-problems--v2-3- Hungarian algorithm for matrix assignment problem. costMat: there are (rows) works and (cols) jobs. costMat(i,j) means the cost of assigning job (j) to worker (i). The problem is to solve a holistic optimization problem of assigning each worker a job! The algorithm allows partial assignment - if there is no proper job for worker (i) we would set assignment(i) to -1, meaning no assignment for worker (i). Negatives in costMat means the corresponding assignments are forbidden. */ void munkres(Mat &IoUMat, vector &assignment) { assert(IoUMat.type() == CV_32FC1); const int rows = IoUMat.rows, cols = IoUMat.cols; assignment.assign(rows, -1); // modify input port O - IoU = cost Mat O = Mat::ones(rows, cols, CV_32FC1); Mat costMat(rows, cols, CV_32FC1); absdiff(O, IoUMat, costMat); Mat validMat(rows, cols, CV_8UC1); compare(costMat, Scalar(0), validMat, CV_CMP_GE); float *ptF, *ptF2; uchar *ptU, *ptU2; int stepGap; int r, c, i; unsigned j; vector::iterator it1, it2; vector::iterator it3, it4; // validCol & validRow vector validRow(rows, false); ptU = validMat.data; for (r = 0; r validCol(cols, false); ptU = validMat.data; for (c = 0; cnCols ? nRows : nCols; if (!n) return; // sumValid & maxValid float sumValid = 0, maxValid = -1.f; ptF = (float*)costMat.data; ptU = validMat.data; stepGap = validMat.step - validMat.cols; r = 0; while (r++maxValid) maxValid = v; } else ptF++; } ptU += stepGap; } // bigM & maxValid maxValid *= 10.f; float bigM = log10f(sumValid); int power = (int)ceilf(bigM) + 1; bigM = 1.f; //bigM = pow( 10, power ); for (i = 0; i starZ(n, -1); ptU = zP.data; for (r = 0; r noncoverColumn(n, true); for (it3 = starZ.begin(); it3 != starZ.end(); it3++){ if (*it3<0) continue; noncoverColumn[*it3] = false; } vector noncoverRow(n, true); vector primeZ(n, -1); // minC_uncovered & minR_uncovered int cnt1 = 0, cnt2 = 0; it1 = noncoverColumn.begin(), it2 = noncoverRow.begin(); i = 0; while (i++ rIdx, cIdx; // [rIdx,cIdx] = find(temp4); ptU = temp4.data; stepGap = temp4.step - temp4.cols; for (r = 0; r cR, cC; for (j = 0; j rIdx2, cIdx2; for (it3 = rIdx.begin(), it4 = cIdx.begin(); it3 != rIdx.end(); it3++, it4++) if (*it3 != uZr){ rIdx2.push_back(*it3); cIdx2.push_back(*it4); } rIdx = rIdx2, cIdx = cIdx2; // cR = find(~coverRow); cR.clear(); for (j = 0; j(stz)); temp1 = tmp1(cv::Rect(0, 0, 1, sz)); extractDots(dMat.col(stz), noncoverRow, temp1); temp4 = tmp4(cv::Rect(0, 0, 1, sz)); compare(temp1, minR_uncovered, temp4, CV_CMP_EQ); // rIdx = [rIdx(:);cR(z)]; for (i = 0, ptU = temp4.data; i= 0){ starZ[rowZ1] = -1; uZc = primeZ[rowZ1]; uZr = rowZ1; for (j = 0; j rowIdx(nRows), colIdx(nCols); it1 = validRow.begin(), it2 = validCol.begin(); for (i = 0, it3 = rowIdx.begin(); i vIdx(nRows, false); it1 = vIdx.begin(), it3 = starZ.begin(); i = 0; while (i++-1){ uchar isInvalid = validMat.at(j, job); // validMat is now "invalidMat" if (isInvalid) assignment[j] = -1; } } }