void CmSaliencyGC::GetGU(vecD& gc, vecD &d, double sigmaDist, double dominate) { if (d.size() == 0){ d.resize(_NUM); #pragma omp parallel for for (int i = 0; i < _NUM; i++) SpatialVar(_PixelSalCi1f[i], d[i]); } Mat_<double> clrDist; clrDist = Mat_<double>::zeros(_NUM, _NUM); vector<Vec3f> gmmClrs(_NUM); cvtColor(_gmmClrs, gmmClrs, CV_BGR2Lab); vecD maxDist(_NUM); for (int i = 0; i < _NUM; i++) for (int j = 0; j < i; j++){ double dCrnt = vecDist(gmmClrs[i], gmmClrs[j]); clrDist(i, j) = clrDist(j, i) = dCrnt; maxDist[i] = max(maxDist[i], dCrnt); maxDist[j] = max(maxDist[j], dCrnt); } for (int i = 0; i < _NUM; i++) { gc[i] = 0; for (int j = 0; j < _NUM; j++) gc[i] += _gmmW[j] * clrDist(i, j) / maxDist[i]; //min(clrDist(i, j), dominate); } for (int i = 0; i < _NUM; i++) _gu[i] = _gu[i] * exp(-9.0 * sqr(d[i])); // normalize(_gu, _gu, 0, 1, CV_MINMAX); }
void Saliency::Evaluate(const string& resultW, const string >ImgW, vecD &precision, vecD &recall) { vecS names; string inDir; int imgNum = CmFile::GetNames(resultW, names, inDir); int COLOR_NUM = 256; precision.resize(COLOR_NUM, 0); recall.resize(COLOR_NUM, 0); string truthDir = CmFile::GetFolder(gtImgW); size_t pathSize = gtImgW.size(), nPos = gtImgW.find_last_of('.'); string ext = gtImgW.substr(nPos, pathSize - nPos); for (int i = 0; i < imgNum; i++) { CmLog::LogProgress("Processing %-40s\r", names[i].c_str()); Mat resS = imread(inDir + names[i], CV_LOAD_IMAGE_GRAYSCALE); CV_Assert_(resS.data != NULL, ("Can't load saliency map: %s\n", names[i].c_str())); names[i].resize(names[i].find_last_of("_")); Mat truM = imread(truthDir + CmFile::GetNameNE(names[i]) + ext, CV_LOAD_IMAGE_GRAYSCALE); compare(truM, 128, truM, CMP_GE); if (truM.data == NULL) { CmLog::LogLine("Evaluation stopped due to missing ground truth results\n"); exit(1); } CV_Assert_(resS.size() == truM.size(), ("Saliency map and ground truth image size mismatch\n")); double groundTruth = sum(truM).val[0]; #pragma omp parallel for for (int thr = 0; thr < COLOR_NUM; thr++) { Mat resM; compare(resS, thr, resM, CMP_GE); double res = sum(resM).val[0]; bitwise_and(resM, truM, resM); double common = sum(resM).val[0]; precision[thr] += common/(res + 1e-8); recall[thr] += common/(groundTruth + 1e-8); } } for (int thr = 0; thr < COLOR_NUM; thr++) { precision[thr] /= imgNum; recall[thr] /= imgNum; } }
void CmEvaluation::PrintVector(FILE *f, const vecD &v, CStr &name) { fprintf(f, "%s = [", name.c_str()); for (size_t i = 0; i < v.size(); i++) fprintf(f, "%g ", v[i]); fprintf(f, "];\n"); }
void Illustrate::__PrintVector(const vecD &v, CStr &name) { FILE* f = fopen(_S(name), "w"); CV_Assert(f != NULL); for (size_t i = 0; i < v.size(); i++) { fprintf(f, "%g\n", v[i]); } fclose(f); }
// load format(imgW, i) and add information to the back of imgs and lens void CmIllustr::LoadImgs(CStr &imgW, vecM &imgs, vecD &lens, int W, int H) { bool toRow = W > H; double crnt = -space; if (imgs.size()){ // There exist a predefined image for sketch lens.push_back(toRow ? H*imgs[0].cols*1./imgs[0].rows : W*imgs[0].rows*1./imgs[0].cols); crnt += lens[0] + space; } for (int i = 0; i < 500; i++){ string imgN = format(_S(imgW), i), inDir, maskN; vecS names; int subN = CmFile::GetNames(imgN, names, inDir); if (subN == 0) continue; Mat img = imread(inDir + names[0]); if (img.data == NULL){ printf("Can't load image file %-70s\n", _S(names[0])); continue; } if (subN > 1){ Mat mask1u = imread(inDir + names[1], CV_LOAD_IMAGE_GRAYSCALE), big1u; dilate(mask1u, big1u, Mat(), Point(-1, -1), 5); bitwise_xor(mask1u, big1u, mask1u); img.setTo(Scalar(0, 0, 255), mask1u); } lens.push_back(toRow ? H*img.cols*1./img.rows : W*img.rows*1./img.cols); imgs.push_back(img); crnt += lens[lens.size() - 1] + space; if (crnt >= max(H, W)) break; } int num = imgs.size(); if (num && abs(crnt - max(H,W)) > abs(crnt - lens[num - 1] - space - max(H,W))) imgs.resize(num - 1), lens.resize(num - 1); printf("%s: %d\n", _S(imgW), num); if (crnt < max(H, W)) { printf(_S(imgW + ": not enough images\n")); exit(0); } }
int Saliency::PrintVector(FILE *f, const vecD &v, const string &name, int maxNum) { fprintf(f, "%s = [", name.c_str()); maxNum = min(maxNum, (int)v.size()); int i; for (i = 0; i < maxNum; i++) if (v[i] > 0.001) // Very small recall is too much noisy (may due to compression) fprintf(f, "%g ", v[i]); else break; fprintf(f, "];\n"); return i; }
void CmSaliencyGC::GetCSD(vecD &_csd, vecD &_cD) { MergeGMMs(); vecD csd, cD; int num = (int)_pciM1f.size(); // Number of Gaussian Size imgSz = _pciM1f[0].size(); double centerX = imgSz.width / 2, centerY = imgSz.height / 2; cD.resize(num); vecD V(num), D(num); #pragma omp parallel for for (int i = 0; i < num; i++) V[i] = SpatialVar(_pciM1f[i], cD[i]); normalize(V, V, 0, 1, CV_MINMAX); normalize(cD, D, 0, 1, CV_MINMAX); csd.resize(num); for (int i = 0; i < num; i++) csd[i] = (1-V[i])*(1-D[i]); normalize(csd, csd, 0, 1, CV_MINMAX); _csd.resize(_NUM); _cD.resize(_NUM); for (int i = 0; i < _NUM; i++) _csd[i] = csd[_ClusteredIdx[i]], _cD[i] = cD[_ClusteredIdx[i]]; }
Mat CmIllustr::ArrangeImgs(vecM &imgs, vecD &len, int W, int H, bool toRow) { int imgN = (int)(imgs.size()), s = 0; CV_Assert(len.size() == imgN); double ratio, sumL = 0, err = 0; for (int i = 0; i < imgN; i++) sumL += len[i]; ratio = ((toRow ? W : H) - (imgN - 1) * space) / sumL; Mat dstImg(H, W, CV_8UC3); dstImg = Scalar(255, 255, 255); for (int i = 0; i < imgN; i++) { len[i] *= ratio; int l = cvRound(len[i] + err); Rect reg = toRow ? Rect(s, 0, l, H) : Rect(0, s, W, l); resize(imgs[i], dstImg(reg), reg.size()); err = len[i] + err - l; s += l + space; } CV_Assert(s - space == (toRow ? dstImg.cols : dstImg.rows)); return dstImg; }
// Return mean absolute error (MAE) double CmEvaluation::Evaluate_(CStr >ImgW, CStr &inDir, CStr& resExt, vecD &precision, vecD &recall, vecD &tpr, vecD &fpr) { vecS names; string truthDir, gtExt; int imgNum = CmFile::GetNamesNE(gtImgW, names, truthDir, gtExt); precision.resize(NUM_THRESHOLD, 0); recall.resize(NUM_THRESHOLD, 0); tpr.resize(NUM_THRESHOLD, 0); fpr.resize(NUM_THRESHOLD, 0); if (imgNum == 0){ printf("Can't load ground truth images %s\n", _S(gtImgW)); return 10^20; } else printf("Evaluating %d saliency maps ... \r", imgNum); double mea = 0; for (int i = 0; i < imgNum; i++){ if(i % 100 == 0) printf("Evaluating %03d/%d %-40s\r", i, imgNum, _S(names[i] + resExt)); Mat resS = imread(inDir + names[i] + resExt, CV_LOAD_IMAGE_GRAYSCALE); CV_Assert_(resS.data != NULL, ("Can't load saliency map: %s\n", _S(names[i] + resExt))); normalize(resS, resS, 0, 255, NORM_MINMAX); Mat gtFM = imread(truthDir + names[i] + gtExt, CV_LOAD_IMAGE_GRAYSCALE), gtBM; if (gtFM.data == NULL) continue; CV_Assert_(resS.size() == gtFM.size(), ("Saliency map and ground truth image size mismatch: %s\n", _S(names[i]))); compare(gtFM, 128, gtFM, CMP_GT); bitwise_not(gtFM, gtBM); double gtF = sum(gtFM).val[0]; double gtB = resS.cols * resS.rows * 255 - gtF; #pragma omp parallel for for (int thr = 0; thr < NUM_THRESHOLD; thr++){ Mat resM, tpM, fpM; compare(resS, thr * STEP, resM, CMP_GE); bitwise_and(resM, gtFM, tpM); bitwise_and(resM, gtBM, fpM); double tp = sum(tpM).val[0]; double fp = sum(fpM).val[0]; //double fn = gtF - tp; //double tn = gtB - fp; recall[thr] += tp/(gtF+EPS); double total = EPS + tp + fp; precision[thr] += (tp+EPS)/total; tpr[thr] += (tp + EPS) / (gtF + EPS); fpr[thr] += (fp + EPS) / (gtB + EPS); } gtFM.convertTo(gtFM, CV_32F, 1.0/255); resS.convertTo(resS, CV_32F, 1.0/255); cv::absdiff(gtFM, resS, resS); mea += sum(resS).val[0] / (gtFM.rows * gtFM.cols); } int thrS = 0, thrE = NUM_THRESHOLD, thrD = 1; for (int thr = thrS; thr != thrE; thr += thrD){ precision[thr] /= imgNum; recall[thr] /= imgNum; tpr[thr] /= imgNum; fpr[thr] /= imgNum; } return mea/imgNum; }