Django 使用 opencv2 剪切并仅将人脸放在图片字段中
Django cut and put only the face in the picture field using opencv2
我使用 cv2 对 FaceCropped 进行了编码并且它有效!
我想在 ProcessedImageField 模型中通过 facecropped 方法放置 img。
到底有没有
我想要的是上传图片到学生模型的时候自动切脸存入数据库
裁剪方法
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()
我的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)
我的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)
有几种方法可以实现。
覆盖模型保存方法
将裁剪图像保存到数据库的一种方法是您需要重写保存方法。
看看 this document.
在将数据保存到数据库之前,您可以对模型数据做任何您想处理的事情。您可以自由覆盖这些方法(以及任何其他模型方法)以改变行为。
以下代码来自django文档
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()
继承字段 class 并覆盖清理方法
我假设您使用的是来自 imagekit
的 ProcessedImageField
from imagekit.models import ProcessedImageField
您可以继承 ProcessedImageField
并覆盖 class 字段的 clean method。
清理方法确保字段中的所有数据都清理。保存前的图像处理可以用干净的方法。
以下代码来自django源码
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
覆盖表单清理方法
This question 解释如何覆盖表单清理方法。
清除方法将 运行 在保存方法之前。
这是另一种在保存前更改数据的常用方法。
我解决了!
郝老师加油!
我们可以进一步优化代码吗?
在model.py
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
FaceCropped(self.picture.path)
def FaceCropped(full_path):
face_cascade = cv2.CascadeClassifier('D:/Dropbox/atom/django/Manage/Project/student/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(full_path, mode='w+b') as f:
encoded_img.tofile(f)
我使用 cv2 对 FaceCropped 进行了编码并且它有效!
我想在 ProcessedImageField 模型中通过 facecropped 方法放置 img。
到底有没有
我想要的是上传图片到学生模型的时候自动切脸存入数据库
裁剪方法
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()
我的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)
我的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)
有几种方法可以实现。
覆盖模型保存方法
将裁剪图像保存到数据库的一种方法是您需要重写保存方法。
看看 this document.
在将数据保存到数据库之前,您可以对模型数据做任何您想处理的事情。您可以自由覆盖这些方法(以及任何其他模型方法)以改变行为。
以下代码来自django文档
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()
继承字段 class 并覆盖清理方法
我假设您使用的是来自 imagekit
ProcessedImageField
from imagekit.models import ProcessedImageField
您可以继承 ProcessedImageField
并覆盖 class 字段的 clean method。
清理方法确保字段中的所有数据都清理。保存前的图像处理可以用干净的方法。
以下代码来自django源码
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
覆盖表单清理方法
This question 解释如何覆盖表单清理方法。
清除方法将 运行 在保存方法之前。
这是另一种在保存前更改数据的常用方法。
我解决了!
郝老师加油!
我们可以进一步优化代码吗?
在model.py
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
FaceCropped(self.picture.path)
def FaceCropped(full_path):
face_cascade = cv2.CascadeClassifier('D:/Dropbox/atom/django/Manage/Project/student/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(full_path, mode='w+b') as f:
encoded_img.tofile(f)