int make_first_simplex(point_set *P, simplex **s){ face f; point *p3; int min_index; // select the point p1 nearest to the plane f.point[0] = P->point[P->size/2-1]; // select a second point p2 such that p2 is the nearest point to p1 on the other side of alpha minimum_distance(f.point[0], P, P->size/2, P->size, &min_index); if (!valid_index(P,min_index)) return 0; f.point[1] = P->point[min_index]; // search the point p3 such that the circum-circle around the 1-face (p1, p2) and the point p3 has the minimum //radius minimum_radius(f.point[0], f.point[1], P, 0, P->size, &min_index); if (!valid_index(P,min_index)) return 0; p3 = P->point[min_index]; if (pointLocationRelativeToFace(&f,p3) != 1) revert_face(&f); build_simplex(s, &f, p3); revert_face((*s)->face[0]); return 1; }
void Features::getVertex(const Node *first, const Node *last, int id, std::vector<NodePair> *node_pairs) const { if (node_pairs->size() <= static_cast<size_t>(id)) node_pairs->resize(id + 1); (*node_pairs)[id].first = first; (*node_pairs)[id].last = last; Node *best = 0; const float dist = minimum_distance(first, last, &best); static const float error = 0.001; if (dist > error) { getVertex(first, best, id * 2 + 1, node_pairs); getVertex(best, last, id * 2 + 2, node_pairs); } }
bool ContourFlip::update() { //if (!ImageNode::update()) return false; if (!Contour::update()) return false; // TBD get dirtiness of in to see if flip map needs to be recomputed if (!isDirty(this, 23)) { return true;} cv::Mat to_flip = getImage("to_flip"); if (to_flip.empty()) { VLOG(2) << name << " in is empty"; return false; } cv::Mat flipped = cv::Mat(to_flip.size(), to_flip.type()); bool valid; bool is_dirty; cv::Mat in = getImage("in", valid, is_dirty, 51); if (is_dirty) { LOG(INFO) << "contour flip updating " << is_dirty; cv::Mat dist = cv::Mat(to_flip.size(), to_flip.type()); const int wd = dist.cols; const int ht = dist.rows; // This is very slow for dense contours, maybe make // scale option that will process the image at a lower resolution // then upscale the off_x,off_y for the remap for (int y = 0; y < ht; y++) { for (int x = 0; x < wd; x++) { float min_dist = 1e9; cv::Point2f min_closest; int count = 0; // TBD just find the nearest contour point for now, don't worry about long segment // or the actual normal of the segment - just flip the pixel on the nearest point for (int i = 0; i < contours0.size(); i++) { for (int j = 0; j < contours0[i].size(); j++) { cv::Point2f v = contours0[i][j]; cv::Point2f w = contours0[i][ (j+1) % contours0[i].size() ]; //const float dx = (contours0[i][j].x - x); //const float dy = (contours0[i][j].y - y); //const float cur_dist = fabs(dx) + fabs(dy); //const float cur_dist = sqrt(dx*dx + dy*dy); cv::Point2f closest; const float cur_dist = minimum_distance( v, w, cv::Point2f(x, y), closest ); if (cur_dist < min_dist) { min_dist = cur_dist; min_closest = closest; } count++; }} if ( (x == 0) && ( y == 0) ) setSignal("count", count); // TBD make a reflection effect instead of straight rolling over the edges? const int src_x = ((x + (int) ( 2 * (min_closest.x - x) ) ) + wd) % wd; const int src_y = ((y + (int) ( 2 * (min_closest.y - y) ) ) + ht) % ht; // TBD this could be a map for remap and if the in image doesn't change it will // be more efficient //flipped.at<cv::Vec4b>(y, x) = to_flip.at<cv::Vec4b>(src_y, src_x); off_x.at<float>(y, x) = src_x - x; off_y.at<float>(y, x) = src_y - y; //LOG_FIRST_N(INFO,20) << src_x << " " << x << ", " << src_y << " " << y; dist.at<cv::Vec4b>(y, x) = cv::Scalar::all(min_dist); // % 255); }} cv::Mat dist_x = base_x + (off_x); //_scaled - offsetx * scalex); cv::Mat dist_y = base_y + (off_y); //_scaled - offsety * scaley); cv::convertMaps(dist_x, dist_y, dist_xy16, dist_int, CV_16SC2, true); setImage("dist", dist); { cv::Mat dist_xy8; cv::Mat dist_xy16_temp; cv::convertMaps(off_x, off_y, dist_xy16_temp, dist_int, CV_16SC2, true); dist_xy16_temp.convertTo(dist_xy8, CV_8UC2, getSignal("map_scale")); cv::Mat mapx = cv::Mat( Config::inst()->getImSize(), CV_8UC4, cv::Scalar(0,0,0,0)); cv::Mat mapy = cv::Mat( Config::inst()->getImSize(), CV_8UC4, cv::Scalar(0,0,0,0)); int chx[] = {0,0, 0,1, 0,2}; mixChannels(&dist_xy8, 1, &mapx, 1, chx, 3 ); int chy[] = {1,0, 1,1, 1,2}; mixChannels(&dist_xy8, 1, &mapy, 1, chy, 3 ); setImage("mapx", mapx); setImage("mapy", mapy); } } if (!dist_xy16.empty()) cv::remap(to_flip, flipped, dist_xy16, cv::Mat(), getModeType(), getBorderType()); setImage("flipped", flipped); return true; }