使用图像处理技术进行自拍分割

问题描述 投票:0回答:1

我想在Android上执行自拍分割,类似于Zoom所做的。然而,我希望最好不使用深度学习模型,而是仅依赖传统的图像处理和计算机视觉技术,例如仅使用 OpenCV 或仅使用 Android SDK。 Google MLKit 或 Mediapipe 有此功能,但我不想包含一个大型库来实现此功能,因此库大小是我唯一关心的问题。我的目标是实现快速的自拍分割;可能不是很准确,但只要它不是一个大图书馆就可以了。

我怎样才能做到这一点?我认为像 Zoom 这样的应用程序可能在使用深度学习模型之前就使用了图像处理技术,所以应该有办法实现这一点。

我在Python中使用OpenCV的

grabcut
做了一些简单的实验。但它很慢而且一点也不准确。

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
img = cv.imread('selfie.jpg')
assert img is not None, "file could not be read, check with os.path.exists()"
mask = np.zeros(img.shape[:2],np.uint8)
bgdModel = np.zeros((1,65),np.float64)
fgdModel = np.zeros((1,65),np.float64)
rect = (0,0,530,710)
cv.grabCut(img,mask,rect,bgdModel,fgdModel,5,cv.GC_INIT_WITH_RECT)
mask2 = np.where((mask==2)|(mask==0),0,1).astype('uint8')
img = img*mask2[:,:,np.newaxis]
plt.imshow(img),plt.colorbar(),plt.show()

java android image-processing computer-vision image-segmentation
1个回答
0
投票

您要求提供 Python/OpenCV 中的阈值和形态学示例。在下文中,我将展示一种更好的方法,该方法可以简单地设置阈值并获得最大轮廓。后一种方法不应依赖于图像和阈值。

输入:

import cv2
import numpy as np

# read the input
img = cv2.imread('headshot.png')
hh, ww = img.shape[:2]

# threshold on background
lower = (160,160,160)
upper = (255,255,255)
thresh = cv2.inRange(img, lower, upper)

# invert
thresh = 255 - thresh

# pad
thresh2 = cv2.copyMakeBorder(thresh, 20, 20, 20, 20, borderType=cv2.BORDER_CONSTANT, value=(0,0,0))

# apply morphology open and close to clean up (kernel will be image and threshold dependent)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (15,15))
morph = cv2.morphologyEx(thresh2, cv2.MORPH_OPEN, kernel)
morph = cv2.morphologyEx(morph, cv2.MORPH_CLOSE, kernel)

# invert
morph = 255 - morph

# crop to remove pad
result1 = morph[20:hh+20, 20:ww+20]

# BETTER should be to just get the largest contour from the threshold image
contours = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]
big_contour = max(contours, key=cv2.contourArea)

# draw black filled contour on white background as mas
result2 = np.full_like(thresh, 255)
cv2.drawContours(result2, [big_contour], 0, 0, -1)

# save results
cv2.imwrite('headshot_thresh.png', thresh2)
cv2.imwrite('headshot_morph.png', morph)
cv2.imwrite('headshot_result1.png', result1)
cv2.imwrite('headshot_result2.png', result2)

# show results
cv2.imshow('thresh', thresh2)
cv2.imshow('morph', morph)
cv2.imshow('result1', result1)
cv2.imshow('result2', result2)
cv2.waitKey(0)

阈值图像:

阈值和形态结果:

阈值结果并使用最大轮廓:

© www.soinside.com 2019 - 2024. All rights reserved.