使用OpenCV自动去除背景色
点击上方“小白学视觉”,选择加"星标"或“置顶”
重磅干货,第一时间送达
几天前,我遇到了一个项目,要求将草图放到某个文件夹中时删除草图的白色背景。这都是在硬件扫描仪中发生的。
下面是一个草图示例:
第一步是安装此项目的依赖关系,具体需要内容我们将在下面列出。此外,我们还将使用Python 3.7。
opencv_python==4.1.0.25
pip install opencv-python
numpy==1.16.4
pip install numpy
之后,我们将导入项目所需的所有模块
import cv2
import os
import string
import random
from os import listdir
from os.path import isfile, join, splitext
import time
import sys
import numpy as np
import argparse
然后,我们创建三个不同的变量:要处理的文件夹的名称,图像在处理后存储的文件夹的名称,以及在监视文件夹时的轮询时间(即,它检查文件夹中更改的频率,在我们这里设置的是一秒钟)
watch_folder = ‘toprocess’
processed_folder = ‘processed’
poll_time = 1
文件夹“ toprocess”和“ processed”放置在和我们的python脚本的同一目录中。
然后,我们将介绍我们程序主要功能的代码,它将监视我们的“ toprocess”目录,如果没有发生任何更改,程序将处理存入在该文件夹的所有图像。
before = dict([(f, None) for f in os.listdir(watch_folder)])
while 1:
time.sleep(poll_time)
after = dict([(f, None) for f in os.listdir(watch_folder)])
added = [f for f in after if not f in before]
removed = [f for f in before if not f in after]
if added:
print(“Added “, “, “.join(added))
if added[0] is not None:
processImage(added[0])
if removed:
print(“Removed “, “, “.join(removed))
before = after
这段代码将无限循环运行,直到脚本被杀死为止。启动后,它将文件存储在名为“ before”的词典目录中。接下来,下面将分解介绍无限循环中的步骤:
睡眠指定的poll_time(1秒)。 将文件信息存储在名为after的字典目录中。 通过比较之后的IN和之前的NOT来存储已添加的内容 检查最后添加的元素(added [0])(如果存在),然后调用一个函数,我们将在文件上稍作介绍的processImage进行讨论。 如果已删除,请通过打印一些信息来让用户知道。 最后,将目录中的最新文件进行更新。
接下来介绍processImage函数,这是程序的核心。这就是OpenCV后台删除魔术发生的地方。下面的注释解释了该代码(需要基本的OpenCV知识):
def processImage(fileName):
# Load in the image using the typical imread function using our watch_folder path, and the fileName passed in, then set the final output image to our current image for now
image = cv2.imread(watch_folder + ‘/’ + fileName)
output = image
# Set thresholds. Here, we are using the Hue, Saturation, Value color space model. We will be using these values to decide what values to show in the ranges using a minimum and maximum value.
THESE VALUES CAN BE PLAYED AROUND FOR DIFFERENT COLORS
hMin = 29 # Hue minimum
sMin = 30 # Saturation minimum
vMin = 0 # Value minimum (Also referred to as brightness)
hMax = 179 # Hue maximum
sMax = 255 # Saturation maximum
vMax = 255 # Value maximum
# Set the minimum and max HSV values to display in the output image using numpys' array function. We need the numpy array since OpenCVs' inRange function will use those.
lower = np.array([hMin, sMin, vMin])
upper = np.array([hMax, sMax, vMax])
# Create HSV Image and threshold it into the proper range.
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) # Converting color space from BGR to HSV
mask = cv2.inRange(hsv, lower, upper) # Create a mask based on the lower and upper range, using the new HSV image
# Create the output image, using the mask created above. This will perform the removal of all unneeded colors, but will keep a black background.
output = cv2.bitwise_and(image, image, mask=mask)
# Add an alpha channel, and update the output image variable
*_, alpha = cv2.split(output)
dst = cv2.merge((output, alpha))
output = dst
# Resize the image to 512, 512 (This can be put into a variable for more flexibility), and update the output image variable.
dim = (512, 512)
output = cv2.resize(output, dim)
# Generate a random file name using a mini helper function called randomString to write the image data to, and then save it in the processed_folder path, using the generated filename.
file_name = randomString(5) + ‘.png’
cv2.imwrite(processed_folder + ‘/’ + file_name, output)
接下来是一个非常简单的功能,可以正确地完成工作。再次强调,使用阈值可以提供更好的结果。我们需要讨论的最后一件事是mini helper函数,该函数为文件名生成随机字符串。
def randomString(length):
letters = string.ascii_lowercase
return ‘’.join(random.choice(letters) for i in range(length))
这是一个简单的功能。它使用“string”库获取字母,然后根据我们传入的长度加入随机选择的字符。传入5的长度将生成5个字符的字符串。
整个程序的处理结果如下所示:
交流群
欢迎加入公众号读者群一起和同行交流,目前有SLAM、三维视觉、传感器、自动驾驶、计算摄影、检测、分割、识别、医学影像、GAN、算法竞赛等微信群(以后会逐渐细分),请扫描下面微信号加群,备注:”昵称+学校/公司+研究方向“,例如:”张三 + 上海交大 + 视觉SLAM“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进入相关微信群。请勿在群内发送广告,否则会请出群,谢谢理解~