几天前,我遇到了一个项目,要求将草图放到某个文件夹中时删除草图的白色背景。这都是在硬件扫描仪中发生的。
下面是一个草图示例:
第一步是安装此项目的依赖关系,具体需要内容我们将在下面列出。此外,我们还将使用Python 3.7。
代码语言:javascript复制opencv_python==4.1.0.25
pip install opencv-python
numpy==1.16.4
pip install numpy
之后,我们将导入项目所需的所有模块
代码语言:javascript复制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
然后,我们创建三个不同的变量:要处理的文件夹的名称,图像在处理后存储的文件夹的名称,以及在监视文件夹时的轮询时间(即,它检查文件夹中更改的频率,在我们这里设置的是一秒钟)
代码语言:javascript复制watch_folder = ‘toprocess’
processed_folder = ‘processed’
poll_time = 1
文件夹“ toprocess”和“ processed”放置在和我们的python脚本的同一目录中。
然后,我们将介绍我们程序主要功能的代码,它将监视我们的“ toprocess”目录,如果没有发生任何更改,程序将处理存入在该文件夹的所有图像。
代码语言:javascript复制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知识):
代码语言:javascript复制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函数,该函数为文件名生成随机字符串。
代码语言:javascript复制def randomString(length):
letters = string.ascii_lowercase
return ‘’.join(random.choice(letters) for i in range(length))
这是一个简单的功能。它使用“string”库获取字母,然后根据我们传入的长度加入随机选择的字符。传入5的长度将生成5个字符的字符串。
整个程序的处理结果如下所示: