void emptyStacks(VVI &inp,STACK &sti,STACK &stj,int &val){ while(!sti.empty()){ int i = sti.top(); sti.pop(); int j = stj.top(); stj.pop(); if(inp[i][j]<val){ inp[i][j] = val; } } val = 0; }
REGION Acquisition::seedFill( REG_COLOR colorID, unsigned int u, unsigned int v) { #define canBePainted( colorID, u, v) (!analisedPixel(u,v) && calibracaoParam.getHardColor(ImBruta[v][u]) == colorID) static STACK s; REGION region; double su=0, sv=0, suu=0, svv=0, suv=0; int nPixel=0; unsigned int v1; unsigned int vMax=0,vMin=ImBruta.nlin(); unsigned int uMax=0,uMin=ImBruta.ncol(); bool expanLeft, expanRight; region.nPixel=0; region.colorID = colorID; if ( !canBePainted(colorID,u,v) ) return region; s.empty(); if (!s.push(u,v)) { cerr << "Buffer estourou 1!\n"; return region; } while(s.pop(u,v)) { v1 = v; while(v1>0 && canBePainted(colorID,u,v1-1)) v1--; expanLeft = expanRight = false; while(v1<ImBruta.nlin() && canBePainted(colorID,u,v1) ) { analisedPixel.setValue(u,v1,true); if(v1 < vMin) vMin = v1; if(v1 > vMax) vMax = v1; if(u < uMin) uMin = u; if(u > uMax) uMax = u; su += u; sv += v1; suu += u*u; svv += v1*v1; suv += u*v1; nPixel++; if(!expanLeft && u>0 && canBePainted(colorID,u-1,v1)) { if(!s.push(u-1,v1)) { cerr << "Buffer estourou 2!\n"; return region; } expanLeft = true; } else if(expanLeft && u>0 && !canBePainted(colorID,u-1,v1)) { expanLeft = false; } if(!expanRight && u<(ImBruta.ncol()-1) && canBePainted(colorID,u+1,v1)) { if(!s.push(u+1,v1)) { cerr << "Buffer estourou 3!\n"; return region; } expanRight = true; } else if(expanRight && u<(ImBruta.ncol()-1) && !canBePainted(colorID,u+1,v1)) { expanRight = false; } v1++; } } //testa se a regiao é uma linha vertical ou horizontal if((vMax-vMin) > LINE_THRESHOLD || (uMax-uMin) > LINE_THRESHOLD) return region; region.center.u() = su/nPixel; region.center.v() = sv/nPixel; region.nPixel = nPixel; double varu, varv, varuv; varu = suu/nPixel - (su/nPixel)*(su/nPixel); //a varv = svv/nPixel - (sv/nPixel)*(sv/nPixel); //c varuv = suv/nPixel - (su/nPixel)*(sv/nPixel); //b //testa se a regiao eh simetrica, ou seja, nao tem como calcular o angulo do segundo momento. double lim_zero = 0.001; if(fabs(varuv) < lim_zero && fabs(varu-varv) < lim_zero){ //a figura é simetrica region.symetric = true; region.orientation = 0.0; }else{ region.symetric = false; region.orientation = -atan2(varuv,varu-varv)/2.0; } return region; }
// a simple client to drive the stack // one improvement may be to have the client maintain a free list of unused nodes int main() { STACK s; STACK_NODE *p; bool done = false; int option, value; while( !done ) { cout << "1) push\n2) pop\n3) peek\n4) pop all\n5) init\n" << "6) check if empty\n7) quit\n\nEnter option : " << flush; cin >> option; switch( option ) { case 1: cout << "Enter value to push : " << flush; cin >> value; p = new STACK_NODE; p->key = value; s.push( p ); break; case 2: if( !s.IsEmpty() ) { p = s.pop(); value = p->key; delete p; cout << "Popped " << value << endl; } else { cout << "Nothing to pop!" << endl; } break; case 3: if( !s.IsEmpty() ) { // cast off const-ness (but DON't mess with the data!) p = const_cast<STACK_NODE *>(s.peek()); value = p->key; cout << "Peeked " << value << endl; } else { cout << "Nothing to peek!" << endl; } break; case 4: while( !s.IsEmpty() ) { p = s.pop(); value = p->key; delete p; cout << "Popped " << value << endl; } cout << "Stack is now empty" << endl; break; case 5: cout << "Initializing..." << endl; s.init(); break; case 6: cout << "IsEmpty returns " << ( s.IsEmpty() ? "true" : "false" ) << endl; break; case 7: done = true; break; default: cout << "What?" << endl; } } return 0; }