Страницы

Поиск по вопросам

воскресенье, 29 марта 2020 г.

Как обрезать изображение с лицом, найденным с помощью openCV?

#python #python_3x #opencv


Пытаюсь создать функцию, которая будет возвращать обрезанное изображение, если на
нем есть лицо:

def upload_image(request):
data = {"success": False}
if request.method == 'POST':        
    form = forms.FileUploadForm(data=request.POST, files=request.FILES) 
    if form.is_valid():         
        image = grab_image(request.FILES['photo'])
        #fs = FileSystemStorage();
        #fs.save('d', image)
        #path_to_image = settings.MEDIA_ROOT + '\\' + image.name
        #uploaded_image = im.upload_image(path_to_image, title=image.name)
        #uploadet_link = uploaded_image.link
        #fs.delete(image.name)
        # convert the image to grayscale, load the face cascade detector,
        # and detect faces in the image
        image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        detector = cv2.CascadeClassifier(FACE_DETECTOR_PATH)
        rects = detector.detectMultiScale(image, scaleFactor=1.1, minNeighbors=5,
        minSize=(30, 30), flags=cv2.CASCADE_SCALE_IMAGE)
        image = cv2.cvtColor(image, cv2.COLOR_GRAY2RGB)#попытка сделать его цветым
        # construct a list of bounding boxes from the detection
        rects = [(int(x), int(y), int(x + w), int(y + h)) for (x, y, w, h) in rects]
        # update the data dictionary with the faces detected
        data.update({"num_faces": len(rects), "faces": rects, "success": True})
        if(len(rects) > 1):
            pass
        elif(len(rects) < 1):
            pass
        else:
            rect_list = list(map(int,rects[0]))
            crop_img = image[rect_list[1]:rect_list[1] + rect_list[3], rect_list[0]:rect_list[0]
+ rect_list[2]]#обрезка изображения по лицу
            print(type(crop_img))
            normal_image = Image.fromarray(crop_img).convert('RGB')#попытка сделать
его цветым №2
            print(type(normal_image))
            normal_image.save( settings.MEDIA_ROOT + '\\' + str(uuid.uuid4()) + '.jpg')
            #fs = FileSystemStorage();
            #fs.save(str(uuid.uuid4()), normal_image)
            crop_image()
    else:
        print(form.errors)
return JsonResponse(data)

def grab_image(stream):
    data = stream.read()
    # convert the image to a NumPy array and then read it into
    # OpenCV format
    image = np.asarray(bytearray(data), dtype="uint8")
    image = cv2.imdecode(image, cv2.IMREAD_COLOR)
return image


Вот какое изображение я отправляю - изображение на вход и вот, что получаю:
получаю на выходе.

Метод для обрезки нашел здесь. Но он как-то не правильно обрезает. Слишком большая
ширина. Может проблема в самом определении лица? Пробовал и другие фотографии - тоже
самое, в ширину разносит. Еще изображение возвращается в черно-белом, хотя пытаюсь
его окрасить:

image = cv2.cvtColor(image, cv2.COLOR_GRAY2RGB)#попытка сделать его цветым
normal_image = Image.fromarray(crop_img).convert('RGB')#попытка сделать его цветым №2

    


Ответы

Ответ 1



Попробуйте так: FACE_DETECTOR_PATH=r'...\Library\etc\haarcascades\haarcascade_frontalface_default.xml' def crop_face(img, scaleFactor=1.001, face_detector_path=FACE_DETECTOR_PATH): face_cascade = cv2.CascadeClassifier(FACE_DETECTOR_PATH) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) faces = face_cascade.detectMultiScale(gray, scaleFactor, 5) for (x,y,w,h) in faces: #img = cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2) #roi_gray = gray[y:y+h, x:x+w] roi_color = img[y:y+h, x:x+w] return roi_color cropped = crop_face(img, scaleFactor=1.01) cv2.imshow('1', cropped) cv2.imwrite(r'с:/temp/res.png', cropped)

Комментариев нет:

Отправить комментарий