Detect color and remove that color from image

前端 未结 2 1079
北荒
北荒 2021-01-07 03:36

I have image with kind of light purple image in background and character in dark blue. My goal is to identify text from the image. So I\'m trying to remove light purple colo

相关标签:
2条回答
  • 2021-01-07 03:53

    Here is an approach using a pixel array. Pixel arrays are slow, but if speed isn't an issue, they could serve your needs without having to download any outside libraries. Also, pixel arrays are easy to understand.

    import pygame
    # -- You would load your image as a sprite here. --
    # -- But let's create a demonstration sprite instead.--
    #
    usecolor = (46,12,187,255)       # Declare an example color.
    sprite = pygame.Surface((10,10)) # Greate a surface. Let us call it a 'sprite'.
    sprite.fill(usecolor)            # Fill the 'sprite' with our chosen color.
    #
    # -- Now process the image. --
    array = pygame.PixelArray(sprite)   # Create a pixel array of the sprite, locking the sprite.
    sample = array[5,5]                 # Sample the integer holding the color values of pixel [5,5]
                                        # We will feed this integer to pygame.Color()
    sample_1 = sprite.get_at((5,5))     # Alternately, we can use the .get_at() method.
    # Do the same for every pixel, creating a list (an array) of color values.
    del array                           # Then delete the pixel array, unlocking the sprite.
    
    m,r,g,b = pygame.Color(sample) # Note: m is for the alpha value (not used by .Color()) 
    
    print("\n sample =",sample,"decoded by python.Color() to:")
    print(" r >>",r)
    print(" g >>",g)
    print(" b >>",b)
    print("\n or we could use .get_at()")
    print(" sample_1 =",sample_1)
    print()
    exit()
    

    Just test each r,g,b value to see if they fall within some desired range for each color component. Then copy each pixel over to a new surface, replacing all colors that fall within your range with your desired replacement color.

    Or you could add, say 75 to each R,G,B color component (if color > 255: color = 255) before placing the pixel in the new image. This would have the effect of fading all colors towards white until the light color is gone. Then you could repeat the process subtracting 75 from each remaining pixel (with component values less than 255) to bring the colors forward again. I doubt any decent captcha is so easily defeated, but there you go.

    Fun fun!

    0 讨论(0)
  • 2021-01-07 04:04

    Since there seems to be a distinguishable shade from the text and the background, color thresholding should work here. The idea is to convert the image to HSV format then use a lower and upper threshold to generate a binary segmented mask then bitwise-and to extract the text. Here's an implementation using Python OpenCV


    Using this lower and upper threshold, we obtain this mask

    lower = np.array([0, 120, 0])
    upper = np.array([179, 255, 255])
    

    Then we bitwise-and with the original image

    Finally we threshold to get a binary image with the foreground text in black and the background in white

    import numpy as np
    import cv2
    
    # Color threshold
    image = cv2.imread('1.png')
    original = image.copy()
    hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
    lower = np.array([0, 120, 0])
    upper = np.array([179, 255, 255])
    mask = cv2.inRange(hsv, lower, upper)
    result = cv2.bitwise_and(original,original,mask=mask)
    result[mask==0] = (255,255,255)
    
    # Make text black and foreground white
    result = cv2.cvtColor(result, cv2.COLOR_BGR2GRAY)
    result = cv2.threshold(result, 0, 255, cv2.THRESH_OTSU + cv2.THRESH_BINARY)[1]
    
    cv2.imshow('mask', mask)
    cv2.imshow('result', result)
    cv2.waitKey()
    

    You can use this HSV color threshold script to determine the lower and upper thresholds

    import cv2
    import sys
    import numpy as np
    
    def nothing(x):
        pass
    
    # Load in image
    image = cv2.imread('1.png')
    
    # Create a window
    cv2.namedWindow('image')
    
    # create trackbars for color change
    cv2.createTrackbar('HMin','image',0,179,nothing) # Hue is from 0-179 for Opencv
    cv2.createTrackbar('SMin','image',0,255,nothing)
    cv2.createTrackbar('VMin','image',0,255,nothing)
    cv2.createTrackbar('HMax','image',0,179,nothing)
    cv2.createTrackbar('SMax','image',0,255,nothing)
    cv2.createTrackbar('VMax','image',0,255,nothing)
    
    # Set default value for MAX HSV trackbars.
    cv2.setTrackbarPos('HMax', 'image', 179)
    cv2.setTrackbarPos('SMax', 'image', 255)
    cv2.setTrackbarPos('VMax', 'image', 255)
    
    # Initialize to check if HSV min/max value changes
    hMin = sMin = vMin = hMax = sMax = vMax = 0
    phMin = psMin = pvMin = phMax = psMax = pvMax = 0
    
    output = image
    wait_time = 33
    
    while(1):
    
        # get current positions of all trackbars
        hMin = cv2.getTrackbarPos('HMin','image')
        sMin = cv2.getTrackbarPos('SMin','image')
        vMin = cv2.getTrackbarPos('VMin','image')
    
        hMax = cv2.getTrackbarPos('HMax','image')
        sMax = cv2.getTrackbarPos('SMax','image')
        vMax = cv2.getTrackbarPos('VMax','image')
    
        # Set minimum and max HSV values to display
        lower = np.array([hMin, sMin, vMin])
        upper = np.array([hMax, sMax, vMax])
    
        # Create HSV Image and threshold into a range.
        hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
        mask = cv2.inRange(hsv, lower, upper)
        output = cv2.bitwise_and(image,image, mask= mask)
    
        # Print if there is a change in HSV value
        if( (phMin != hMin) | (psMin != sMin) | (pvMin != vMin) | (phMax != hMax) | (psMax != sMax) | (pvMax != vMax) ):
            print("(hMin = %d , sMin = %d, vMin = %d), (hMax = %d , sMax = %d, vMax = %d)" % (hMin , sMin , vMin, hMax, sMax , vMax))
            phMin = hMin
            psMin = sMin
            pvMin = vMin
            phMax = hMax
            psMax = sMax
            pvMax = vMax
    
        # Display output image
        cv2.imshow('image',output)
    
        # Wait longer to prevent freeze for videos.
        if cv2.waitKey(wait_time) & 0xFF == ord('q'):
            break
    
    cv2.destroyAllWindows()
    
    0 讨论(0)
提交回复
热议问题