Changeset 41945
- Timestamp:
- Dec 1, 2021, 9:27:09 AM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/ipp-20211108/psModules/src/imcombine/pmStack.c
r41940 r41945 1538 1538 #define SORT_VALUES(NVALUES) { PSSORT(NVALUES, SORT_VV_COMPARE, SORT_VV_SWAP, F32); } 1539 1539 1540 #define ESCAPE \ 1541 combined->image->data.F32[y][x] = NAN; \ 1542 combined->variance->data.F32[y][x] = NAN; \ 1543 combined->mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] = blankMaskBits; \ 1544 if (expmaps) { \ 1545 expmaps->image->data.F32[y][x] = 0.0; \ 1546 expmaps->variance->data.F32[y][x] = 0.0; \ 1547 expmaps->mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] = 0; \ 1548 } \ 1549 continue; 1550 1540 1551 bool pmStackCombineByPercentile( 1541 1552 pmReadout *combined, // output stacked readout … … 1631 1642 nGood ++; 1632 1643 } 1644 # define MIN_GOOD_PERCENTILE 3 1645 1646 if (nGood < MIN_GOOD_PERCENTILE) ESCAPE; 1647 1633 1648 pixelData->n = nGood; 1649 1650 // sort pixelData, pixelVariance, expTime (if it exists) 1651 SORT_VALUES (pixelData->n); 1652 1653 // we now have a sorted vector of values. We can make a very coarse outlier 1654 // cut based on the median and interquartile range. This will let us reject 1655 // some extreme outliers that bias the signal otherwise. 1656 1657 int Nlo = 0; 1658 int Nhi = nGood; 1659 1660 if (nGood >= 5) { 1661 int midPoint = nGood / 2; 1662 float rawMedian = (nGood % 2) ? pixelData->data.F32[midPoint] : 0.5*(pixelData->data.F32[midPoint] + pixelData->data.F32[midPoint-1]); 1663 1664 // XXX measure interquartile range 1665 int P25 = 0.25*nGood; 1666 int P75 = 0.75*nGood; 1667 float rawSigma = 0.74*(pixelData->data.F32[P75] - pixelData->data.F32[P25]); 1668 float minThresh = rawMedian - 7.0*rawSigma; 1669 float maxThresh = rawMedian + 7.0*rawSigma; 1670 1671 // find the entries which are in the range 1672 // these should be safe since minThresh and maxThresh are guaranteed to contain the median 1673 while (pixelData->data.F32[Nlo ] < minThresh) { Nlo ++; } 1674 while (pixelData->data.F32[Nhi - 1] > maxThresh) { Nhi --; } 1675 } 1676 1677 // if we did not clip above (either nGood < 5 or no rejection), Nlo will be 0, Nhi will be nGood 1678 // In either case, Nlo is the offset of the first unclipped point. 1679 int nGoodClip = Nhi - Nlo; 1634 1680 1635 1681 // rather than define a min and max value, … … 1645 1691 # define MIN_GOOD_PERCENTILE 3 1646 1692 # if (AT_LEAST) 1647 int Ns = MIN(MAX(1, 0.5*rejectFraction * nGood ), nGood);1648 int Ne = nGood - Ns ;1693 int Ns = MIN(MAX(1, 0.5*rejectFraction * nGoodClip), nGoodClip) + Nlo; 1694 int Ne = nGood - Ns + Nlo; 1649 1695 int Npt = Ne - Ns; 1650 1696 # else 1651 int Ns = MIN(MAX(0, 0.5*rejectFraction * nGood), nGood) ;1652 int Ne = nGood - Ns ;1697 int Ns = MIN(MAX(0, 0.5*rejectFraction * nGood), nGood) + Nlo; 1698 int Ne = nGood - Ns + Nlo; 1653 1699 int Npt = Ne - Ns; 1654 1700 # endif 1655 if ((Npt < 1) || (nGood < MIN_GOOD_PERCENTILE)) { 1656 combined->image->data.F32[y][x] = NAN; 1657 combined->variance->data.F32[y][x] = NAN; 1658 combined->mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] = blankMaskBits; // probably not needed since it was set above. 1659 if (expmaps) { 1660 expmaps->image->data.F32[y][x] = 0.0; // XXX should this value be NAN or 0? 1661 expmaps->variance->data.F32[y][x] = 0.0; 1662 expmaps->mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] = 0; 1663 } 1664 continue; 1665 } 1666 1667 // sort pixelData, pixelVariance, expTime (if it exists) 1668 SORT_VALUES (pixelData->n); 1669 1701 if ((Npt < 1) || (nGood < MIN_GOOD_PERCENTILE)) ESCAPE; 1702 1703 // XXX note that this does not respect the clipping above 1670 1704 // set the given (suspect) mask bit if nGoodBits[i] > f*nGood 1671 1705 // in other words if more than 65% of the good inputs had one of … … 1705 1739 // this coefficient varies between 1.4 (for pure median) and 1.05 for 68% range. 1706 1740 1707 float varValue = varSum / (float) (nGood *nGood);1741 float varValue = varSum / (float) (nGoodClip*nGoodClip); 1708 1742 1709 1743 combined->image->data.F32[y][x] = mean; … … 1719 1753 if (expTime) { 1720 1754 float sum = 0.0; 1721 for (int n = 0; n < nGood; n++) {1755 for (int n = Nlo; n < Nhi; n++) { 1722 1756 sum += expTime->data.F32[n]; 1723 1757 } 1724 1758 expmaps->image->data.F32[y][x] = sum; 1725 1759 } 1726 if (expmaps) { expmaps->mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] = nGood ; }1760 if (expmaps) { expmaps->mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] = nGoodClip; } 1727 1761 } 1728 1762 }
Note:
See TracChangeset
for help on using the changeset viewer.
