def kirschEdgeDetection(image, sigma=1, kernelSize=5):
    """
        Apply the Kirsch filter for an edge detection

        Parameters
        ----------
        image: ndarray((h, w, 3))

        sigma: float

        kernelSize: int

        Returns
        -------
        ndarray((h, w, 3))
    """

    smoothedImage = optimizedConv2D(image, gaussianKernel(kernelSize, sigma))
    gradientMatrix, thetaMatrix = kirschFilters(smoothedImage)
    return gradientMatrix
def cannyEdgeDetection(image,
                       sigma=1,
                       kernelSize=5,
                       weakPix=75,
                       strongPix=255,
                       lowThreshold=0.05,
                       highThreshold=0.15):
    """
        Apply the Canny filter for an edge detection

        Parameters
        ----------
        image: ndarray((h, w, 3))

        sigma: float

        kernelSize: int

        weakPix: int

        strongPix: int

        lowThreshold: int

        highThreshold: int

        Returns
        -------
        ndarray((h, w, 3))
    """

    smoothedImage = optimizedConv2D(image, gaussianKernel(kernelSize, sigma))
    gradientMatrix, thetaMatrix = sobelFilters(smoothedImage)
    nonMaxImage = nonMaxSuppression(gradientMatrix, thetaMatrix)
    thresholdImage = threshold(nonMaxImage,
                               lowThresholdRatio=lowThreshold,
                               highThresholdRatio=highThreshold,
                               weakPix=weakPix,
                               strongPix=strongPix)
    return hysteresis(thresholdImage, weakPixel=weakPix, strongPixel=strongPix)
Exemple #3
0
    if len(channels) == 2:
        hp.saveBMP(
            bmp,
            newImage,
            outputFile=f'output/channel/ch-{channels[0]}-{channels[1]}-half.bmp'
        )
    else:
        hp.saveBMP(bmp,
                   newImage,
                   outputFile=f'output/channel/ch-{channels}-half.bmp')
colourers.success('Successfully kept specific channels')

colourers.info('Denoising the image (Wiener Filter)')
os.mkdir('output/denoise')
newImage = Filters.wienerFilter(bmp.imageData,
                                gaussianKernel(9, sigma=0.33),
                                K=10)
hp.saveBMP(bmp, newImage, outputFile=f'output/denoise/d.bmp')
colourers.success('Successfully denoised the image')

colourers.info('Applying texture detection (Gabor Filter)')
os.mkdir('output/texture-detection')
newImage = Filters.gaborFilter(bmp.imageData, gaborKernel(0))
hp.saveBMP(bmp, newImage, outputFile=f'output/texture-detection/td.bmp')
colourers.success('Successfully detected the texure')

colourers.info('Applying increased edge enhancement filter')
os.mkdir('output/increased-edge-enhancement')
newImage = Filters.iee(bmp.imageData)
hp.saveBMP(bmp,
           newImage,
Exemple #4
0
def imageProcessing():
    """
        Process a given image in parameter (BMP or PNG)
    """

    # Parser initialization
    parser = argparse.ArgumentParser(description=colourers.toCyan('Image processor for reading/writing images into BMP/PNG formats and applying transformations on it.'))
    
    # Formats Parser
    group = parser.add_argument_group(colourers.toGreen('formats'))
    formatParser = group.add_mutually_exclusive_group(required=True)
    formatParser.add_argument('--bmp',
                               type=str,
                               metavar=colourers.toRed('<bmp file name>'), 
                               help=colourers.toMagenta('bmp file to parse'))
    formatParser.add_argument('--png',
                              type=str,
                              metavar=colourers.toRed('<png file name>'),
                              help=colourers.toMagenta('png file to parse'))

    # Printers Parser
    group = parser.add_argument_group(colourers.toYellow('printers'))
    printers = group.add_mutually_exclusive_group()
    printers.add_argument('--header',
                       help=colourers.toMagenta('print the file format header'),
                       action='store_true')
    printers.add_argument('--print-color',
                       '-pc',
                       type=int,
                       nargs=2,
                       metavar=(colourers.toRed('<width>'), colourers.toRed('<height>')),
                       help=colourers.toMagenta('pixel to print'))
    printers.add_argument('--histogram',
                       action='store_true',
                       help=colourers.toMagenta('print histogram associated'))
    printers.add_argument('--output',
                        '-o',
                        type=str,
                        metavar=colourers.toRed('<output file>'),
                        help=colourers.toMagenta('image output file'))

    # Transformers Parser
    transformers = parser.add_argument_group(colourers.toBlue('transformers'))
    transformers.add_argument('--half',
                              action='store_true',
                              help='applying the filter on one half of the image')
    transformers.add_argument('--rotate',
                        '-r',
                        type=int,
                        choices=[90, 180, 270],
                        metavar=colourers.toRed('<degree of rotation>'),
                        help=colourers.toMagenta('rotate the image'))
    transformers.add_argument('--scale',
                        '-s',
                        type=int,
                        nargs='+',
                        action=required_length(1, 2),
                        metavar=(colourers.toRed('<scaleRatio> | [<width>'), colourers.toRed('<height>')),
                        help=colourers.toMagenta('scale/shrink the image'))
    transformers.add_argument('--contrast',
                        '-c',
                        type=float,
                        metavar=colourers.toRed('<contrast factor>'),
                        help=colourers.toMagenta('apply a factor contrast'))
    transformers.add_argument('--grayscale',
                        '-gs',
                        action='store_true',
                        help=colourers.toMagenta('to grayscale image'))
    transformers.add_argument('--binary',
                        '-b',
                        action='store_true',
                        help=colourers.toMagenta('to binary image'))
    transformers.add_argument('--invert',
                        '-i',
                        action='store_true',
                        help=colourers.toMagenta('to inverted image, equivalent to --contrast -1'))
    transformers.add_argument('--channel',
                        type=str,
                        choices=['blue', 'green', 'red'],
                        metavar=colourers.toRed('<channel>'),
                        nargs='+',
                        action=required_length(1, 2),
                        help=colourers.toMagenta('to the specified channel'))
    
    # Filters Parser
    filters = parser.add_argument_group(colourers.toCyan('filters'))
    filters.add_argument('--edge-detection',
                         '-ed',
                         type=str,
                         choices=['canny', 'sobel', 'prewitt', 'roberts', 'kirsch'],
                         metavar=colourers.toRed('<filter name>'),
                         help=colourers.toMagenta('perform an edge detection'))
    filters.add_argument('--retrieve-color',
                         '-rv',
                         action='store_true',
                         help=colourers.toMagenta('retrieve the colors of a grayscale image'))
    filters.add_argument('--edge-enhancement',
                         '-ee',
                         action='store_true', 
                         help=colourers.toMagenta('applying increased edge enhancement filter'))
    filters.add_argument('--sharpen',
                         action='store_true',
                         help=colourers.toMagenta('sharpening the image'))
    filters.add_argument('--unsharp',
                        action='store_true',
                        help=colourers.toMagenta('unsharp the image'))       
    filters.add_argument('--denoise',
                         action='store_true',
                         help=colourers.toMagenta('denoise the image'))
    filters.add_argument('--texture-detection',
                         '-td',
                         action='store_true',
                         help=colourers.toMagenta('applying texture detection (Gabor Filter)'))
    filters.add_argument('--blur',
                         type=str,
                         choices=['simple', 'more', 'average', 'gaussian', 'motion'],
                         metavar=colourers.toRed('<type of blur>'),
                         help=colourers.toMagenta('perform the selected blur'))
    filters.add_argument('--blur-iteration',
                         '-bi',
                         type=int,
                         default=1,
                         metavar=colourers.toRed('<number of iteration>'),
                         help=colourers.toMagenta('apply N times the blur function'))
    filters.add_argument('--emboss',
                         action='store_true',
                         help=colourers.toMagenta('perform an embossing filter'))
    filters.add_argument('--overlap',
                         type=str,
                         nargs='+',
                         metavar=colourers.toRed('<image to overlap>'),
                         help=colourers.toMagenta('overlap an image given on the selected image'))

    # Args parsing
    args = parser.parse_args()

    filename = ""
    # BMP Block
    if args.bmp:
        filename = args.bmp

        if not os.path.isfile(filename):
            colourers.error('"{}" does not exist !'.format(filename))
            sys.exit(-1)
        colourers.success('Success Opening {}...'.format(filename))

        bmp = BMP(filename)
        half = args.half

        if args.print_color:
            width, height = args.print_color
            colourers.info(f'Printing pixel color of ({width}, {height})')
            Printers.printPixel(bmp, width, height)
            sys.exit(0)
        
        elif args.header:
            colourers.info(f'Printing BMP header of {bmp.filename}')
            Printers.printHeader(bmp)
            sys.exit(0)
        
        elif args.histogram:
            colourers.info(f'Printing color histogram of {bmp.filename}')
            Printers.printHistogram(bmp)
            sys.exit(0)
        
        if (args.rotate or args.scale or args.contrast or args.grayscale or 
            args.binary or args.channel or args.edge_detection or args.retrieve_color or
            args.edge_enhancement or args.blur or args.emboss or args.overlap or args.texture_detection or
            args.denoise or args.sharpen or args.unsharp):
            if not hp.atLeastOne(args.output, (
                args.rotate,
                args.scale,
                args.contrast,
                args.grayscale,
                args.binary,
                args.channel,
                args.edge_detection,
                args.retrieve_color,
                args.edge_enhancement,
                args.blur,
                args.emboss,
                args.overlap,
                args.texture_detection,
                args.denoise,
                args.sharpen,
                args.unsharp
            )):
                parser.error('--rotate/--scale/--contrast/--grayscale/--binary/--channel/--edge-detection/--retrieve-color/--edge-enhancement/--blur/--emboss/--overlap/--texture-detection/--denoise/--sharpen/--unsharp and --output must be given together')
        
        if args.rotate:
            degree = args.rotate
            colourers.info(f'Rotating image to {degree} degree')
            bmp.imageData = Transformers.rotate(bmp, degree)

        if args.scale:
            if len(args.scale) == 2:
                width, height = args.scale
                colourers.info(f'Scaling image to {width}x{height} pixels')
                bmp.imageData = Transformers.scale(bmp, height, width)
            else:
                scaleRatio = args.scale[0]

                colourers.info(f'Scaling image to {scaleRatio} scale ratio')

                height = int(hp.readLittleEndian(bmp.height))
                width = int(hp.readLittleEndian(bmp.width))

                bmp.imageData = Transformers.scale(bmp, height * scaleRatio, width * scaleRatio)
        
        if args.contrast:
            factor = args.contrast
            colourers.info(f'Applying a factor contrast of {factor}')
            bmp.imageData = Transformers.contrast(bmp, factor)
        
        if args.grayscale:
            colourers.info(f'Applying grayscale mask to the image')
            bmp.imageData = Transformers.grayscale(bmp, half)
        
        if args.binary:
            colourers.info(f'Applying binary mask to the image')
            bmp.imageData = Transformers.binary(bmp, half)
        
        if args.invert:
            colourers.info(f'Inverting image colours')
            bmp.imageData = Transformers.invert(bmp, half)
        
        if args.channel:
            if len(args.channel) == 2:
                c1, c2 = args.channel
                colourers.info(f'Keeping only {c1} and {c2} channels of the image')
                bmp.imageData = Transformers.toChannel(bmp, [c1, c2], half)
            else:
                channel = args.channel[0]
                colourers.info(f'Keeping only {channel} channel of the image')
                bmp.imageData = Transformers.toChannel(bmp, channel, half)
        
        if args.denoise:
            colourers.info(f'Denoising the image')
            bmp.imageData = Filters.wienerFilter(bmp.imageData, gaussianKernel(9, sigma=0.33), K=10)
        
        if args.texture_detection:
            colourers.info(f'Applying texture detection (Gabor Filter)')
            bmp.imageData = Filters.gaborFilter(bmp.imageData, gaborKernel(0))
        
        if args.edge_enhancement:
            colourers.info(f'Applying increased edge enhancement filter')
            bmp.imageData = Filters.iee(bmp.imageData)

        if args.edge_detection:
            filterName = args.edge_detection
            if filterName == 'canny':
                colourers.info(f'Performing Canny filter for edge detection')
                bmp.imageData = Filters.ced(bmp.imageData, sigma=0.33, kernelSize=9, weakPix=50)
            if filterName == 'sobel':
                colourers.info(f'Performing Sobel filter for edge detection')
                bmp.imageData = Filters.sed(bmp.imageData, sigma=0.33, kernelSize=9)
            if filterName == 'prewitt':
                colourers.info(f'Performing Prewitt filter for edge detection')
                bmp.imageData = Filters.ped(bmp.imageData, sigma=0.33, kernelSize=9)
            if filterName == 'roberts':
                colourers.info(f'Performing Roberts filter for edge detection')
                bmp.imageData = Filters.red(bmp.imageData, sigma=0.33, kernelSize=9)
            if filterName == 'kirsch':
                colourers.info(f'Performing Kirsch filter for edge detection')
                bmp.imageData = Filters.ked(bmp.imageData, sigma=0.33, kernelSize=9)

        if args.sharpen:
            colourers.info(f'Sharpening the image')
            bmp.imageData = Filters.sharpen(bmp.imageData)
        
        if args.unsharp:
            colourers.info(f'Unsharpening the image')
            bmp.imageData = Filters.unsharp(bmp.imageData)

        if args.retrieve_color:
            colourers.info(f'Retrieving color')
            bmp.imageData = Filters.retrieveColor(bmp.imageData)
        
        if args.blur:
            blurType = args.blur
            colourers.info(f'Performing a {blurType} blur')
            for _ in range(args.blur_iteration):
                blurFunc = Filters.blur.switcher.get(blurType)
                bmp.imageData = blurFunc(bmp.imageData)
        
        if args.emboss:
            colourers.info(f'Performing emboss filter')
            bmp.imageData = Filters.emboss(bmp.imageData)
        
        if args.overlap:
            overlappers = []
            for ov in args.overlap:
                overlappers.append(BMP(ov).imageData)
            colourers.info(f'Performing an overlapping between {bmp.filename} and {args.overlap}')
            bmp.imageData = Filters.overlap(bmp.imageData, overlappers)
       
        if args.output:
            outputFile = args.output
            hp.saveBMP(bmp, bmp.imageData, outputFile)
            colourers.success(f'Succesfully saved into {outputFile}')
            sys.exit(0)
        
        parser.error('Give at least one more argument')
        
    # PNG Block
    else:
        filename = args.png

        if not os.path.isfile(filename):
            print('"{}" does not exist'.format(filename), file=sys.stderr)
            sys.exit(-1)
        print('Success Opening {}...'.format(filename))
        
        png = PNG(filename)