Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

opencv - Django cut and put only the face in the picture field using opencv2

I coded FaceCropped using cv2 and it works!
I want to put img through facecropped method in ProcessedImageField model.
Is there anyway? What I want is to automatically cut the face and put it in the database when uploading pictures into student model.

method facecropped

import numpy as np
import cv2
import os
import glob

def FaceCropped(full_path, extra='face', show=False):
    face_cascade = cv2.CascadeClassifier('C:../haarcascade_frontalface_default.xml')
    full_path = full_path
    path,file = os.path.split(full_path)


    ff = np.fromfile(full_path, np.uint8)
    img = cv2.imdecode(ff, cv2.IMREAD_UNCHANGED)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    faces = face_cascade.detectMultiScale(gray, 1.3,5)

    for (x,y,w,h) in faces:
        cropped = img[y - int(h/4):y + h + int(h/4), x - int(w/4):x + w + int(w/4)]
        result, encoded_img = cv2.imencode(full_path, cropped)
        if result:
            with open(path + '/' + extra + file, mode='w+b') as f:
                encoded_img.tofile(f)
    if show:
        cv2.imshow('Image view', cropped)
        cv2.waitKey(0)
        cv2.destroyAllWindows()

my model.py

class Student(models.Model):
    picture = ProcessedImageField(
        verbose_name = 'picture',
        upload_to = 'students/%Y/',
        processors=[ResizeToFill(300,300)],
        options={'quality':80},
        format='JPEG',
        null=True,
        blank=True,
        default='students/no-img.jpg',
    )
    name = models.CharField(max_length=255)

my views.py

class StudentAdd(FormView):
    model = Student
    template_name = 'student/list_add.html'
    context_object_name = 'student'
    form_class = AddStudent

    def post(self, request):
        form = self.form_class(request.POST, request.FILES)

        if form.is_valid():
            student = form.save(commit=False)
            student.created_by = request.user

            student.save()
            messages.info(request, student.name + ' addddd', extra_tags='info')
            if "save_add" in self.request.POST:
                return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
            return redirect('student_detail', pk=student.pk, school_year=student.school_year)

        return FormView.post(self, request)
question from:https://stackoverflow.com/questions/65949196/django-cut-and-put-only-the-face-in-the-picture-field-using-opencv2

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There several ways to achieve this.

Override Model Save Method

One way to save crop Image into database is that you need to override the save method.
Have a look at this document.

You can do whatever you want to process on model data before you save data into database. You’re free to override these methods (and any other model method) to alter behavior.

The code below is from django document.

from django.db import models

class Blog(models.Model):
    name = models.CharField(max_length=100)
    tagline = models.TextField()

    def save(self, *args, **kwargs):
        do_something()
        super().save(*args, **kwargs)  # Call the "real" save() method.
        do_something_else()

Inherit Field class and override clean method

I assumed you are using ProcessedImageField from imagekit

from imagekit.models import ProcessedImageField

You can inherit ProcessedImageField and override the clean method of Field classes.

Clean method ensure that all data in field is cleaned. Image processing before saving can be in clean method.

The code below is from django source code.

def clean(self, value):
    """
    Validate the given value and return its "cleaned" value as an
    appropriate Python object. Raise ValidationError for any errors.
    """
    value = self.to_python(value)
    self.validate(value)
    self.run_validators(value)
    return value

Override Form clean method

This question explain how to override form clean method.
Clean method will run before save method.
This is another common way to change the data before saving.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...