/* computes current energy */ int Match::BVZ_ComputeEnergy() { int k; Coord p, d, q, dq; E = 0; for (p.y=0; p.y<im_size.y; p.y++) for (p.x=0; p.x<im_size.x; p.x++) { d = Coord(IMREF(x_left, p), IMREF(y_left, p)); E += BVZ_data_penalty(p, d); for (k=0; k<NEIGHBOR_NUM; k++) { q = p + NEIGHBORS[k]; if (q>=Coord(0,0) && q<im_size) { dq = Coord(IMREF(x_left, q), IMREF(y_left, q)); E += BVZ_smoothness_penalty(p, q, d, dq); } } } return E; }
double PortraitCut::BVZ_ComputeDataOnly() { double E=0; int i,j,index=0; for (j=0; j<_h; j++) for (i=0; i<_w; i++, ++index) { Coord coord(i,j); E += BVZ_data_penalty(coord,_labels[index]); } //assert(_finite(E) && !_isnan(E)); return E; }
double PortraitCut::BVZ_ComputeEnergy() { double E=0; int i,j,index=0, k; Coord np; for (j=0; j<_h; j++) for (i=0; i<_w; i++, ++index) { Coord coord(i,j); E += BVZ_data_penalty(coord,_labels[index]); for (k=0; k<(int)NEIGHBOR_NUM; k++){ np = coord + NEIGHBORS[k]; if (np>=Coord(0,0) && np<_size) E += BVZ_interaction_penalty(coord,np,_labels[index], _labels[CINDEX(np)]); } } //assert(_finite(E) && !_isnan(E)); return E; }
void Match::BVZ_Expand(Coord a) { Coord p, d, q, dq; Energy::Var var, qvar; int E_old, E00, E0a, Ea0; int k; /* node_vars stores variables corresponding to nodes */ Energy *e = new Energy(BVZ_error_function); /* initializing */ for (p.y=0; p.y<im_size.y; p.y++) for (p.x=0; p.x<im_size.x; p.x++) { d = Coord(IMREF(x_left, p), IMREF(y_left, p)); if (a == d) { IMREF(node_vars, p) = VAR_ACTIVE; e -> add_constant(BVZ_data_penalty(p, d)); } else { IMREF(node_vars, p) = var = e -> add_variable(); e -> ADD_TERM1(var, BVZ_data_penalty(p, d), BVZ_data_penalty(p, a)); } } for (p.y=0; p.y<im_size.y; p.y++) for (p.x=0; p.x<im_size.x; p.x++) { d = Coord(IMREF(x_left, p), IMREF(y_left, p)); var = (Energy::Var) IMREF(node_vars, p); /* smoothness term */ for (k=0; k<NEIGHBOR_NUM; k++) { q = p + NEIGHBORS[k]; if ( ! ( q>=Coord(0,0) && q<im_size ) ) continue; qvar = (Energy::Var) IMREF(node_vars, q); dq = Coord(IMREF(x_left, q), IMREF(y_left, q)); if (var != VAR_ACTIVE && qvar != VAR_ACTIVE) E00 = BVZ_smoothness_penalty(p, q, d, dq); if (var != VAR_ACTIVE) E0a = BVZ_smoothness_penalty(p, q, d, a); if (qvar != VAR_ACTIVE) Ea0 = BVZ_smoothness_penalty(p, q, a, dq); if (var != VAR_ACTIVE) { if (qvar != VAR_ACTIVE) e -> ADD_TERM2(var, qvar, E00, E0a, Ea0, 0); else e -> ADD_TERM1(var, E0a, 0); } else { if (qvar != VAR_ACTIVE) e -> ADD_TERM1(qvar, Ea0, 0); else {} } } } E_old = E; E = e -> minimize(); if (E < E_old) { for (p.y=0; p.y<im_size.y; p.y++) for (p.x=0; p.x<im_size.x; p.x++) { var = (Energy::Var) IMREF(node_vars, p); if (var!=VAR_ACTIVE && e->get_var(var)==VALUE1) { IMREF(x_left, p) = a.x; IMREF(y_left, p) = a.y; } } } delete e; }
double PortraitCut::BVZ_Expand(ushort a, double E_old) { Coord p, np; ushort l, nl; Graph *g; float delta, P_00, P_0a, P_a0; Graph::node_id index, nindex; int k, ind=0; double E; /* indeces_a stores node indeces */ /* D_a sto res penalties for assigning label a */ g = new Graph(BVZ_error_function); /* initializing */ E = 0.; for (p.y=0; p.y<_h; p.y++) for (p.x=0; p.x<_w; p.x++, ++ind) { l = _labels[ind]; if (a == l) // 和原始的label一样 { IMREF(indeces_a, p) = INDEX_ACTIVE; //返回点p在graph中的节点索引,默认为0 E += BVZ_data_penalty(p, l); continue; } // 而void *则不同,任何类型的指针都可以直接赋值给它,无需进行强制类型转换://void *p1; //int *p2; // p1 = p2 //label 不一样的话 IMREF(indeces_a, p) = g -> add_node(); delta = BVZ_data_penalty(p, l); IMREF(D_a, p) = BVZ_data_penalty(p, a) - delta; E += delta; } ind=0; for (p.y=0; p.y<_h; p.y++) for (p.x=0; p.x<_w; p.x++, ++ind) { l = _labels[ind]; index = (Graph::node_id) IMREF(indeces_a, p); /* adding interactions */ for (k=0; k<(int)NEIGHBOR_NUM; k++) { np = p + NEIGHBORS[k]; if ( ! ( np>=Coord(0,0) && np<_size ) ) continue; //HUM nl = _labels[CINDEX(np)]; nindex = (Graph::node_id) IMREF(indeces_a, np);//获取在graph 中node的id if (IS_NODE_ID(index)) { if (IS_NODE_ID(nindex)) { P_00 = BVZ_interaction_penalty(p, np, l, nl); P_0a = BVZ_interaction_penalty(p, np, l, a); P_a0 = BVZ_interaction_penalty(p, np, a, nl); delta = (P_00 < P_0a) ? P_00 : P_0a; if (delta > 0) { IMREF(D_a, p) -= delta; E += delta; P_00 -= delta; P_0a -= delta; } delta = (P_00 < P_a0) ? P_00 : P_a0; if (delta > 0) { IMREF(D_a, np) -= delta; E += delta; P_00 -= delta; P_a0 -= delta; } if (P_00 > 0.0001) { fprintf(_fp, "ERROR: BVZ_interaction_penalty() is non-metric %f!\n",P_00); fflush(_fp); /*assert(0);*/ } #ifdef BVZ_ALPHA_SINK g -> add_edge(index, nindex, P_0a, P_a0); #else g -> add_edge(index, nindex, P_a0, P_0a); #endif } else { delta = BVZ_interaction_penalty(p, np, l, a); IMREF(D_a, p) -= delta; E += delta; } } else { if (IS_NODE_ID(nindex)) { delta = BVZ_interaction_penalty(p, np, a, nl); IMREF(D_a, np) -= delta; E += delta; } } }// end for neighbor }// end for image-pixel /* adding source and sink edges */ for (p.y=0; p.y<_h; p.y++) for (p.x=0; p.x<_w; p.x++) { index = (Graph::node_id) IMREF(indeces_a, p); if (IS_NODE_ID(index)) { delta = (float) IMREF(D_a, p); #ifdef BVZ_ALPHA_SINK if (delta > 0) { g -> set_tweights(index, delta, 0); } else { g -> set_tweights(index, 0, -delta); E += delta; } #else if (delta > 0) { g -> set_tweights(index, 0, delta); } else { g -> set_tweights(index, -delta, 0); E += delta; } #endif } } E += g -> maxflow(); //fprintf(_fp, "internal E: %f\n",E); fflush(_fp); if (E < E_old) { //fprintf(_fp,"Writing into _labels\n"); fflush(_fp); ind=0; for (p.y=0; p.y<_h; p.y++) for (p.x=0; p.x<_w; p.x++, ++ind) { index = (Graph::node_id) IMREF(indeces_a, p); if (IS_NODE_ID(index) && g->what_segment(index)==BVZ_TERM_B) { _labels[ind] = a; //进行交换操作 } } delete g; return E; } delete g; return E_old; }
float PortraitCut::getCurrDataTerm(const int i, const int j) { assert(i>=0 && i<_w && j>=0 && j<_h); Coord p(i,j); return BVZ_data_penalty(p, _labels[j*_w+i]); }