void CmSaliencyRC::GetCmplx(CMat& mag32F, CMat& ang32F, Mat& cmplx32FC2) { CV_Assert(mag32F.type() == CV_32FC1 && ang32F.type() == CV_32FC1 && mag32F.size() == ang32F.size()); cmplx32FC2.create(mag32F.size(), CV_32FC2); for (int y = 0; y < mag32F.rows; y++) { float* cmpD = cmplx32FC2.ptr<float>(y); const float* dataA = ang32F.ptr<float>(y); const float* dataM = mag32F.ptr<float>(y); for (int x = 0; x < mag32F.cols; x++, cmpD += 2) { cmpD[0] = dataM[x] * cos(dataA[x]); cmpD[1] = dataM[x] * sin(dataA[x]); } } }
void CmSaliencyRC::SmoothSaliency(CMat &colorNum1i, Mat &sal1f, float delta, const vector<vector<CostfIdx>> &similar) { if (sal1f.cols < 2) return; CV_Assert(sal1f.rows == 1 && sal1f.type() == CV_32FC1); CV_Assert(colorNum1i.size() == sal1f.size() && colorNum1i.type() == CV_32SC1); int binN = sal1f.cols; Mat newSal1d= Mat::zeros(1, binN, CV_64FC1); float *sal = (float*)(sal1f.data); double *newSal = (double*)(newSal1d.data); int *pW = (int*)(colorNum1i.data); // Distance based smooth int n = max(cvRound(binN * delta), 2); vecD dist(n, 0), val(n), w(n); for (int i = 0; i < binN; i++){ const vector<CostfIdx> &similari = similar[i]; double totalDist = 0, totoalWeight = 0; for (int j = 0; j < n; j++){ int ithIdx =similari[j].second; dist[j] = similari[j].first; val[j] = sal[ithIdx]; w[j] = pW[ithIdx]; totalDist += dist[j]; totoalWeight += w[j]; } double valCrnt = 0; for (int j = 0; j < n; j++) valCrnt += val[j] * (totalDist - dist[j]) * w[j]; newSal[i] = valCrnt / (totalDist * totoalWeight); } normalize(newSal1d, sal1f, 0, 1, NORM_MINMAX, CV_32FC1); }
// Training SVM with feature vector X and label Y. // Each row of X is a feature vector, with corresponding label in Y. // Return a CV_32F weight Mat Mat Objectness::trainSVM(CMat &X1f, const vecI &Y, int sT, double C, double bias, double eps) { // Set SVM parameters parameter param; { param.solver_type = sT; // L2R_L2LOSS_SVC_DUAL; param.C = C; param.eps = eps; // see setting below param.p = 0.1; param.nr_weight = 0; param.weight_label = NULL; param.weight = NULL; set_print_string_function(print_null); CV_Assert(X1f.rows == Y.size() && X1f.type() == CV_32F); } // Initialize a problem feature_node *x_space = NULL; problem prob;{ prob.l = X1f.rows; prob.bias = bias; prob.y = Malloc(double, prob.l); prob.x = Malloc(feature_node*, prob.l); const int DIM_FEA = X1f.cols; prob.n = DIM_FEA + (bias >= 0 ? 1 : 0); x_space = Malloc(feature_node, (prob.n + 1) * prob.l); int j = 0; for (int i = 0; i < prob.l; i++){ prob.y[i] = Y[i]; prob.x[i] = &x_space[j]; const float* xData = X1f.ptr<float>(i); for (int k = 0; k < DIM_FEA; k++){ x_space[j].index = k + 1; x_space[j++].value = xData[k]; } if (bias >= 0){ x_space[j].index = prob.n; x_space[j++].value = bias; } x_space[j++].index = -1; } CV_Assert(j == (prob.n + 1) * prob.l); } // Training SVM for current problem const char* error_msg = check_parameter(&prob, ¶m); if(error_msg){ fprintf(stderr,"ERROR: %s\n",error_msg); exit(1); } model *svmModel = train(&prob, ¶m); Mat wMat(1, prob.n, CV_64F, svmModel->w); wMat.convertTo(wMat, CV_32F); free_and_destroy_model(&svmModel); destroy_param(¶m); free(prob.y); free(prob.x); free(x_space); return wMat; }
void BenchMarkLatex::printMatTransport(CMat &mat1di, CStr texFile, const char* rowDes[], bool *descendOrder) { FILE* f = fopen(_S(texFile), "w"); if (f == NULL){ printf("Can't open file %s\n", _S(texFile)); return; } CV_Assert(mat1di.cols == _numMethod); const int MAX_COL = min(20, _numMethod); const int NUM_BLOCK = (_numMethod + MAX_COL - 1) / MAX_COL; string strAlign = "|l||"; for (int i = 0; i < MAX_COL; i++) strAlign += "c|"; const char* rankCommand[3] = {"\\first", "\\second", "\\third"}; Mat mat1d = mat1di.t(); mat1d.convertTo(mat1d, CV_64F); Mat rnk1i = getRankIdx(mat1d, true).t(); Mat rnkInv = getRankIdx(mat1d, false).t(); for (int i = 0; i < mat1di.rows; i++) if (!descendOrder[i]) rnkInv.row(i).copyTo(rnk1i.row(i)); // Revert ordering for row i for (int b = 0; b < NUM_BLOCK; b++){ fprintf(f, "\\begin{tabular}{%s} \\hline\n\tMethod ", _S(strAlign)); for (int i = 0; i < MAX_COL; i++){ int colIdx = i + b * MAX_COL; fprintf(f, "& %4s", colIdx < _numMethod ? _S(_methodNames[colIdx]) : ""); } fprintf(f, "\\\\\\hline\n"); for (int i = 0; i < mat1di.rows; i++){ fprintf(f, "\t%-5s ", rowDes[i]); for (int j = 0; j < MAX_COL; j++){ int colIdx = j + b * MAX_COL; if (colIdx >= _numMethod){ fprintf(f, "& "); continue; } int idx = rnk1i.at<int>(i, colIdx); if (mat1di.type() == CV_32S){ if (idx < 3) fprintf(f, "& %s{%d} ", rankCommand[idx], mat1di.at<int>(i, colIdx)); else fprintf(f, "& %d ", mat1di.at<int>(i, colIdx)); } else{// CV_64F if (idx < 3) fprintf(f, "& %s{%5.3f} ", rankCommand[idx], mat1di.at<double>(i, colIdx)); else fprintf(f, "& %5.3f ", mat1di.at<double>(i, colIdx)); } } fprintf(f, "\\\\\n"); } fprintf(f, "\\hline\n\\end{tabular}\n"); } fclose(f); }
void CmSaliencyRC::SmoothByHist(CMat &img3f, Mat &sal1f, float delta) { //imshow("Before", sal1f); imshow("Src", img3f); // Quantize colors CV_Assert(img3f.size() == sal1f.size() && img3f.type() == CV_32FC3 && sal1f.type() == CV_32FC1); Mat idx1i, binColor3f, colorNums1i; int binN = Quantize(img3f, idx1i, binColor3f, colorNums1i); //CmShow::HistBins(binColor3f, colorNums1i, "Frequency"); // Get initial color saliency Mat _colorSal = Mat::zeros(1, binN, CV_64FC1); int rows = img3f.rows, cols = img3f.cols;{ double* colorSal = (double*)_colorSal.data; if (img3f.isContinuous() && sal1f.isContinuous()) cols *= img3f.rows, rows = 1; for (int y = 0; y < rows; y++){ const int* idx = idx1i.ptr<int>(y); const float* initialS = sal1f.ptr<float>(y); for (int x = 0; x < cols; x++) colorSal[idx[x]] += initialS[x]; } const int *colorNum = (int*)(colorNums1i.data); for (int i = 0; i < binN; i++) colorSal[i] /= colorNum[i]; normalize(_colorSal, _colorSal, 0, 1, NORM_MINMAX, CV_32F); } // Find similar colors & Smooth saliency value for color bins vector<vector<CostfIdx>> similar(binN); // Similar color: how similar and their index Vec3f* color = (Vec3f*)(binColor3f.data); cvtColor(binColor3f, binColor3f, CV_BGR2Lab); for (int i = 0; i < binN; i++){ vector<CostfIdx> &similari = similar[i]; similari.push_back(make_pair(0.f, i)); for (int j = 0; j < binN; j++) if (i != j) similari.push_back(make_pair(vecDist<float, 3>(color[i], color[j]), j)); sort(similari.begin(), similari.end()); } cvtColor(binColor3f, binColor3f, CV_Lab2BGR); //CmShow::HistBins(binColor3f, _colorSal, "BeforeSmooth", true); SmoothSaliency(colorNums1i, _colorSal, delta, similar); //CmShow::HistBins(binColor3f, _colorSal, "AfterSmooth", true); // Reassign pixel saliency values float* colorSal = (float*)(_colorSal.data); for (int y = 0; y < rows; y++){ const int* idx = idx1i.ptr<int>(y); float* resSal = sal1f.ptr<float>(y); for (int x = 0; x < cols; x++) resSal[x] = colorSal[idx[x]]; } //imshow("After", sal1f); //waitKey(0); }
void CmShow::SaveShow(CMat& img, CStr& title) { if (title.size() == 0) return; int mDepth = CV_MAT_DEPTH(img.type()); double scale = (mDepth == CV_32F || mDepth == CV_64F ? 255 : 1); if (title.size() > 4 && title[title.size() - 4] == '.') imwrite(title, img*scale); else if (title.size()) imshow(title, img); }
int SegmentImage(CMat &_src3f, Mat &pImgInd, float sigma, float c, int min_size) { CV_Assert(_src3f.type() == CV_32FC3); int width(_src3f.cols), height(_src3f.rows); pImgInd.create(height, width, CV_32S); image<RGB_f> *im = new image<RGB_f>(width, height, _src3f.data); image<int> *regIdx = new image<int>(width, height, pImgInd.data); int regNum = SegmentImage(im, regIdx, sigma, c, min_size); im->data = NULL; regIdx->data = NULL; delete im; delete regIdx; return regNum; }
Mat CmSaliencyRC::GetFT(CMat &img3f) { CV_Assert(img3f.data != NULL && img3f.type() == CV_32FC3); Mat sal(img3f.size(), CV_32F), tImg; GaussianBlur(img3f, tImg, Size(3, 3), 0); cvtColor(tImg, tImg, CV_BGR2Lab); Scalar colorM = mean(tImg); for (int r = 0; r < tImg.rows; r++) { float *s = sal.ptr<float>(r); float *lab = tImg.ptr<float>(r); for (int c = 0; c < tImg.cols; c++, lab += 3) s[c] = (float)(sqr(colorM[0] - lab[0]) + sqr(colorM[1] - lab[1]) + sqr(colorM[2] - lab[2])); } normalize(sal, sal, 0, 1, NORM_MINMAX); return sal; }
void CmSaliencyRC::AbsAngle(CMat& cmplx32FC2, Mat& mag32FC1, Mat& ang32FC1) { CV_Assert(cmplx32FC2.type() == CV_32FC2); mag32FC1.create(cmplx32FC2.size(), CV_32FC1); ang32FC1.create(cmplx32FC2.size(), CV_32FC1); for (int y = 0; y < cmplx32FC2.rows; y++) { const float* cmpD = cmplx32FC2.ptr<float>(y); float* dataA = ang32FC1.ptr<float>(y); float* dataM = mag32FC1.ptr<float>(y); for (int x = 0; x < cmplx32FC2.cols; x++, cmpD += 2) { dataA[x] = atan2(cmpD[1], cmpD[0]); dataM[x] = sqrt(cmpD[0] * cmpD[0] + cmpD[1] * cmpD[1]); } } }
// 3, 30, 20, 10 GrabCutMF::GrabCutMF(CMat &img3f, CMat &img3u, CStr &nameNE, float w1, float w2, float w3, float alpha, float beta, float gama, float mu) :_fGMM(5), _bGMM(5), _w(img3f.cols), _h(img3f.rows) ,_crf(_w, _h, 2), _nameNE(nameNE) { CV_Assert(img3f.data != NULL && img3f.type() == CV_32FC3); _imgBGR3f = img3f; _img3u = img3u; _trimap1i.create(_h, _w, CV_32S); _segVal1f.create(_h, _w, CV_32F); _unary2f.create(_h, _w, CV_32FC2); _res1u.create(_h, _w, CV_8U); if (w1 != 0) _crf.addPairwiseBilateral(alpha, alpha, beta, beta, beta, img3u.data, w1); if (w2 != 0) _crf.addPairwiseGaussian(gama, gama, w2); if (w3 != 0) _crf.addPairwiseColorGaussian(mu, mu, mu, img3u.data, w3); }
// img3f is the input BGR image void CmColorQua::S_Quantize(CMat& _img3f, Mat &idx1i, int method) { CV_Assert(method >= 0 && method < S_Q_NUM && _img3f.data != NULL && _img3f.type() == CV_32FC3); S_QUANTIZE_FUNC SQ_Function = sqFuns[method]; Mat img; switch (method) { case S_BGR: img = _img3f; break; case S_HSV: cvtColor(_img3f, img, CV_BGR2HSV); break; case S_LAB: cvtColor(_img3f, img, CV_BGR2Lab); break; } idx1i.create(img.size(), CV_32S); for (int r = 0; r < img.rows; r++) { const Vec3f * imgD = img.ptr<Vec3f>(r); int *idx = idx1i.ptr<int>(r); for (int c = 0; c < img.cols; c++) idx[c] = (*SQ_Function)(imgD[c]); } }
// src3f are BGR, color3f are 1xBinDim matrix represent color fore each histogram bin int CmColorQua::S_BinInf(CMat& idx1i, Mat &color3f, vecI &colorNum, int method, CMat &src3f) { int totalBinNum = 0; CV_Assert(idx1i.data != NULL && idx1i.type() == CV_32S && method >= 0 && method < S_Q_NUM); // Find colors for each bin color3f = Mat::zeros(1, binNum[method], CV_32FC3); Vec3f* color = (Vec3f*)(color3f.data); vector<Vec3d> colorD(color3f.cols, 0); colorNum.resize(color3f.cols, 0); if (src3f.size() != Size() && src3f.data != NULL) { for (int r = 0; r < idx1i.rows; r++) { const int *idx = idx1i.ptr<int>(r); const Vec3f *src = src3f.ptr<Vec3f>(r); for (int c = 0; c < idx1i.cols; c++) { colorD[idx[c]] += src[c]; colorNum[idx[c]] ++; } } } S_RECOVER_FUNC SR_Function = srFuns[method]; for (int i = 0; i < color3f.cols; i++) { if (colorNum[i] == 0) (*SR_Function)(i, color[i]); else totalBinNum += colorNum[i]; } if (method == 1) cvtColor(color3f, color3f, CV_HSV2BGR); else if (method == 2) cvtColor(color3f, color3f, CV_Lab2BGR); for (int i = 0; i < color3f.cols; i++) if (colorNum[i] > 0) color[i] = Vec3f((float)(colorD[i][0]/colorNum[i]), (float)(colorD[i][1]/colorNum[i]), (float)(colorD[i][2]/colorNum[i])); return totalBinNum; }
/* * Segment an image * * Returns a color image representing the segmentation. * * Input: * im: image to segment. * sigma: to smooth the image. * c: constant for threshold function. * min_size: minimum component size (enforced by post-processing stage). * nu_ccs: number of connected components in the segmentation. * Output: * colors: colors assigned to each components * pImgInd: index of each components, [0, colors.size() -1] */ int SegmentImage(CMat &_src3f, Mat &pImgInd, double sigma, double c, int min_size) { CV_Assert(_src3f.type() == CV_32FC3); int width(_src3f.cols), height(_src3f.rows); Mat smImg3f; GaussianBlur(_src3f, smImg3f, Size(), sigma, 0, BORDER_REPLICATE); // build graph edge *edges = new edge[width*height*4]; int num = 0; { for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { if (x < width-1) { edges[num].a = y * width + x; edges[num].b = y * width + (x+1); edges[num].w = diff(smImg3f, x, y, x+1, y); num++; } if (y < height-1) { edges[num].a = y * width + x; edges[num].b = (y+1) * width + x; edges[num].w = diff(smImg3f, x, y, x, y+1); num++; } if ((x < width-1) && (y < height-1)) { edges[num].a = y * width + x; edges[num].b = (y+1) * width + (x+1); edges[num].w = diff(smImg3f, x, y, x+1, y+1); num++; } if ((x < width-1) && (y > 0)) { edges[num].a = y * width + x; edges[num].b = (y-1) * width + (x+1); edges[num].w = diff(smImg3f, x, y, x+1, y-1); num++; } } } } // segment universe *u = segment_graph(width*height, num, edges, (float)c); // post process small components for (int i = 0; i < num; i++) { int a = u->find(edges[i].a); int b = u->find(edges[i].b); if ((a != b) && ((u->size(a) < min_size) || (u->size(b) < min_size))) u->join(a, b); } delete [] edges; // pick random colors for each component map<int, int> marker; pImgInd.create(smImg3f.size(), CV_32S); int idxNum = 0; for (int y = 0; y < height; y++) { int *imgIdx = pImgInd.ptr<int>(y); for (int x = 0; x < width; x++) { int comp = u->find(y * width + x); if (marker.find(comp) == marker.end()) marker[comp] = idxNum++; int idx = marker[comp]; imgIdx[x] = idx; } } delete u; return idxNum; }