Arv* moveDirRed(Arv* arv) { trocarCor(arv); if(cor(arv->esq->esq) == RED) { arv = rDir(arv); trocaCor(arv); } return arv; }
Arv* moveEsqRed(Arv* arv) { trocarCor(arv); if(cor(arv->dir->esq) == RED) { arv->dir = rDir(arv->dir); arv = rEsq(arv); trocarCor(arv); } return arv; }
Arv* auxInsere(Arv* no, int valor,int* resp, int *chave) { if(no == NULL) { Arv* novo = (Arv*) malloc(sizeof(Arv)); if(novo == NULL) { *resp = 0; return NULL; } novo->val = valor; novo->chave = *chave; novo->esq = NULL; novo->dir = NULL; novo->cor = RED; *resp = 1; return novo; } if(valor == no->val) { *resp = 0; } else { if(valor > no->val) { no->dir = auxInsere(no->dir,valor,resp, chave); } else { no->esq = auxInsere(no->esq,valor,resp, chave); } } if((cor(no->dir) == RED) && (cor(no->esq) == BLACK)) { no = rEsq(no); } if((cor(no->esq) == RED) && (cor(no->esq->esq) == RED)) { no = rDir(no); } if((cor(no->esq) == RED) && (cor(no->dir) == RED)) { trocarCor(no); } return no; }
// ###################################################################### Image<float> ContourBoundaryDetector::getRidge (std::vector<Image<float> > gradImg, int r) { Image<float> gradImgX = gradImg[0]; Image<float> gradImgY = gradImg[1]; int w = gradImg[0].getWidth(); int h = gradImg[0].getHeight(); Image<float> ridgeImg(w,h,NO_INIT); std::vector<float> dx(NUM_GRADIENT_DIRECTIONS); std::vector<float> dy(NUM_GRADIENT_DIRECTIONS); for(uint k = 0; k < NUM_GRADIENT_DIRECTIONS; k++) { dx[k] = cos(k*2*M_PI/NUM_GRADIENT_DIRECTIONS); dy[k] = sin(k*2*M_PI/NUM_GRADIENT_DIRECTIONS); } // threshold the gradient image std::vector<std::vector<Image<float> > > dVin(NUM_GRADIENT_DIRECTIONS); for(uint k = 0; k < NUM_GRADIENT_DIRECTIONS; k++) dVin[k] = std::vector<Image<float> >(2); for(uint k = 0; k < NUM_GRADIENT_DIRECTIONS; k++) { dVin[k][0] = Image<float>(w,h,NO_INIT); dVin[k][1] = Image<float>(w,h,NO_INIT); for(int i = 0; i < w; i++) { for(int j = 0; j < h; j++) { float x = 0.0; float y = 0.0; int ii = int(i + r*dx[k]); int jj = int(j + r*dy[k]); if(ii < 0) ii = -ii; if(jj < 0) jj = -jj; if(ii >= w) ii = 2*w - 2 - ii; if(jj >= h) jj = 2*h - 2 - jj; float vX = gradImgX.getVal(ii,jj); float vY = gradImgY.getVal(ii,jj); if((vX*dx[k] + vY*dy[k]) < 0.0) { x = vX; y = vY; } dVin[k][0].setVal(i,j, x); dVin[k][1].setVal(i,j, y); } } } itsDVin = dVin; std::vector<Image<float> > rDir (NUM_GRADIENT_DIRECTIONS); Image<float> rDirIndex(w,h,NO_INIT); // calculate the geometric and arithmetic ridge direction // and sum the two together for(uint k = 0; k < NUM_GRADIENT_DIRECTIONS; k++) { rDir[k] = Image<float>(w,h,NO_INIT); for(int i = 0; i < w; i++) { for(int j = 0; j < h; j++) { float x1 = dVin[k][0].getVal(i,j); float y1 = dVin[k][1].getVal(i,j); uint k2 = k + NUM_RIDGE_DIRECTIONS; if(k >= NUM_RIDGE_DIRECTIONS) k2 = k - NUM_RIDGE_DIRECTIONS/2; float x2 = dVin[k2][0].getVal(i,j); float y2 = dVin[k2][1].getVal(i,j); float gVal = -(x1*x2 + y1*y2); if(gVal < 0.0) gVal = 0.0; else gVal = pow(gVal, 0.5); // float ax = x2 - x1; // float ay = y2 - y1; // float aVal = pow(ax*ax + ay*ay, 0.5)/ 2.0; // rDir[k].setVal(i,j, gVal + aVal); rDir[k].setVal(i,j, gVal); } } } itsRidgeDirection = rDir; std::vector<Image<float> > rDirMax(NUM_RIDGE_DIRECTIONS); for(uint k = 0; k < NUM_RIDGE_DIRECTIONS; k++) rDirMax[k] = Image<float>(w,h,ZEROS); // get the maximum among the directions for(int i = 0; i < w; i++) { for(int j = 0; j < h; j++) { float max = 0.0; int maxk = -1; for(uint k = 0; k < NUM_RIDGE_DIRECTIONS; k++) { float val = rDir[k].getVal(i,j); if(val > max) { max = val; maxk = k; } } ridgeImg.setVal(i,j, max); rDirIndex.setVal(i,j, maxk); if(maxk != -1) rDirMax[maxk].setVal(i,j, max); } } itsRidgeDirectionIndex = rDirIndex; itsRidgeDirectionMax = rDirMax; return ridgeImg; }