Mat CmShow::HistBins(CMat& color3f, CMat& val, CStr& title, bool descendShow, CMat &with) { // Prepare data int H = 300, spaceH = 6, barH = 10, n = color3f.cols; CV_Assert(color3f.size() == val.size() && color3f.rows == 1); Mat binVal1i, binColor3b, width1i; if (with.size() == val.size()) with.convertTo(width1i, CV_32S, 400/sum(with).val[0]); // Default shown width else width1i = Mat(1, n, CV_32S, Scalar(600.0/(val.cols*val.rows))); // Default bin width = 10 int W = cvRound(sum(width1i).val[0]); color3f.convertTo(binColor3b, CV_8UC3, 255); double maxVal, minVal; minMaxLoc(val, &minVal, &maxVal); val.convertTo(binVal1i, CV_32S, H/max(maxVal, -minVal)); Size szShow(W, H + spaceH + barH); szShow.height += minVal < 0 && !descendShow ? H + spaceH : 0; Mat showImg3b(szShow, CV_8UC3, WHITE); int* binH = (int*)(binVal1i.data); Vec3b* binColor = (Vec3b*)(binColor3b.data); int* binW = (int*)(width1i.data); vector<CostiIdx> costIdx(n); if (descendShow) { for (int i = 0; i < n; i++) costIdx[i] = make_pair(binH[i], i); sort(costIdx.begin(), costIdx.end(), std::greater<CostiIdx>()); } // Show image for (int i = 0, x = 0; i < n; i++) { int idx = descendShow ? costIdx[i].second : i; int h = descendShow ? abs(binH[idx]) : binH[idx]; Scalar color(binColor[idx]); Rect reg(x, H + spaceH, binW[idx], barH); showImg3b(reg) = color; // Draw bar rectangle(showImg3b, reg, BLACK); reg.height = abs(h); reg.y = h >= 0 ? H - h : H + 2 * spaceH + barH; showImg3b(reg) = color; rectangle(showImg3b, reg, BLACK); x += binW[idx]; } putText(showImg3b, format("Min = %g, Max = %g", minVal, maxVal), Point(5, 20), CV_FONT_HERSHEY_PLAIN, 1, CV_RGB(255,0,0)); SaveShow(showImg3b, title); return showImg3b; }
void BenchMarkLatex::printModelRanking(CStr outName, CMat &meanF1d, CMat &maxF1d, CMat &cutAdp1d, CMat &cutSC1d, CMat &auc1d, CMat &mae1d) { CV_Assert(meanF1d.size == cutAdp1d.size && cutAdp1d.size == cutSC1d.size); CV_Assert(meanF1d.size() == Size(_numDb, _numMethod)); Mat RnkMean1i = getRankIdx(meanF1d), RnkAdp1i = getRankIdx(cutAdp1d), RnkSc1i = getRankIdx(cutSC1d); Mat RnkMax1i = getRankIdx(maxF1d), RnkAuc1i = getRankIdx(auc1d), RnkMae1i = getRankIdx(mae1d, false); const int NUM_ROW = 5; // Number of rows in the table const char* rowDes[NUM_ROW] = { "Max", "AUC", "MAE", "AdpT", "SCut" }; bool decentOrder[NUM_ROW]; memset(decentOrder, 0, sizeof(bool) * NUM_ROW); Mat dbTable = Mat::zeros(NUM_ROW, _numMethod, CV_64F); for (int m = 0; m < _numMethod; m++){ for (int d = 0; d < _numDb; d++) { dbTable.at<double>(0, m) += RnkMax1i.at<int>(m, d) + 1; dbTable.at<double>(1, m) += RnkAuc1i.at<int>(m, d) + 1; dbTable.at<double>(2, m) += RnkMae1i.at<int>(m, d) + 1; dbTable.at<double>(3, m) += RnkAdp1i.at<int>(m, d) + 1; dbTable.at<double>(4, m) += RnkSc1i.at<int>(m, d) + 1; } } printMatTransport(dbTable, outName + "D.tex", rowDes, decentOrder); Mat rnkDb = getRankIdx(dbTable.t(), false).t() + 1; printMatTransport(rnkDb, outName + ".tex", rowDes, decentOrder); }
Mat CmSaliencyRC::GetLC(CMat &img3f) { Mat img; cvtColor(img3f, img, CV_BGR2GRAY); img.convertTo(img, CV_8U, 255); double f[256], s[256]; memset(f, 0, 256*sizeof(double)); memset(s, 0, 256*sizeof(double)); for (int r = 0; r < img.rows; r++){ byte* data = img.ptr<byte>(r); for (int c = 0; c < img.cols; c++) f[data[c]] += 1; } for (int i = 0; i < 256; i++) for (int j = 0; j < 256; j++) s[i] += abs(i - j) * f[j]; Mat sal1f(img3f.size(), CV_64F); for (int r = 0; r < img.rows; r++){ byte* data = img.ptr<byte>(r); double* sal = sal1f.ptr<double>(r); for (int c = 0; c < img.cols; c++) sal[c] = s[data[c]]; } normalize(sal1f, sal1f, 0, 1, NORM_MINMAX, CV_32F); return sal1f; }
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]); } } }
Mat CmSaliencyRC::GetSR(CMat &img3f) { Size sz(64, 64); Mat img1f[2], sr1f, cmplxSrc2f, cmplxDst2f; cvtColor(img3f, img1f[1], CV_BGR2GRAY); resize(img1f[1], img1f[0], sz, 0, 0, CV_INTER_AREA); img1f[1] = Mat::zeros(sz, CV_32F); merge(img1f, 2, cmplxSrc2f); dft(cmplxSrc2f, cmplxDst2f); AbsAngle(cmplxDst2f, img1f[0], img1f[1]); log(img1f[0], img1f[0]); blur(img1f[0], sr1f, Size(3, 3)); sr1f = img1f[0] - sr1f; exp(sr1f, sr1f); GetCmplx(sr1f, img1f[1], cmplxDst2f); dft(cmplxDst2f, cmplxSrc2f, DFT_INVERSE | DFT_SCALE); split(cmplxSrc2f, img1f); pow(img1f[0], 2, img1f[0]); pow(img1f[1], 2, img1f[1]); img1f[0] += img1f[1]; GaussianBlur(img1f[0], img1f[0], Size(3, 3), 0); normalize(img1f[0], img1f[0], 0, 1, NORM_MINMAX); resize(img1f[0], img1f[1], img3f.size(), 0, 0, INTER_CUBIC); return img1f[1]; }
void GrabCutMF::illuProb(CMat sampleDf, CmGMM &bGMM, CmGMM &fGMM, CStr &nameNE) { vector<Mat> pciF, pciB; Mat pI = Mat::zeros(sampleDf.size(), CV_32F); fGMM.GetProbsWN(sampleDf, pciF); bGMM.GetProbsWN(sampleDf, pciB); int fK = fGMM.K(), bK = bGMM.K(); assert(fGMM.maxK() == bGMM.maxK()); for (int i = 0; i < fK; i++) add(pciF[i], pI, pI); for (int i = 0; i < bK; i++) add(pciB[i], pI, pI); Mat tmpShow; for (int i = 0; i < fK; i++){ divide(pciF[i], pI, pciF[i]); imwrite(nameNE + format("_F%d.png", i), pciF[i]*255); } for (int i = 0; i < bK; i++){ divide(pciB[i], pI, pciB[i]); imwrite(nameNE + format("_B%d.png", i), pciB[i]*255); } for (int i = fK; i < fGMM.maxK(); i++) CmFile::WriteNullFile(nameNE + format("_F%d.nul", i)); for (int i = bK; i < bGMM.maxK(); i++) CmFile::WriteNullFile(nameNE + format("_B%d.nul", i)); }
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); }
// Show a label map. labelNum: how many number of random colors used for show, use default colors if is -1 Mat CmShow::Label(CMat& label1i, CStr& title, int labelNum, bool showIdx) { bool useRandom = labelNum > 0; labelNum = useRandom ? labelNum : COLOR_NU_NO_GRAY; vector<Vec3b> colors(labelNum); if (useRandom) for (size_t i = 0; i < colors.size(); i++) colors[i] = RandomColor(); else for (size_t i = 0; i < colors.size(); i++) colors[i] = gColors[i]; Mat showImg = Mat::zeros(label1i.size(), CV_8UC3); for (int y = 0; y < label1i.rows; y++) { Vec3b* showD = showImg.ptr<Vec3b>(y); const int* label = label1i.ptr<int>(y); for (int x = 0; x < label1i.cols; x++) if (label[x] >= 0) { showD[x] = colors[label[x] % labelNum]; if (showIdx) showD[x][2] = (byte)(label[x]); } } SaveShow(showImg, title); return showImg; }
Mat CmShow::Complex(CMat& _cmplx, CStr& title, float minMagShowAng, int flag) { CV_Assert(_cmplx.channels() == 2 && _cmplx.data != NULL); Mat ang(_cmplx.size(), CV_32FC1), mag(_cmplx.size(), CV_32FC1), cmplx; _cmplx.convertTo(cmplx, CV_32F); for (int y = 0; y < cmplx.rows; y++) { float* cpV = cmplx.ptr<float>(y); float* angV = ang.ptr<float>(y); float* magV = mag.ptr<float>(y); for (int x = 0; x < cmplx.cols; x++, cpV+=2) { magV[x] = sqrt(cpV[0] * cpV[0] + cpV[1] * cpV[1]); angV[x] = cvFastArctan(cpV[1], cpV[0]); } } return Complex(ang, mag, title, minMagShowAng, flag); }
void CmShow::Pseudocolor(CMat& matfd1, CStr& title) { Mat hsvMat[3], hsvM; matfd1.convertTo(hsvMat[0], CV_32FC1, -240, 240); hsvMat[1] = hsvMat[2] = Mat::ones(matfd1.size(), CV_32F); merge(hsvMat, 3, hsvM); cvtColor(hsvM, hsvM, CV_HSV2BGR); SaveShow(hsvM, title); }
Mat CmSaliencyRC::GetBorderReg(CMat &idx1i, int regNum, double ratio, double thr) { // Variance of x and y vecD vX(regNum), vY(regNum); int w = idx1i.cols, h = idx1i.rows;{ vecD mX(regNum), mY(regNum), n(regNum); // Mean value of x and y, pixel number of region for (int y = 0; y < idx1i.rows; y++){ const int *idx = idx1i.ptr<int>(y); for (int x = 0; x < idx1i.cols; x++, idx++) mX[*idx] += x, mY[*idx] += y, n[*idx]++; } for (int i = 0; i < regNum; i++) mX[i] /= n[i], mY[i] /= n[i]; for (int y = 0; y < idx1i.rows; y++){ const int *idx = idx1i.ptr<int>(y); for (int x = 0; x < idx1i.cols; x++, idx++) vX[*idx] += abs(x - mX[*idx]), vY[*idx] += abs(y - mY[*idx]); } for (int i = 0; i < regNum; i++) vX[i] = vX[i]/n[i] + EPS, vY[i] = vY[i]/n[i] + EPS; } // Number of border pixels in x and y border region vecI xbNum(regNum), ybNum(regNum); int wGap = cvRound(w * ratio), hGap = cvRound(h * ratio); vector<Point> bPnts; { ForPoints2(pnt, 0, 0, w, hGap) // Top region ybNum[idx1i.at<int>(pnt)]++, bPnts.push_back(pnt); ForPoints2(pnt, 0, h - hGap, w, h) // Bottom region ybNum[idx1i.at<int>(pnt)]++, bPnts.push_back(pnt); ForPoints2(pnt, 0, 0, wGap, h) // Left region xbNum[idx1i.at<int>(pnt)]++, bPnts.push_back(pnt); ForPoints2(pnt, w - wGap, 0, w, h) xbNum[idx1i.at<int>(pnt)]++, bPnts.push_back(pnt); } Mat bReg1u(idx1i.size(), CV_8U);{ // likelihood map of border region double xR = 1.0/(4*hGap), yR = 1.0/(4*wGap); vector<byte> regL(regNum); // likelihood of each region belongs to border background for (int i = 0; i < regNum; i++) { double lk = xbNum[i] * xR / vY[i] + ybNum[i] * yR / vX[i]; regL[i] = lk/thr > 1 ? 255 : 0; //saturate_cast<byte>(255 * lk / thr); } for (int r = 0; r < h; r++) { const int *idx = idx1i.ptr<int>(r); byte* maskData = bReg1u.ptr<byte>(r); for (int c = 0; c < w; c++, idx++) maskData[c] = regL[*idx]; } } for (size_t i = 0; i < bPnts.size(); i++) bReg1u.at<byte>(bPnts[i]) = 255; return bReg1u; }
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); }
Mat CmSaliencyRC::Get(CMat &img3f, GET_SAL_FUNC fun, int _wkSize) { Mat sal; double ratio = _wkSize * 1.0 / max(img3f.rows, img3f.cols); Size wkSize(cvRound(img3f.cols * ratio), cvRound(img3f.rows * ratio)); Mat wkImg, wkSal; resize(img3f, wkImg, wkSize, 0, 0, INTER_AREA); wkSal = fun(wkImg); resize(wkSal, sal, img3f.size(), 0, 0, INTER_CUBIC); return sal; }
Mat GrabCutMF::getGrabMask(CMat &img3u, Rect rect) { // Initialize flood fill queue<Point> selectedPnts; const int _h = img3u.rows, _w = img3u.cols, BW = 5; {// If not connected to image border, expand selection border unless stopped by edges Point rowT(rect.x, rect.y), rowB(rect.x, rect.y + rect.height - 1); Point colL(rect.x, rect.y), colR(rect.x + rect.width - 1, rect.y); if (rect.x >= BW) // Expand left edge for (int y = 0; y < rect.height; y++, colL.y++) selectedPnts.push(colL); else rect.x = BW; if (rect.y >= BW) // Expand top edge for (int x = 0; x < rect.width; x++, rowT.x++) selectedPnts.push(rowT); else rect.y = BW; if (rect.x + rect.width + BW <= _w) // Expand right edge for (int y = 0; y < rect.height; y++, colR.y++) selectedPnts.push(colR); else rect.width = _w - rect.x - BW; if (rect.y + rect.height + BW <= _h) // Expand bottom edge for (int x = 0; x < rect.width; x++, rowB.x++) selectedPnts.push(rowB); else rect.height = _h - rect.y - BW; } Mat mask1u(img3u.size(), CV_8U); memset(mask1u.data, 255, mask1u.step.p[0] * mask1u.rows); mask1u(rect) = Scalar(0); Mat edge1u; CmCv::CannySimpleRGB(img3u, edge1u, 120, 1200, 5); dilate(edge1u, edge1u, Mat(), Point(-1, -1), 3); //rectangle(edge1u, rect, Scalar(128)); //imwrite(sameNameNE + "_Selection.png", edge1u); // Flood fill while (!selectedPnts.empty()){ Point crntPnt = selectedPnts.front(); mask1u.at<byte>(crntPnt) = 255; selectedPnts.pop(); for (int i = 0; i < 4; i++){ Point nbrPnt = crntPnt + DIRECTION4[i]; if (CHK_IND(nbrPnt) && mask1u.at<byte>(nbrPnt) == 0 && edge1u.at<byte>(nbrPnt) == 0) mask1u.at<byte>(nbrPnt) = 255, selectedPnts.push(nbrPnt); } } cv::Mat temp(mask1u(Rect(rect.x + 1, rect.y + 1, rect.width - 2, rect.height - 2))); CmCv::rubustifyBorderMask(temp); return mask1u; }
Mat CmSaliencyRC::GetRC(CMat &img3f, CMat ®Idx1i, int regNum, double sigmaDist) { Mat colorIdx1i, regSal1v, tmp, color3fv; int QuatizeNum = Quantize(img3f, colorIdx1i, color3fv, tmp); if (QuatizeNum == 2){ printf("QuatizeNum == 2, %d: %s\n", __LINE__, __FILE__); Mat sal; compare(colorIdx1i, 1, sal, CMP_EQ); sal.convertTo(sal, CV_32F, 1.0/255); return sal; } if (QuatizeNum <= 2) // Color quantization return Mat::zeros(img3f.size(), CV_32F); cvtColor(color3fv, color3fv, CV_BGR2Lab); vector<Region> regs(regNum); BuildRegions(regIdx1i, regs, colorIdx1i, color3fv.cols); RegionContrast(regs, color3fv, regSal1v, sigmaDist); Mat sal1f = Mat::zeros(img3f.size(), CV_32F); cv::normalize(regSal1v, regSal1v, 0, 1, NORM_MINMAX, CV_32F); float* regSal = (float*)regSal1v.data; for (int r = 0; r < img3f.rows; r++){ const int* regIdx = regIdx1i.ptr<int>(r); float* sal = sal1f.ptr<float>(r); for (int c = 0; c < img3f.cols; c++) sal[c] = regSal[regIdx[c]]; } Mat bdReg1u = GetBorderReg(regIdx1i, regNum, 0.02, 0.4); sal1f.setTo(0, bdReg1u); SmoothByHist(img3f, sal1f, 0.1f); SmoothByRegion(sal1f, regIdx1i, regNum); sal1f.setTo(0, bdReg1u); GaussianBlur(sal1f, sal1f, Size(3, 3), 0); return sal1f; }
// img3f and src3f are BGR void CmColorQua::S_Recover(CMat& idx1i, Mat& img3f, int method, CMat &src3f) { Mat color3f; vecI colorNum; S_BinInf(idx1i, color3f, colorNum, method, src3f); Vec3f* color = (Vec3f*)(color3f.data); img3f.create(idx1i.size(), CV_32FC3); for (int r = 0; r < idx1i.rows; r++) { const int *idx = idx1i.ptr<int>(r); Vec3f *img = img3f.ptr<Vec3f>(r); for (int c = 0; c < idx1i.cols; c++) img[c] = color[idx[c]]; } }
void CmColorQua::D_Recover(CMat& idx1i, Mat &img3f, CMat &color3f) { CV_Assert(idx1i.data != NULL); img3f.create(idx1i.size(), CV_32FC3); Vec3f* color = (Vec3f*)(color3f.data); for (int y = 0; y < idx1i.rows; y++) { Vec3f* imgData = img3f.ptr<Vec3f>(y); const int* idx = idx1i.ptr<int>(y); for (int x = 0; x < idx1i.cols; x++) { imgData[x] = color[idx[x]]; CV_Assert(idx[x] < color3f.cols); } } }
Mat CmShow::Complex(CMat& _ang, CMat& _mag, CStr& title, float minMagShowAng, int flag) { CV_Assert(_ang.size() == _mag.size() && _ang.channels() == 1 && _mag.channels() == 1); Mat ang, mag; _ang.convertTo(ang, CV_32F); _mag.convertTo(mag, CV_32F); if (flag & SHOW_MAG_LOG) { cv::log(mag + 1, mag); CmCv::FFTShift(mag); } normalize(mag, mag, 0, 255, NORM_MINMAX, CV_8U); minMagShowAng *= 255; int rows = ang.rows, cols = ang.cols; Mat img8U3C(rows, flag & MAG_AS_SAT ? cols : cols * 2, CV_8UC3); if (!(flag & MAG_AS_SAT)) cvtColor(mag, img8U3C(Rect(cols, 0, cols, rows)), CV_GRAY2BGR); Mat showAng = img8U3C(Rect(0, 0, cols, rows)); Ornt2HueFunc ornt2HueFunc = flag & ORNT2HUE_SYM4 ? Ornt2HueSym4 : Ornt2Hue; for (int y = 0; y < rows; y++) { float* angV = ang.ptr<float>(y); byte* magV = mag.ptr<byte>(y); byte* angShow = showAng.ptr<byte>(y); for (int x = 0; x < cols; x++, angShow += 3) { if (magV[x] < minMagShowAng) continue; angShow[0] = ornt2HueFunc(angV[x]); angShow[1] = flag & MAG_AS_SAT ? magV[x] : 255; angShow[2] = 255; } } cvtColor(showAng, showAng, CV_HSV2BGR); SaveShow(img8U3C, title); return img8U3C; }
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]); } } }
void CmColorQua::Show(CMat &counts1d, CStr title, Mat &show3f, int method) { int n = binNum[method]; CV_Assert(method >= 0 && method < S_Q_NUM && counts1d.size() == Size(n, 1)); Mat color3f(1, n, CV_32FC3); Vec3f* colors = (Vec3f*)(color3f.data); for (int i = 0; i < n; i++) { switch (method) { case 0: SR_BGR(i, colors[i]); break; case 1: SR_HSV(i, colors[i]); break; case 2: SR_Lab(i, colors[i]); break; } } switch (method) { case 1: cvtColor(color3f, color3f, CV_HSV2BGR); break; case 2: cvtColor(color3f, color3f, CV_Lab2BGR); break; } //CmShow::HistBins(color3f, counts1d, title); }
Mat CmSaliencyRC::GetHC(CMat &img3f) { // Quantize colors and Mat idx1i, binColor3f, colorNums1i, _colorSal; Quantize(img3f, idx1i, binColor3f, colorNums1i); cvtColor(binColor3f, binColor3f, CV_BGR2Lab); GetHC(binColor3f, colorNums1i, _colorSal); float* colorSal = (float*)(_colorSal.data); Mat salHC1f(img3f.size(), CV_32F); for (int r = 0; r < img3f.rows; r++){ float* salV = salHC1f.ptr<float>(r); int* _idx = idx1i.ptr<int>(r); for (int c = 0; c < img3f.cols; c++) salV[c] = colorSal[_idx[c]]; } GaussianBlur(salHC1f, salHC1f, Size(3, 3), 0); normalize(salHC1f, salHC1f, 0, 1, NORM_MINMAX); return salHC1f; }
// 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; }
int CmSaliencyRC::Quantize(CMat& img3f, Mat &idx1i, Mat &_color3f, Mat &_colorNum, double ratio, const int clrNums[3]) { float clrTmp[3] = {clrNums[0] - 0.0001f, clrNums[1] - 0.0001f, clrNums[2] - 0.0001f}; int w[3] = {clrNums[1] * clrNums[2], clrNums[2], 1}; CV_Assert(img3f.data != NULL); idx1i = Mat::zeros(img3f.size(), CV_32S); int rows = img3f.rows, cols = img3f.cols; if (img3f.isContinuous() && idx1i.isContinuous()){ cols *= rows; rows = 1; } // Build color pallet map<int, int> pallet; for (int y = 0; y < rows; y++) { const float* imgData = img3f.ptr<float>(y); int* idx = idx1i.ptr<int>(y); for (int x = 0; x < cols; x++, imgData += 3) { idx[x] = (int)(imgData[0]*clrTmp[0])*w[0] + (int)(imgData[1]*clrTmp[1])*w[1] + (int)(imgData[2]*clrTmp[2]); pallet[idx[x]] ++; } } // Find significant colors int maxNum = 0; { int count = 0; vector<pair<int, int>> num; // (num, color) pairs in num num.reserve(pallet.size()); for (map<int, int>::iterator it = pallet.begin(); it != pallet.end(); it++) num.push_back(pair<int, int>(it->second, it->first)); // (color, num) pairs in pallet sort(num.begin(), num.end(), std::greater<pair<int, int>>()); maxNum = (int)num.size(); int maxDropNum = cvRound(rows * cols * (1-ratio)); for (int crnt = num[maxNum-1].first; crnt < maxDropNum && maxNum > 1; maxNum--) crnt += num[maxNum - 2].first; maxNum = min(maxNum, 256); // To avoid very rarely case if (maxNum <= 10) maxNum = min(10, (int)num.size()); pallet.clear(); for (int i = 0; i < maxNum; i++) pallet[num[i].second] = i; vector<Vec3i> color3i(num.size()); for (unsigned int i = 0; i < num.size(); i++) { color3i[i][0] = num[i].second / w[0]; color3i[i][1] = num[i].second % w[0] / w[1]; color3i[i][2] = num[i].second % w[1]; } for (unsigned int i = maxNum; i < num.size(); i++) { int simIdx = 0, simVal = INT_MAX; for (int j = 0; j < maxNum; j++) { int d_ij = vecSqrDist<int, 3>(color3i[i], color3i[j]); if (d_ij < simVal) simVal = d_ij, simIdx = j; } pallet[num[i].second] = pallet[num[simIdx].second]; } } _color3f = Mat::zeros(1, maxNum, CV_32FC3); _colorNum = Mat::zeros(_color3f.size(), CV_32S); Vec3f* color = (Vec3f*)(_color3f.data); int* colorNum = (int*)(_colorNum.data); for (int y = 0; y < rows; y++) { const Vec3f* imgData = img3f.ptr<Vec3f>(y); int* idx = idx1i.ptr<int>(y); for (int x = 0; x < cols; x++) { idx[x] = pallet[idx[x]]; color[idx[x]] += imgData[x]; colorNum[idx[x]] ++; } } for (int i = 0; i < _color3f.cols; i++) color[i] /= (float)colorNum[i]; return _color3f.cols; }