Beispiel #1
0
//---------------------------------------------------------
// Compute x-coordinates (LP-based approach) (for graphs)
//---------------------------------------------------------
void OptimalHierarchyLayout::computeXCoordinates(
	const Hierarchy& H,
	GraphCopyAttributes &AGC)
{
	const GraphCopy &GC = H;
	const int k = H.size();

	//
	// preprocessing: determine nodes that are considered as virtual
	//
	NodeArray<bool> isVirtual(GC);

	int i;
	for(i = 0; i < k; ++i)
	{
		const Level &L = H[i];
		int last = -1;
		for(int j = 0; j < L.size(); ++j)
		{
			node v = L[j];

			if(H.isLongEdgeDummy(v) == true) {
				isVirtual[v] = true;

				node u = v->firstAdj()->theEdge()->target();
				if(u == v) u = v->lastAdj()->theEdge()->target();

				if(H.isLongEdgeDummy(u) == true) {
					int down = H.pos(u);
					if(last != -1 && last > down) {
						isVirtual[v] = false;
					} else {
						last = down;
					}
				}
			} else
				isVirtual[v] = false;
		}
	}

	//
	// determine variables of LP
	//
	int nSegments     = 0; // number of vertical segments
	int nRealVertices = 0; // number of real vertices
	int nEdges        = 0; // number of edges not in vertical segments
	int nBalanced     = 0; // number of real vertices with deg > 1 for which
	                       // balancing constraints may be applied

	NodeArray<int> vIndex(GC,-1); // for real node: index of x[v]
	                              // for dummy: index of corresponding segment
	NodeArray<int> bIndex(GC,-1); // (relative) index of b[v]
	EdgeArray<int> eIndex(GC,-1); // for edge not in vertical segment:
	                              //   its index
	Array<int> count(GC.numberOfEdges());  // counts the number of dummy vertices
	                              // in corresponding segment that are not at
	                              // position 0

	for(i = 0; i < k; ++i)
	{
		const Level &L = H[i];
		for(int j = 0; j < L.size(); ++j) {
			node v = L[j];
			if(isVirtual[v] == true)
				continue;

			// we've found a real vertex
			vIndex[v] = nRealVertices++;
			if(v->degree() > 1)
				bIndex[v] = nBalanced++;

			// consider all outgoing edges
			edge e;
			forall_adj_edges(e,v) {
				node w = e->target();
				if(w == v)
					continue;

				// we've found an edge not belonging to a vetical segment
				eIndex[e] = nEdges++;

				if(isVirtual[w] == false)
					continue;

				// we've found a vertical segment
				count[nSegments] = 0;
				do {
					vIndex[w] = nSegments;
					const int high = H[H.rank(w)].high();
					if(high > 0) {
						if (H.pos(w) == 0 || H.pos(w) == high)
							++count[nSegments];
						else
							count[nSegments] += 2;
					}

					// next edge / dummy in segment
					e = e->adjTarget()->cyclicSucc()->theEdge();
					w = e->target();
				} while(isVirtual[w]);

				// edge following vertical segment
                eIndex[e] = nEdges++;

				++nSegments;
			}
		}
	}
int main(int argc, char** argv) {
  // Initialize Google's logging library.
  google::InitGoogleLogging(argv[0]);
  google::ParseCommandLineFlags(&argc, &argv, true);

  if (FLAGS_logging) {
    FLAGS_logtostderr = 1;
  }

  if (FLAGS_input.empty()) {
    std::cerr << "Input file not specified. Specify via -input.\n";
    return 1;
  }

  // Determine conversion mode.
  enum ConvMode { CONV_TEXT, CONV_BINARY, CONV_BITMAP_ID, CONV_BITMAP_COLOR, STRIP };
  ConvMode mode = CONV_TEXT;
  float hier_level = 0;
  std::string dest_filename;

  if (FLAGS_text_format) {
    mode = CONV_TEXT;
    std::cout << "Converting to text.";
  } else if (FLAGS_binary_format) {
    mode = CONV_BINARY;
    std::cout << "Converting to binary format.";
  } else if (FLAGS_bitmap_ids >= 0) {
    mode = CONV_BITMAP_ID;
    hier_level = FLAGS_bitmap_ids;
    std::cout << "Converting to id bitmaps for hierarchy level: " << hier_level << "\n";
  } else if (FLAGS_bitmap_color >= 0) {
    mode = CONV_BITMAP_COLOR;
    hier_level = FLAGS_bitmap_color;
    std::cout << "Converting to color bitmaps for hierarchy level: "
              << hier_level << "\n";
  } else if (!FLAGS_strip.empty()) {
    mode = STRIP;
    dest_filename = FLAGS_strip;
  } else {
    std::cout << "Unknown mode specified.\n";
    return 1;
  }
  std::string filename = FLAGS_input;

  // Read segmentation file.
  // Don't need rasterization when we are stripping file.
  const bool valid_rasterization = !FLAGS_strip.empty();
  SegmentationReader segment_reader(filename, valid_rasterization);
  segment_reader.OpenFileAndReadHeaders();
  std::vector<int> segment_headers = segment_reader.GetHeaderFlags();

  std::cout << "Segmentation file " << filename << " contains "
            << segment_reader.NumFrames() << " frames.\n";

  SegmentationWriter* writer = nullptr;
  bool use_vectorization = false;
  if (mode == STRIP) {
    writer = new SegmentationWriter(dest_filename);
    std::vector<int> header_entries;
    if (!FLAGS_use_rasterization && segment_headers.size() > 0) {
      header_entries.push_back(use_vectorization = segment_headers[0]);
    } else {
      header_entries.push_back(0);
    }

    header_entries.push_back(0);   // No shape moments.

    if (!writer->OpenFile(header_entries)) {
      std::cout << "Could not open destination file.\n";
      delete writer;
      return 1;
    }

    LOG(INFO) << "Stripping files with " << (use_vectorization ? "vectorization"
                                                               : "rasterization"); 
  }

  Hierarchy hierarchy;
  const int chunk_size = 100;    // By default use chunks of 100 frames.
  int absolute_level = -1;
  // Use absolute level if supplied.
  if (hier_level == 0 || hier_level >= 1) {
    absolute_level = hier_level;
  }

  for (int f = 0; f < segment_reader.NumFrames(); ++f) {
    segment_reader.SeekToFrame(f);

    // Read from file.
    SegmentationDesc segmentation;
    segment_reader.ReadNextFrame(&segmentation);

    if (segmentation.hierarchy_size() > 0) {
      hierarchy.Clear();
      hierarchy.MergeFrom(segmentation.hierarchy());
      // Convert fractional to constant absolute level.
      if (absolute_level < 0) {
        absolute_level = hier_level * (float)hierarchy.size();
        LOG(INFO) << "Selecting level " << absolute_level << " of " << hierarchy.size()
                  << std::endl;
      }
    }

    std::string curr_file = FLAGS_output_dir + "/";
    if (mode == CONV_TEXT) {
      curr_file += base::StringPrintf("frame%05d.pbtxt", f);
    } else if (mode == CONV_BINARY) {
      curr_file += base::StringPrintf("frame%05d.pb", f);
    } else {
      curr_file += base::StringPrintf("frame%05d.png", f);
    }

    if (f % 5 == 0) {
      std::cout << "Writing frame " << f << " of "
                << segment_reader.NumFrames() << "\n";
    }

    int frame_width = segmentation.frame_width();
    int frame_height = segmentation.frame_height();

    if (mode == CONV_BINARY) {
      std::ofstream ofs(curr_file, std::ios_base::out | std::ios_base::binary);
      segmentation.SerializeToOstream(&ofs);
    } else if (mode == CONV_TEXT) {
      std::ofstream ofs(curr_file, std::ios_base::out);
      ofs << segmentation.DebugString();
    } else if (mode == CONV_BITMAP_ID) {
      cv::Mat id_image(frame_height, frame_width, CV_32S);
      SegmentationDescToIdImage(absolute_level,
                                segmentation,
                                &hierarchy,
                                &id_image);

      // Get 4 channel view via evil casting.
      cv::Mat id_image_view(frame_height, frame_width, CV_8UC4, id_image.ptr<uint8_t>(0));

      // Discard most significant 8bit (little endian).
      vector<cv::Mat> id_channels;
      cv::split(id_image_view, id_channels);
      cv::Mat frame_buffer(frame_height, frame_width, CV_8UC3);
      cv::merge(&id_channels[0], 3, frame_buffer);
      cv::imwrite(curr_file, frame_buffer);
    } else if (mode == CONV_BITMAP_COLOR) {
      cv::Mat frame_buffer(frame_height, frame_width, CV_8UC3);
      RenderRegionsRandomColor(absolute_level,
                               true,
                               false,
                               segmentation,
                               &hierarchy,
                               &frame_buffer);
      cv::imwrite(curr_file, frame_buffer);
    } else if (mode == STRIP) {
      std::string stripped_data;
      StripToEssentials(segmentation,
                        use_vectorization,
                        false,   // no shape moments.
                        &stripped_data);
      writer->AddSegmentationDataToChunk(stripped_data, f);
      if (f > 0 && f % chunk_size == 0) {
        writer->WriteChunk();
      }
    }
  }

  if (mode == STRIP) {
    writer->WriteTermHeaderAndClose();
    delete writer;
  }

  segment_reader.CloseFile();
  return 0;
}