如何在 python 中加快这个图像蒙版创建过程?

Posted

技术标签:

【中文标题】如何在 python 中加快这个图像蒙版创建过程?【英文标题】:How can I speed up this image mask creation process in python? 【发布时间】:2021-01-21 03:30:16 【问题描述】:

我需要为 100.000 张图像创建蒙版,此代码在 cpu 上运行,每小时创建约 500 个蒙版。有没有办法通过并行化或在 gpu 上运行代码来加快速度?我可以接受那些让我大量重写代码的解决方案,只要它能加快进程。

我尝试自己编译带有 cuda 支持的 opencv 库,但是我无法让我在这里使用的大多数 cv2 方法在 gpu 上运行。

这是我的代码

编辑#1

在代码中添加了导入列表和 cmets。

添加了输入和输出图像。

import cv2
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image
import glob
import sys
import os
import skimage.color
import skimage.filters
import skimage.io
import skimage.viewer


grayScale = cv2.imread(filename,cv2.IMREAD_REDUCED_GRAYSCALE_4)#read image as grayscale with size reduction

kernel = cv2.getStructuringElement(1,(17,17))

blackhat = cv2.morphologyEx(grayScale, cv2.MORPH_BLACKHAT, kernel)

ret,thresh2 = cv2.threshold(blackhat,10,255,cv2.THRESH_BINARY)

dst = cv2.inpaint(newimg,thresh2,1,cv2.INPAINT_TELEA)  #4 lines above are used to remove hair from image

mask = np.zeros(dst.shape[:2],np.uint8)

h,w,c = dst.shape

bgdModel = np.zeros((1,65),np.float64)

fgdModel = np.zeros((1,65),np.float64)

rect = (int(0.1*w),int(0.1*h),int(0.8*w),int(0.8*h))

cv2.grabCut(dst,mask,rect,bgdModel,fgdModel,1,cv2.GC_INIT_WITH_RECT) #removes some background from image
#code for k means clustering starts here

mask2 = np.where((mask==2)|(mask==0),0,1).astype('uint8')

dst = dst*mask2[:,:,np.newaxis]

vectorized = dst.reshape((-1,3))

vectorized = np.float32(vectorized)

criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0) #11 lines above are used to remove some background from image

K = 4 
attempts=1

  ret,label,center=cv2.kmeans(vectorized,K,None,criteria,attempts,cv2.KMEANS_PP_CENTERS)

center = np.uint8(center)

labels = label.flatten()

res = center[label.flatten()]

result_image = res.reshape((dst.shape)) #k means clustering ends here

gray = cv2.cvtColor(result_image, cv2.COLOR_BGR2GRAY)

ret, thresh = cv2.threshold(gray, 10, 20, cv2.THRESH_BINARY)

result_image[thresh == 0] = 255

kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))

erosion = cv2.erode(result_image, kernel, iterations = 1)

blur = skimage.color.rgb2gray(erosion)

blur = skimage.filters.gaussian(blur, sigma=float(1)) 

histogram, bin_edges = np.histogram(blur, bins=256, range=(0, 1))

index = next((i for i, x in enumerate(histogram) if x), None)

mask = blur > bin_edges[index+1] #10 lines above are used to create mask

mask = abs(mask-255) #inverts mask

array = np.array(mask, dtype='uint8') 

finimg = cv2.resize(array,None,fx=4.0,fy=4.0) #returns image to original size

plt.imsave("Masks/"+filename, finimg, cmap = plt.cm.gray) #saves result image

input image - skin mole image output image - mask of skin mole

【问题讨论】:

这仅涉及图像处理。多处理将有所帮助。他们使用了多处理:github.com/ocropus/ocropy/blob/master/ocropus-nlbin 我怀疑,如果您描述了您正在尝试做的事情,并提供了各个部分的一些基准/时序,而不是倾倒大量格式不正确、未注释的代码,您可能会得到更好的回应。我只阅读了您的代码的一部分,因为我不知道您要实现什么,但您可能应该将cv2.IMREAD_REDUCED_GRAYSCALE_4 作为imread() 的参数,因为这将显着减少I/O 和内存负载。您还应该进行基准测试,看看时间在哪里。另外,如果你有一个不错的 CPU+RAM+磁盘,请查看多处理。 为什么要删除import 声明?如果询问有关图像处理的问题,请提供具有代表性的输入和输出图像。 @Pygirl 让多处理工作,谢谢。 @MarkSetchell 添加了一些关于代码的作用、输入、输出图像、多处理工作的 cmets,现在我在 imread() 中使用建议的参数。还有什么我可以做的吗? 【参考方案1】:

您可以尝试在 Python/Opencv 中使用 kmeans 处理作为第一步。然后获取内部轮廓并将其用于您的面具。将内部轮廓绘制为黑色背景上的白色填充。您可能需要先使用形态学来清理 kmeans 结果

输入:

Kmeans 2:

Kmeans 3:

Kmeans 4:

【讨论】:

以上是关于如何在 python 中加快这个图像蒙版创建过程?的主要内容,如果未能解决你的问题,请参考以下文章

如何根据蒙版阈值裁剪图像?

如何在处理中加载的 png 图像上创建颜色剪贴蒙版?

使用 OpenCV 在图像上创建矩形区域蒙版

IOS使用drawrect在图像上创建蒙版

在opencv中屏蔽图像

OpenCV:创建一个透明蒙版?