void removeStuckPixels()

in source/isp/CameraIsp.h [979:1058]


  void removeStuckPixels() {
    if (stuckPixelRadius > 0) {
      struct Pval {
        float val;
        int i;
        int j;

        Pval(float v) : val(v) {}
        Pval(const Pval& other) = default;

        bool operator<(const Pval& p) const {
          return val < p.val;
        }

        Pval& operator=(const Pval& p) {
          val = p.val;
          i = p.i;
          j = p.j;
          return *this;
        }
      };

      std::vector<Pval> region;

      for (int i = 0; i < height; ++i) {
        // Traverse boustrophedonically
        const bool evenScanLine = (i % 2) == 0;
        const int jStart = evenScanLine ? 0 : width - 1;
        const int jEnd = evenScanLine ? width - 1 : 0;
        const int jStep = evenScanLine ? 1 : -1;

        for (int j = jStart; j != jEnd; j += jStep) {
          const bool thisPixelRed = redPixel(i, j);
          const bool thisPixelGreen = greenPixel(i, j);
          const bool thisPixelBlue = bluePixel(i, j);

          region.clear();

          float mean = 0.0f;
          for (int y = -stuckPixelRadius; y <= stuckPixelRadius; y++) {
            const int ip = math_util::reflect(i + y, height);
            for (int x = -stuckPixelRadius; x <= stuckPixelRadius; x++) {
              const int jp = math_util::reflect(j + x, width);
              Pval p(rawImage(ip, jp));
              p.i = ip;
              p.j = jp;
              if (redPixel(ip, jp) && thisPixelRed) {
                mean += p.val;
                region.push_back(p);
              } else if (greenPixel(ip, jp) && thisPixelGreen) {
                mean += p.val;
                region.push_back(p);
              } else if (bluePixel(ip, jp) && thisPixelBlue) {
                mean += p.val;
                region.push_back(p);
              }
            }
          }
          mean /= float(region.size());

          // Only deal with dark regions
          if (mean < stuckPixelDarknessThreshold) {
            sort(region.begin(), region.end());

            // See if the middle pixel is an outlier
            for (int k = int(region.size()) - 1; k >= int(region.size()) - stuckPixelThreshold;
                 --k) {
              if (region[k].i == i && region[k].j == j) {
                // Replace the pixel pixel with the median of the region.
                rawImage(i, j) = region[region.size() / 2].val;
                goto l0;
              }
            }
          }
        l0:
          continue;
        }
      }
    }
  }