【问题标题】:Detect color and remove that color from image检测颜色并从图像中删除该颜色
【发布时间】:2020-02-07 00:31:18
【问题描述】:

我的图像背景为浅紫色,字符为深蓝色。我的目标是从图像中识别文本。所以我试图从背景中去除浅紫色,这样我的图像就没有噪音了,但我找不到该图像的确切颜色代码,因为它在各处都有些不同,所以我无法掩盖图片。这是我的代码

import numpy as np
from PIL import Image

im = Image.open('capture.png')

im = im.convert('RGBA')
data = np.array(im)

rgb = data[:,:,:3]
color = [27, 49, 89]   # Original value to be mask
black = [0,0,0, 255]
white = [255,255,255,255]
mask = np.all(rgb == color, axis = -1)
data[mask] = black
data[np.logical_not(mask)] = white

new_im = Image.fromarray(data)
new_im.save('new_file.png')

所以我想如果我可以去除所有特定颜色范围内的颜色,例如 [R:0-20, G:0-20, B:80-100],也许会奏效。有人可以告诉我我该怎么做。

任何其他解决此问题的建议也将不胜感激。

【问题讨论】:

  • 您似乎想入侵一个网站?如果不是,不知道为什么要获取已有的信息?
  • @user1438644 哈哈,不,这是我学校的深度学习课程项目。
  • 大多数情况下,您可以使用其中一个通道对图像进行阈值处理,但很难在没有看到图像的情况下推荐一种方法 - 愿意帮助您的志愿者应该如何重现您的问题?
  • 为什么要拍摄一张图像并将其转换为 4 个通道,然后再拍摄前 3 个?为什么不首先使用im = Image.open(...).convert('RGB') 将其转换为 3 通道?
  • 请添加您的图片。谢谢。

标签: python image image-processing computer-vision captcha


【解决方案1】:

由于文本和背景之间似乎存在可区分的阴影,因此颜色阈值应该在这里起作用。想法是将图像转换为 HSV 格式,然后使用上下阈值生成二进制分段掩码,然后按位提取文本。这是一个使用 Python OpenCV 的实现


使用这个上下阈值,我们得到这个掩码

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

然后我们用原始图像按位与

最后我们阈值得到一个二值图像,前景文本为黑色,背景为白色

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()

您可以使用此 HSV 颜色阈值脚本来确定下限和上限阈值

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()

【讨论】:

  • 它像宝石一样工作。非常感谢你,你是天才
  • bdw 我可以将黑白图像转换为黑白图像吗?喜欢白色背景和黑色文字
  • @VIBHUBAROT,将图像转换为灰度然后使用cv2.bitwise_not()image = 255 - image
  • 我认为您正在寻找图像阈值,检查更新
【解决方案2】:

这是一种使用像素阵列的方法。像素阵列很慢,但如果速度不是问题,它们可以满足您的需求,而无需下载任何外部库。另外,像素数组也很容易理解。

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()

只需测试每个 r、g、b 值,看看它们是否在每个颜色分量的某个所需范围内。然后将每个像素复制到一个新的表面,用您想要的替换颜色替换您范围内的所有颜色。

或者您可以在将像素放入新图像之前,向每个 R、G、B 颜色分量添加 75(如果颜色 > 255:颜色 = 255)。这将具有使所有颜色淡化为白色的效果,直到浅色消失。然后,您可以重复该过程,从每个剩余像素(分量值小于 255)中减去 75,以使颜色再次向前。我怀疑任何像样的验证码都这么容易被打败,但是你去吧。

好玩好玩!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-16
    • 2018-07-16
    • 1970-01-01
    • 2019-05-12
    • 1970-01-01
    • 1970-01-01
    • 2023-04-11
    • 2015-05-08
    相关资源
    最近更新 更多