Changeset 41892 for trunk/psModules/src/imcombine/pmStack.c
- Timestamp:
- Nov 4, 2021, 6:05:18 PM (5 years ago)
- Location:
- trunk/psModules
- Files:
-
- 2 edited
-
. (modified) (1 prop)
-
src/imcombine/pmStack.c (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psModules
-
trunk/psModules/src/imcombine/pmStack.c
r36710 r41892 756 756 // *goodMask &= mask->data.PS_TYPE_IMAGE_MASK_DATA[yIn][xIn]; // save the mask bits still used 757 757 // check for set bits and increment counter as appropriate 758 // count the number of times a given mask bit is set in the input pixels. 759 // NOTE: since we have explicitly skipped the pixels with any bad bits, these are only 760 // the suspect bits (nGoodBits is a bit of a misnomer: it is more like 'nSuspectBitsForGoodInputs' 758 761 { 759 762 psImageMaskType value = 0x0001; … … 961 964 962 965 // KMM values; 963 float Punimodal = 1.0, KMMmean = NAN,KMMsigma = NAN,KMMpi = NAN;966 float Punimodal = 1.0, KMMmean = NAN, KMMsigma = NAN, KMMpi = NAN; 964 967 int KMM_MINIMUM_INPUTS = 6; 965 968 bool useKMM = false; … … 1510 1513 } 1511 1514 1515 # define MIN_GOOD_PERCENTILE 2 1516 bool pmStackCombineByPercentile( 1517 pmReadout *combined, 1518 psArray *stackData, 1519 psF64 minRange, 1520 psF64 maxRange, 1521 psImageMaskType badMaskBits, // treat these bits as 'bad' 1522 psImageMaskType suspectMaskBits, // treat these bits as 'suspect' 1523 psImageMaskType blankMaskBits // use this mask value for pixels missing input data (distinguish between Ninput = 0 and Ngood = 0?) 1524 ) { 1525 int minInputCols, maxInputCols, minInputRows, maxInputRows; // Smallest and largest values to combine 1526 int xSize, ySize; // Size of the output image 1527 1528 // we need to copy the readouts to their own array for validation 1529 psArray *stackReadouts = psArrayAlloc(stackData->n); 1530 for (int i = 0; i < stackData->n; i++) { 1531 pmStackData *data = stackData->data[i]; // Stack data for this input 1532 pmReadout *ro = data->readout; // Readout of interest 1533 stackReadouts->data[i] = psMemIncrRefCounter(ro); 1534 } 1535 1536 if (!pmReadoutStackValidate(&minInputCols, &maxInputCols, &minInputRows, &maxInputRows, &xSize, &ySize, stackReadouts)) { 1537 psError(psErrorCodeLast(), false, "Input stack is not valid."); 1538 psFree(stackReadouts); 1539 return false; 1540 } 1541 psFree(stackReadouts); 1542 1543 psVector *pixelData = psVectorAlloc(stackData->n, PS_TYPE_F32); 1544 psVector *pixelMask = psVectorAlloc(stackData->n, PS_TYPE_VECTOR_MASK); 1545 1546 for (int y = minInputRows; y < maxInputRows; y++) { 1547 for (int x = minInputCols; x < maxInputCols; x++) { 1548 1549 int nGood = 0; 1550 for (int i = 0; i < stackData->n; i++) { 1551 1552 pmStackData *data = stackData->data[i]; // Stack data for this input 1553 pmReadout *ro = data->readout; // Readout of interest 1554 psImage *image = ro->image; 1555 psImage *mask = ro->mask; 1556 1557 int xIn = x - data->readout->col0; 1558 int yIn = y - data->readout->row0; // Coordinates on input readout 1559 1560 if (!isfinite(image->data.F32[yIn][xIn])) continue; 1561 if (fabs(image->data.F32[yIn][xIn]) > 1e5) continue; 1562 // XXX need to test the input mask as well here 1563 if (mask->data.PS_TYPE_IMAGE_MASK_DATA[yIn][xIn] & badMaskBits); 1564 1565 // XXX save the count of suspect bits 1566 1567 # if (0) 1568 // count the number of times a given mask bit is set in the input pixels. 1569 // NOTE: since we have explicitly skipped the pixels with any bad bits, these are only 1570 // the suspect bits (nGoodBits is a bit of a misnomer: it is more like 'nSuspectBitsForGoodInputs' 1571 if (1) { 1572 psImageMaskType value = 0x0001; 1573 for (int nbit = 0; nbit < 16; nbit ++) { 1574 if (mask->data.PS_TYPE_IMAGE_MASK_DATA[yIn][xIn] & value) { 1575 // XXX nGoodBits[nbit] ++; 1576 } 1577 value <<= 1; 1578 } 1579 } 1580 # endif 1581 1582 pixelData->data.F32[nGood] = image->data.F32[yIn][xIn]; 1583 nGood ++; 1584 } 1585 pixelData->n = nGood; 1586 psVectorSortInPlace (pixelData); 1587 1588 if (nGood < MIN_GOOD_PERCENTILE) { 1589 combined->image->data.F32[y][x] = NAN; 1590 combined->variance->data.F32[y][x] = NAN; 1591 combined->mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] = 1; 1592 continue; 1593 } 1594 1595 # if (0) 1596 # define SUSPECT_FRACTION 0.65 1597 // set the mask bits if nGoodBits[i] > f*numGood 1598 if (0) { 1599 psImageMaskType value = 0x0001; 1600 for (int nbit = 0; nbit < 16; nbit ++) { 1601 if (nGoodBits[nbit] > SUSPECT_FRACTION*numGood) { 1602 *goodMask |= value; 1603 } 1604 value <<= 1; 1605 } 1606 } 1607 # endif 1608 1609 int Ns = MIN(MAX(0, minRange * nGood),nGood); // e.g., 0.1 * 50 = 5 1610 int Ne = MIN(MAX(0, maxRange * nGood),nGood); // e.g., 0.9 * 50 = 45 1611 int Npt = Ne - Ns; 1612 1613 float sum = 0.0; 1614 for (int n = Ns; n < Ne; n++) { 1615 sum += pixelData->data.F32[n]; 1616 } 1617 float mean = sum / (float) Npt; 1618 1619 float varSum = 0.0; 1620 for (int n = Ns; n < Ne; n++) { 1621 varSum += SQ(pixelData->data.F32[n] - mean); 1622 } 1623 // variance on the mean (stdev / sqrt(N))^2 1624 float varValue = varSum / (Npt - 1) / Npt; 1625 1626 // XXX this is probably not the correct variance to save 1627 // the predicted variance should be the 1 / sum (1/var) 1628 1629 combined->image->data.F32[y][x] = mean; 1630 combined->variance->data.F32[y][x] = varValue; 1631 combined->mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] = 0; 1632 } 1633 } 1634 1635 psFree(pixelData); 1636 psFree(pixelMask); 1637 1638 return (true); 1639 } 1640 1512 1641 /// Stack input images 1513 1642 bool pmStackCombine( … … 1644 1773 expweight = expmaps->variance; 1645 1774 } 1646 1647 /* // Pre-reject inputs using KMM bimodality test. */1648 /* if (1) { */1649 /* /\* KMMRejectUnpopular(input,x,y); *\/ */1650 /* rejection = true; */1651 /* } */1652 1775 1653 1776 // Set up rejection list … … 1660 1783 for (int y = minInputRows; y < maxInputRows; y++) { 1661 1784 for (int x = minInputCols; x < maxInputCols; x++) { 1785 // this is only for TESTING: 1662 1786 CHECKPIX(x, y, "Combining pixel %d,%d: %x %x %f %f %f %f %d %d %d\n", x, y, badMaskBits, blankMaskBits, iter, rej, sys, olympic, useVariance, safe, rejection); 1663 1664 /* // Pre-reject inputs using KMM bimodality test. */1665 /* if (1) { */1666 /* KMMRejectUnpopular(input,x,y); */1667 /* /\* rejection = true; *\/ */1668 /* } */1669 /* else { */1670 /* KMMRejectBright(input,x,y); */1671 /* } */1672 1673 #ifdef TESTING1674 if (PS_SQR(x - TEST_X) + PS_SQR(y - TEST_Y) <= PS_SQR(TEST_RADIUS)) {1675 fprintf (stderr, "combine\n");1676 }1677 # endif1678 1787 1679 1788 psVector *reject = NULL; // Images to reject for this pixel
Note:
See TracChangeset
for help on using the changeset viewer.
