Esempio n. 1
0
def findStars(image):
    # find individual features
    image = threshHold(image)

    if doDumpFlat:
        import ImageIo
        ImageIo.dumpImage(image, "flat")

    labels, num_features = scipy.ndimage.label(image)

    if doDumpStars:
        dumpImage = image.copy()
        dumpImageMax = numpy.max(dumpImage)

    # remove small features
    sizes = scipy.ndimage.sum(image > 0, labels, range(num_features + 1))
    
    # HARDCODED PARAMETER: removeSizeThreshhold
    # What is: Minimum size (in pixels) a signal clump needs to be to be considered a star
    # Adjust if: Small stars are getting rejected in --dump_stars OR large noise clumps are getting accepted
    # See also: keepThreshhold
    removeSizeThreshhold = 25

    width, height = image.shape
    for maxx, maxy in scipy.ndimage.maximum_position(image, labels, [x for x in range(num_features + 1) if sizes[x] > removeSizeThreshhold]):
        maxx = int(maxx) # docs say maximum_position returns float
        maxy = int(maxy)
        sliceSize = 3
        if maxx < sliceSize or maxy < sliceSize or maxx >= width - sliceSize or maxy >= height - sliceSize:
            continue
        slice = image[maxx - sliceSize:maxx + sliceSize, maxy - sliceSize:maxy + sliceSize]
        height, x, y, width_x, width_y = fitgaussian(slice)
        x += maxx - sliceSize
        y += maxy - sliceSize
        skewMax = max(width_x / width_y, width_y / width_x)
        if skewMax > 2:
            print("Invalid star found at", x, y, ": too skewed, factor", skewMax)
            continue

        if doDumpStars:
            width_r = (width_x + width_y) / 2 * 4
            xx, yy = numpy.mgrid[:image.shape[0], :image.shape[1]]
            circle = (xx - x) ** 2 + (yy - y) ** 2
            circle = numpy.logical_and(circle < width_r * width_r + 9, circle > width_r * width_r - 9)
            dumpImage += circle * dumpImageMax

        # print("Star at ", x, y, "of height", height, "of width", width_x, width_y)
        yield (height, x, y)

    if doDumpStars:
        import ImageIo
        ImageIo.dumpImage(dumpImage, "stars")
Esempio n. 2
0
if __name__ == "__main__":
    argParser = argparse.ArgumentParser(description="Calibrate, register, and stack astrophotography images")
    argParser.add_argument("images", nargs='+', metavar="image", help="Input images to stack")
    argParser.add_argument("--reference", nargs='?', metavar="image", help="Reference image (not included in stack)")
    argParser.add_argument("--out", nargs='?', metavar="filename", help="Output file (mean)")
    argParser.add_argument("--outstdev", nargs='?', metavar="filename", help="Output file (stdev)")
    argParser.add_argument("--dump_dir", nargs='?', metavar="directory", help="Output directory for image dumps")
    argParser.add_argument("--dump_format", nargs='?', metavar="extension", help="Output format for image dumps")
    argParser.add_argument("--dump_stars", action="store_true", help="Dump found stars to an image")
    argParser.add_argument("--dump_flat", action="store_true", help="Dump flattened image (which is what the star finder uses)")
    argSuccess = True
    try:
        args = argParser.parse_args()
    except (Exception, SystemExit):
        argSuccess = False
    
    if argSuccess:
        ImageIo.initConfig(args.dump_dir, args.dump_format)
        Register.initConfig(args.dump_stars, args.dump_flat)
    
        list = ImageIo.loadImageGlob(args.images)
        reference = None
        if args.reference is not None:
            reference = ImageIo.loadImage(args.reference)
        reg = Register.register(reference, list)
        stack, stackDev = Stack.stack(reg)
        if args.out is not None:
            ImageIo.saveImage(stack, args.out)
        if args.outstdev is not None:
            ImageIo.saveImage(stackDev, args.outstdev)