I initially sent this mail 24 hours ago but it seems to have vanished.
Again, with an updated patch.

lukas


-------- Forwarded Message --------
Subject: enblend patch
Date: Sun, 22 Sep 2019 23:27:03 +0300
From: Wirz <s...@lukas-wirz.de>
To: hugin and other free panoramic software <hugin-ptx@googlegroups.com>

Hi,

attached is a patch that I would suggest to be applied to enblend.  It
does not solve any problem (with respect to the result image) that I am
aware of.

The problem that I'm fixing is in graphcut.h, in the function A_star:
There was first an object of type CostComparer<ImageType> created, then
this object is used to initialise a priority_queue (making a copy of the
object), and later a member variable (totalScore) of the initial
CostComparer was set (and never used).  However, this does not affect
the copy that has been used to init the Queue, so there were accesses to
uninitialized memory.

Furthermore, my testing suggests, that the A_star function would in many
cases terminate later than possible (because the comparison with
totalScore gave wrong results) which leads to measurable performance issues.

My solution is to replace the previous functor class by a lambda.  The
variable totalScore is (also by the copy) caught as a reference.
Testing shows faster runtime, equal output, and valgrind complains much
less.

Does that make sense?  Should I make any modifications?

cheers, lukas

-- 
A list of frequently asked questions is available at: 
http://wiki.panotools.org/Hugin_FAQ
--- 
You received this message because you are subscribed to the Google Groups 
"hugin and other free panoramic software" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to hugin-ptx+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/hugin-ptx/ca18303f-b03d-9436-fbba-f38d2e2824b9%40lukas-wirz.de.
diff -r f3e6c6c88e6e src/graphcut.h
--- a/src/graphcut.h	Mon Sep 23 18:14:04 2019 +0200
+++ b/src/graphcut.h	Mon Sep 23 22:01:33 2019 +0300
@@ -312,34 +312,6 @@
     }
 
 
-    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 +548,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 = [&](const vigra::Point2D& a, const vigra::Point2D& b){
+             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;
@@ -621,7 +602,6 @@
                     neighbour = list[i];
 
                     //visited during an earlier sub-cut, ignore
-
                     if(visited->find(neighbour) != visited->end()) {
                         continue;
                     }
@@ -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;
@@ -743,7 +722,7 @@
              ++currentDual) {
 
             current = convertFromDual(*currentDual);
-            
+
             if (nextDual != cut->end()) {
                 next = convertFromDual(*nextDual);
             }

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to