python - 提取图像的 k 均值聚类的特定成员

标签 python numpy opencv image-processing

我有一张图片(前面的男人)有 4 种不同的颜色(背景、头发、肤色和布料)。我使用 k-mean 和 k=4,图像被分割。现在我要做的是从图像中提取头发。

我使用canny edge detection来检测边缘,这有助于检测头发区域的点(红点指出)。现在,我想提取头发区域,正如红点指出的 k-mean 成员。可能吗?

或者有没有其他方法可以从人像中提取头发区域?

到目前为止完成的代码是:

import cv2
import numpy as np

image1 = cv2.imread('Test1.jpg')

#Resizing Image for fixed width
def image_resize(image1, width = None, height = None, inter = 
cv2.INTER_AREA):
    # initialize the dimensions of the image to be resized and
    # grab the image size
    dim = None
    (h, w) = image1.shape[:2]

    # if both the width and height are None, then return the
    # original image
    if width is None and height is None:
        return image1

    # check to see if the width is None
    if width is None:
        # calculate the ratio of the height and construct the
        # dimensions
        r = height / float(h)
        dim = (int(w * r), height)

    # otherwise, the height is None
    else:
        # calculate the ratio of the width and construct the
        # dimensions
        r = width / float(w)
        dim = (width, int(h * r))

    # resize the image
    resized = cv2.resize(image1, dim, interpolation = inter)

    # return the resized image
    return resized


img1 = image_resize(image1, width = 500)

cv2.imshow("Resized", img1)
cv2.waitKey(0)

#Detecting Edge of image
canny = cv2.Canny(img1, 100, 150)

cv2.imshow("Edge", canny)
cv2.waitKey(0)

coords = np.nonzero(canny)

topmost_y = np.min(coords[0])


#Blurring effect

img2 = cv2.medianBlur(img1, 5)

cv2.imshow("Blurred", img2)
cv2.waitKey(0)

#K-mean approach
Z = img2.reshape((-1,3))
Z = np.float32(Z)

criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)

K=4
ret, label1, center1 = cv2.kmeans(Z, K, None,
                                          criteria, 10, 
cv2.KMEANS_RANDOM_CENTERS)
center1 = np.uint8(center1)
res1 = center1[label1.flatten()]
output1 = res1.reshape((img2.shape))

cv2.circle(output1, (250, topmost_y + 20), 5, (0,0,255), -1)

cv2.imshow("k = 4", output1)
cv2.waitKey(0)
cv2.destroyAllWindows()

图片:

Original Image , Result after resizing , Canny Edge detection , Blurred , K-mean

最佳答案

根据您已有的代码,您只需多加几行即可获得头发所属簇的 xy 坐标。您还可以创建仅显示头发簇的图像:

# find the index of the cluster of the hair
mask = label1.reshape(output1.shape[:-1])
khair = mask[(topmost_y + 20, 250)]

# get a mask that's True at all of the indices of hair's group
hairmask = mask==khair

# get the hair's cluster's xy coordinates
xyhair = hairmask.nonzero()

# plot an image with only the hair's cluster on a white background
cv2.imwrite("khair.jpg", np.where(hairmask[..., None], img1, [255,255,255]))

这是头发簇的样子:

enter image description here

一旦你有了头发的簇,你就可以找到代表“只是头发”的 Blob 。以下是您的操作方式:

import scipy.ndimage as snd

# label all connected blobs in hairmask
bloblab = snd.label(hairmask, structure=np.ones((3,3)))[0]

# create a mask for only the hair
haironlymask = bloblab == bloblab[topmost_y + 20, 250]

# get an image with just the hair and then crop it
justhair = np.where(haironlymask[..., None], img1, [255,255,255])
nz = haironlymask.nonzero()
justhair = justhair[nz[0].min():nz[0].max(), nz[1].min():nz[1].max()]

# save the image of just the hair on a white background
cv2.imwrite("justhair.jpg", justhair)

这是你头发的图片:

enter image description here

关于python - 提取图像的 k 均值聚类的特定成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53848174/

相关文章:

python - 传递参数时重定向

python - Scrapy dmoz教程,csv文件中没有desc数据

image-processing - 空间卷积与频率卷积图像的逆滤波器

arrays - 在 Numpy 中创建不规则数字数组

java - 使用 OpenCV 和 JavaCV 捕获具有间隔的帧

java - 使用opencv进行人脸检测不起作用

c++ - Opencv VideoWriter 只保存一帧

python - 使用 Tweepy 的 Twitter 机器人 - Python

python - Paramiko:从远程执行命令的标准输出中读取

python - 在没有循环的情况下在数组中累加数字。 (Python)