branch:
details: http://enblend.hg.sourceforge.net/hgweb/enblend/enblend/hg/p/enblend/code/rev/4c30a326b3f4
changeset: 1524:4c30a326b3f4
user: tmodes <tm...@us...>
date: Sat Oct 19 08:59:10 2019 +0200
description:
Fixes bug in graph-cut algorithm
Patch by Lukas Wirz
std::priority_queue is storing a *copy* of the comparator object.
So modification of the comparator object later are not taken into account by
the priority_queue. So using instead a lambda which will capture automatically
all changes to the variables.
diffstat:
VERSION | 2 +-
src/graphcut.h | 45 ++++++++++++---------------------------------
2 files changed, 13 insertions(+), 34 deletions(-)
diffs (77 lines):
diff -r f3e6c6c88e6e -r 4c30a326b3f4 VERSION
--- a/VERSION Mon Sep 23 18:14:04 2019 +0200
+++ b/VERSION Sat Oct 19 08:59:10 2019 +0200
@@ -1,1 +1,1 @@
-4.3-4bc188ec1b3a
+4.3-f3e6c6c88e6e
diff -r f3e6c6c88e6e -r 4c30a326b3f4 src/graphcut.h
--- a/src/graphcut.h Mon Sep 23 18:14:04 2019 +0200
+++ b/src/graphcut.h Sat Oct 19 08:59:10 2019 +0200
@@ -311,35 +311,6 @@
return interPointList;
}
-
- template <typename ImageType>
- class CostComparer
- {
- public:
- CostComparer(const ImageType* image) : img(image) {}
-
- bool operator()(const vigra::Point2D& a, const vigra::Point2D& b) const
- {
- if (a == vigra::Point2D(-20, -20)) {
- return totalScore > (*img)[b];
- } else if (b == vigra::Point2D(-20, -20)) {
- return (*img)[a] > totalScore;
- }
-
- return (*img)[a] > (*img)[b];
- }
-
- void setTotalScore(long s)
- {
- totalScore = s;
- }
-
- protected:
- const ImageType* img;
- long totalScore;
- };
-
-
template<class MaskPixelType>
struct OutputLabelingFunctor
{
@@ -576,11 +547,20 @@
vigra::Diff2D bounds, CheckpointPixels* srcDestPoints, std::unordered_set<vigra::Point2D, pointHash>* visited)
{
MaskPixelType zeroVal = vigra::NumericTraits<MaskPixelType>::zero();
- typedef std::priority_queue<vigra::Point2D, std::vector<vigra::Point2D>, CostComparer<ImageType> > Queue;
- CostComparer<ImageType> costcomp(img);
- Queue* openset = new Queue(costcomp);
long score = 0;
long totalScore = 0;
+ auto costcomparer = [&img, &totalScore](const vigra::Point2D& a, const vigra::Point2D& b)->bool {
+ if (a == vigra::Point2D(-20, -20)) {
+ return totalScore > (*img)[b];
+ } else {
+ if (b == vigra::Point2D(-20, -20)) {
+ return (*img)[a] > totalScore;
+ };
+ };
+ return (*img)[a] > (*img)[b];
+ };
+ typedef std::priority_queue<vigra::Point2D, std::vector<vigra::Point2D>, decltype(costcomparer)> Queue;
+ Queue * openset = new Queue(costcomparer);
long iterCount = 0;
int gradientA;
int gradientB;
@@ -668,7 +648,6 @@
if (neighbour == vigra::Point2D(-20, -20)) {
totalScore = score;
destNeighbour = current;
- costcomp.setTotalScore(totalScore);
} else {
(*img)[neighbour(1, 1)] &= BIT_MASK_OPEN;
(*img)[neighbour(1, 1)] += i;
|