void
TolerantEditDistance::extractCells() {

	if (_groundTruth->size() != _reconstruction->size())
		BOOST_THROW_EXCEPTION(SizeMismatchError() << error_message("ground truth and reconstruction have different size") << STACK_TRACE);

	if (_groundTruth->height() != _reconstruction->height() || _groundTruth->width() != _reconstruction->width())
		BOOST_THROW_EXCEPTION(SizeMismatchError() << error_message("ground truth and reconstruction have different size") << STACK_TRACE);

	_depth  = _groundTruth->size();
	_width  = _groundTruth->width();
	_height = _groundTruth->height();

	LOG_ALL(tedlog) << "extracting cells in " << _width << "x" << _height << "x" << _depth << " volume" << std::endl;

	vigra::MultiArray<3, std::pair<float, float> > gtAndRec(vigra::Shape3(_width, _height, _depth));
	vigra::MultiArray<3, unsigned int>             cellIds(vigra::Shape3(_width, _height, _depth));

	// prepare gt and rec image

	for (unsigned int z = 0; z < _depth; z++) {

		boost::shared_ptr<Image> gt  = (*_groundTruth)[z];
		boost::shared_ptr<Image> rec = (*_reconstruction)[z];

		for (unsigned int x = 0; x < _width; x++)
			for (unsigned int y = 0; y < _height; y++) {

				float gtLabel  = (*gt)(x, y);
				float recLabel = (*rec)(x, y);

				gtAndRec(x, y, z) = std::make_pair(gtLabel, recLabel);
			}
	}

	// find connected components in gt and rec image
	cellIds = 0;
	_numCells = vigra::labelMultiArray(gtAndRec, cellIds);

	LOG_DEBUG(tedlog) << "found " << _numCells << " cells" << std::endl;

	// let tolerance function extract cells from that
	_toleranceFunction->extractCells(
			_numCells,
			cellIds,
			*_reconstruction,
			*_groundTruth);

	LOG_ALL(tedlog)
			<< "found "
			<< _toleranceFunction->getGroundTruthLabels().size()
			<< " ground truth labels and "
			<< _toleranceFunction->getReconstructionLabels().size()
			<< " reconstruction labels"
			<< std::endl;
}
Exemplo n.º 2
0
void
VariationOfInformation::updateOutputs() {

	// set output
	if (!_errors)
		_errors = new VariationOfInformationErrors();

	if (_headerOnly)
		return;

	if (_reconstruction->size() != _groundTruth->size())
		BOOST_THROW_EXCEPTION(SizeMismatchError() << error_message("image stacks have different size") << STACK_TRACE);

	// count label occurences

	_p1.clear();
	_p2.clear();
	_p12.clear();

	ImageStack::const_iterator i1  = _reconstruction->begin();
	ImageStack::const_iterator i2  = _groundTruth->begin();

	unsigned int n = 0;

	for (; i1 != _reconstruction->end(); i1++, i2++) {

		if ((*i1)->size() != (*i2)->size())
			BOOST_THROW_EXCEPTION(SizeMismatchError() << error_message("images have different size") << STACK_TRACE);

		n += (*i1)->size();

		Image::iterator j1 = (*i1)->begin();
		Image::iterator j2 = (*i2)->begin();

		for (; j1 != (*i1)->end(); j1++, j2++) {

			if (_ignoreBackground && *j2 == 0) {

				n--;
				continue;
			}

			_p1[*j1]++;
			_p2[*j2]++;
			_p12[std::make_pair(*j1, *j2)]++;
		}
	}

	// normalize

	for (typename LabelProb::iterator i = _p1.begin(); i != _p1.end(); i++)
		i->second /= n;
	for (typename LabelProb::iterator i = _p2.begin(); i != _p2.end(); i++)
		i->second /= n;
	for (typename JointLabelProb::iterator i = _p12.begin(); i != _p12.end(); i++)
		i->second /= n;

	// compute information

	// H(stack 1)
	double H1 = 0.0;
	// H(stack 2)
	double H2 = 0.0;
	double I  = 0.0;

	for(typename LabelProb::const_iterator i = _p1.begin(); i != _p1.end(); i++)
		H1 -= i->second * std::log2(i->second);

	for(typename LabelProb::const_iterator i = _p2.begin(); i != _p2.end(); i++)
		H2 -= i->second * std::log2(i->second);

	for(typename JointLabelProb::const_iterator i = _p12.begin(); i != _p12.end(); i++) {

		const float j = i->first.first;
		const float k = i->first.second;

		const double pjk = i->second;
		const double pj  = _p1[j];
		const double pk  = _p2[k];

		I += pjk * std::log2( pjk / (pj*pk) );
	}

	// H(stack 1, stack2)
	double H12 = H1 + H2 - I;

	// We compare stack1 (reconstruction) to stack2 (groundtruth). Thus, the 
	// split entropy represents the number of splits of regions in stack2 in 
	// stack1, and the merge entropy the number of merges of regions in stack2 
	// in stack1.
	//
	// H(stack 1|stack 2) = H(stack 1, stack 2) - H(stack 2)
	//   (i.e., if I know the ground truth label, how much bits do I need to 
	//   infer the reconstructino label?)
	_errors->setSplitEntropy(H12 - H2);
	// H(stack 2|stack 1) = H(stack 1, stack 2) - H(stack 1)
	//   (i.e., if I know the reconstruction label, how much bits do I need to 
	//   infer the groundtruth label?)
	_errors->setMergeEntropy(H12 - H1);

	LOG_DEBUG(variationofinformationlog)
			<< "sum of conditional entropies is " << _errors->getEntropy()
			<< ", which should be equal to " << (H1 + H2 - 2.0*I) << std::endl;
}
void
VariationOfInformation::updateOutputs() {

	if (_stack1->size() != _stack2->size())
		BOOST_THROW_EXCEPTION(SizeMismatchError() << error_message("image stacks have different size") << STACK_TRACE);

	// count label occurences

	_p1.clear();
	_p2.clear();
	_p12.clear();

	ImageStack::const_iterator i1  = _stack1->begin();
	ImageStack::const_iterator i2  = _stack2->begin();

	unsigned int n = 0;

	for (; i1 != _stack1->end(); i1++, i2++) {

		if ((*i1)->size() != (*i2)->size())
			BOOST_THROW_EXCEPTION(SizeMismatchError() << error_message("images have different size") << STACK_TRACE);

		n += (*i1)->size();

		Image::iterator j1 = (*i1)->begin();
		Image::iterator j2 = (*i2)->begin();

		for (; j1 != (*i1)->end(); j1++, j2++) {

			_p1[*j1]++;
			_p2[*j2]++;
			_p12[std::make_pair(*j1, *j2)]++;
		}
	}

	// normalize

	for (typename LabelProb::iterator i = _p1.begin(); i != _p1.end(); i++)
		i->second /= n;
	for (typename LabelProb::iterator i = _p2.begin(); i != _p2.end(); i++)
		i->second /= n;
	for (typename JointLabelProb::iterator i = _p12.begin(); i != _p12.end(); i++)
		i->second /= n;

	// compute information

	double H0 = 0.0;
	double H1 = 0.0;
	double I  = 0.0;

	for(typename LabelProb::const_iterator i = _p1.begin(); i != _p1.end(); i++)
		H0 -= i->second * std::log(i->second);

	for(typename LabelProb::const_iterator i = _p2.begin(); i != _p2.end(); i++)
		H1 -= i->second * std::log(i->second);

	for(typename JointLabelProb::const_iterator i = _p12.begin(); i != _p12.end(); i++) {

		const float j = i->first.first;
		const float k = i->first.second;

		const double pjk = i->second;
		const double pj  = _p1[j];
		const double pk  = _p2[k];

		I += pjk * std::log( pjk / (pj*pk) );
	}

	// set output

	*_variationOfInformation = H0 + H1 - 2.0 * I;

	// dump to output (useful for redirection into file)
	LOG_USER(variationofinformationlog) << "# VOI" << std::endl;
	LOG_USER(variationofinformationlog) << (*_variationOfInformation) << std::endl;
}