我有一个人像图像,我使用一些k均值和聚类得到这样的图像。
现在我只想从下面的代码中提取出一个用红点指出的头发部分。
import cv2
import numpy as np
img = cv2.imread("Image.jpg")
#Detecting Edge of image
Edge = cv2.Canny(img, 100, 150)
Coords = np.nonzero(Edge)
y = np.min(Coords[0])
y = y + 20
h,w,c = img.shape
x = int(w/2)
cv2.circle(img,(x,y), 5, (0,0,255), -1)
cv2.imshow("dot", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
指向图像的结果是:
但是,我需要头发部分,但是图像大小不应更改。因为我尝试使用Blob选择,它给了我这个结果:
它改变了图像尺寸。但是我希望图像尺寸为原始尺寸,除头发(由红点指向)以外的所有深色像素都变为白色像素。怎么做??有可能吗?
这是我的代码,直到今天:
import cv2
import numpy as np
import dlib
from math import sqrt
import scipy.ndimage as snd
#Facial Landmark Detection
predictor_path = "shape_predictor_68_face_landmarks.dat"
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(predictor_path)
SampleHead = cv2.imread('Test1.jpg')
def facialLandmarks(image):
detect = detector(image)
for k, d in enumerate(detect):
shape = predictor(image, d)
vec = np.empty([68, 2], dtype=int)
for b in range(68):
vec[b][0] = shape.part(b).x
vec[b][1] = shape.part(b).y
return vec
def scale(Himage,a1,a2,b1,b2,x1,x2,y1,y2):
dist1 = sqrt((a2 - a1) ** 2 + (b2 - b1) ** 2)
# print(dist1)
dist2 = sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)
# print(dist2)
r = (dist2/dist1)
# print(r)
Scaled = cv2.resize(Himage, None, fx=r, fy=r, interpolation=cv2.INTER_AREA)
return Scaled
def edgeDetection(image):
Edge = cv2.Canny(image, 100, 150)
Coords = np.nonzero(Edge)
min_x = np.min(Coords[1])
min_y = np.min(Coords[0])
max_x = np.max(Coords[1])
max_y = np.max(Coords[0])
return (min_x, min_y, max_x, max_y)
def blurImage(image,V):
Blurred = cv2.medianBlur(image, V)
return Blurred
def hairExtraction(blurredImg, minimumY, originalImage):
# K-mean approach
Z = blurredImg.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((blurredImg.shape))
x = minimumY + 20
h,w,c = originalImage.shape
y = int(w/2)
# find the index of the cluster of the hair
mask = label1.reshape(output1.shape[:-1])
khair = mask[(x, y)]
# get a mask that's True at all of the indices of hair's group
hairmask = mask == khair
# 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[x, y]
# get an image with just the hair and then crop it
justhair = np.where(haironlymask[..., None], originalImage, [255, 255, 255])
nz = haironlymask.nonzero()
justhair = justhair[nz[0].min()-5:nz[0].max()+5, nz[1].min()-5:nz[1].max()+5]
# save the image of just the hair on a white background
cv2.imwrite("JustHair.jpg", justhair)
finalHair = cv2.imread("JustHair.jpg")
# Perform morphology
se = np.ones((7, 7), dtype='uint8')
hair = cv2.morphologyEx(finalHair, cv2.MORPH_CLOSE, se)
return hair
if __name__ == '__main__':
# Facial Landmark Detection for SampleHead
Hlandmarks = facialLandmarks(SampleHead)
HRightJawlinePoints = (Hlandmarks[0, 0], Hlandmarks[0, 1])
HLeftJawlinePoints = (Hlandmarks[16, 0], Hlandmarks[16, 1])
a1 = HRightJawlinePoints[0]
b1 = HRightJawlinePoints[1]
a2 = HLeftJawlinePoints[0]
b2 = HLeftJawlinePoints[1]
#Scale SampleHead according to size of SampleModel
Resized = scale(SampleHead,a1,a2,b1,b2,x1,x2,y1,y2)
#Detecting value of topmost y of resized head
headExtremeEdgePoints = edgeDetection(Resized)
headMinY = headExtremeEdgePoints[1]
# Blurring effect addition
blurredHeadImage = blurImage(Resized, 5)
# Hair Extraction
headHair = hairExtraction(blurredHeadImage, headMinY, Resized)
cv2.imshow("HeadHair", headHair)
cv2.waitKey(0)
cv2.destroyAllWindows()