Facial detection fails on iPhone photos only using dlib - python

I've been using the dlib library to detect faces, testing on both Python and DotNet wrappers. Both produce the same bizarre issue: poor (low image quality, poor lighting, etc.) images pulled from the internet are almost always detected while photos shot from my iPhone with high quality/lighting are almost never detected.
I am completely certain that the faces shot on my iPhone are of higher quality than those pulled from the internet, yet regardless of how many times I change the lighting and camera angle of my iPhone shots the results are always the same. An occasional iPhone face is detected while the large majority of perfectly acceptable face shots go undetected. I'm at a complete loss, any ideas are much appreciated.
A sample of my relatively straightforward code is below.
from face_recognition import load_image_file, face_locations
faces = face_locations(load_image_file("foo.jpg"))
face_detected = len(faces) >= 1

I figured out a solution and figured I'd share it in case anyone has this specific problem in the future. Converting all images to grayscale fixed literally every undetected face in my dataset. I wrote this in C# instead of Python, but I will share anyway. It can be done using the Emgu.CV library and the following code:
Image<Bgr, byte> emguImage = new Image<Bgr, byte>(path_to_image);
Image<Gray, byte> grayscaleEmguImage = emguImage.Convert<Gray, byte>().Clone();
Bitmap grayscaleBitmapImage = grayscaleEmguImage.ToBitmap();
It's fast and it works.

Could you try deepface as well?
#!pip install deepface
from deepface import DeepFace
img = DeepFace.detectFace("foo.jpg")
It wraps several face detectors actually. Its default detector is mtcnn but you can still set the detector you want.
detectors = ['mtcnn', 'opencv', 'ssd', 'dlib']
DeepFace.detectFace("foo.jpg", detector_backend = detectors[0])
detectFace function return exception if a face could not be detected.

Related

Best image format for face detection and face recognition with the DeepFace library

I'm using the DeepFace library for face recognition and detection.
I was wondering if there is a better format (png, jpg, etc) than others to get better results.
Is there a preferred image format for face recognition and face detection generally? and specifically in this library?
Deepface is wrapped around several face recognition frameworks so the answer to your question should be: it is case-depending issue. However, all basic FR fameworks are not working with the original inpit images, they converting them first to greyscale, downsizing, making numpy arrays and so on usually using OpenCV and PIL for that. So... So, my oppinion is that image file format does not matter. Image file size, colour depth do matter.
This answer is based on an answer from 'Bhargav'.
In python, images are processed as bit bitmaps using the color depth of the graphic system. Converting a PNG image to a bitmap is really fast (20 x times) when compared to jpegs.
In my case, I had the image and needed to save it before proceeding, so I saved it as png so I won't lose quality (jpg is lossy).
Deepace - Currently accepting only 2 types of image input formats. PNG/Jpeg. there is no way to use other formats of images directly as you are using their libraries. If you want to use another input formats so then at least you need to convert either to PNG or Jpeg to give input to the functions. Which may cost you extra execution time while bringing other format images to PNG/Jpegs.
If you want to improve face recognition and face detection with deepface library then use some preprocessing filters.
Some of the filters you can try for better results. ultimate guide
Grayscale conversions
Face straightening
Face cropping (#Deepcae automatically do this while processing so no need to this)
Image resizing
Normalization
Image enhancement with PIL like sharpening.
image equalization.
Some basic filtering will be done by deepface. If your results are not accurate, which means filtering done by deepface is not sufficient, you have to try each and every filter. Something like a trail and error method until you got good results.
sharpening and grayscaling are the first methods to try.

What is the best way to track an object in a video?

I'm trying to learn computer vision and more specifically open-cv in python.
I want to make a program that would track my barbell in a video and show me its path. (I know apps like this exists but I want to make it myself). I tried using the Canny edge detection and the HoughCircles functions but I seem to get everything but a good result.
I have been using this code to find the edges of my image:
gray = cv.cvtColor(src=img, code=cv.COLOR_BGR2GRAY)
blur = cv.blur(gray, (2,2))
canny = cv.Canny(blur, 60, 60)
And then this code to find the circle:
circles = cv.HoughCircles(canny, cv.HOUGH_GRADIENT, dp=2, minDist=1000, circles=None,maxRadius=50)
This is the result:
Result
left = original image with detected circle // right = canny image
Is this the right way to go or should I use another method?
Train the YOLO model for the barbell to detect barbel object is better than anything you tried with OpenCV. You need at least 500 images. Those images can be found on the internet easily. This tutorial is kick start tutorial on YOLO. Let's give a try.
If you tweak the parameters of HoughCircles it may recognize the barbell [EDIT: but with more preprocessing, gamma correction, blurring etc., so better not], however OpenCV has many algorithms for such object tracking - only a region from the image has to be specified first (if that's OK).
In your case the object is always visible and is not changing much, so I guess many of the available algorithms would work fine.
OpenCV has a built-in function for selection:
initBB = cv2.selectROI("Frame", frame, fromCenter=False, showCrosshair=True)
See this tutorial for tracking: https://www.pyimagesearch.com/2018/07/30/opencv-object-tracking/
The summary from the author suggestion is:
CSRT Tracker: Discriminative Correlation Filter (with Channel and Spatial Reliability). Tends to be more accurate than KCF but slightly slower. (minimum OpenCV 3.4.2)
Use CSRT when you need higher object tracking accuracy and can tolerate slower FPS throughput
I guess accuracy is what you want, if it is for offline usage.
Can you share a sample video?
What's your problem exactly? Why do you track the barbell? Do you need semantic segmentation or normal detection? These are important questions. Canny is a very basic approach It' needs a very stable background to use it. That's why there is deep learning to handle that kind of problem If we need to talk about deep learning you can use MaskRCNN, yolvoV4, etc. there are many available solutions out there.

Unable to detect faces of cartoon images

I am trying to implement a simple face detection of cartoons code using opencv and python. Though the code I have used works for faces of humans I am not able to detect cartoon faces using this. Is there any way I can make it detect cartoon faces too.
import cv2
import matplotlib.pyplot as plt
imagePath = 'frame179.jpg'
cascPath = '/Users/tonystark/opencv/data/haarcascades/haarcascade_frontalface_default.xml'
faceCascade = cv2.CascadeClassifier(cascPath)
image = cv2.imread(imagePath)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
faces = faceCascade.detectMultiScale(
gray,
scaleFactor=1.1,
minNeighbors=40,
minSize=(24, 24),
flags=cv2.CASCADE_SCALE_IMAGE
)
The images are human for which I am able to get the location of the face, whereas for cartoon, I am not able to get the location of faces.
Thanks a lot in advance !
Haar cascades are used to detect only one particular thing and in your case, it has been trained to detect only human faces. You will have to create another haar cascade to detect cartoon faces.
You can refer to this video for creating one -https://www.youtube.com/watch?v=jG3bu0tjFbk
Actually I agree with all above comments. There is no ready sollution for catroon objects and I've tried a lot of models and nothing works (ORB, Haar Cascade, SuperPixel and etc.) and no AutoML solution (from Google or Amazon) also does not work. There is only one way to do the face recognition in cartoons objects. This solution is firstly to make your own labeled data set of images and then try to train some models to detect objects. So I've chosen this way, and results are great, 91% accuracy.
So as cartoon images are very different to that of humans, we need to train a model from scratch for them separately.
I implemented a YOLO model, and trained it, and the results were really good !
labelImg can be used to prepare the dataset.
I referred this blog : Darknet YOLO using OpenCV to create my own YOLO detector in which the github repository Darknet YOLO is cloned and modified.
EDIT :
My project on github

OpenCV face detection methods hangs

I have used OpenCVs detectMultiScale and res10_300x300_ssd_iter_140000.caffemodel.forward() methods to detect faces in the images. Exact code is shown.
Both these methods worked well providing good results until a day ago. Today, both of these processes hangs at detectMultiScale and net.forward commands respectively. Additionally when the DNN based model runs, the system memory slowly starts building up until the system hangs.
There has been no modification in any of the python libraries or system configuration in the last day. I have tried to reinstall openCV and python so far which has not been benificial.
#code for For cascade based detection:
faceCascade = cv2.CascadeClassifier('./haarcascade_frontalface_default.xml')
faces = faceCascade.detectMultiScale(frame)
#Python code for For DNN based detection:
modelFile = "res10_300x300_ssd_iter_140000.caffemodel"
configFile = "deploy.prototxt"
net = cv2.dnn.readNetFromCaffe(configFile, modelFile)
net.setInput(blob)
detections = net.forward()
I am unable to understand the reason behind the memory leak that is happening and possible solution to overcome this.

Raspberry pi live video Object detection

I am new to using python and object detection and need some help for a uni project!
1- I am wandering if it is possible to use the same haar cascade file i used to train the pi to detect a specific object in a still image (using the picamera) for detecting the same image in a live video feed as my uni project requires the robot to search and find the specific object and retrieve it or do is it a completely separate process (i.e. setting up classes etc)? if so, where could I i find the most helpful information on doing this as I haven't been too successful when looking online. (pyimagesearch has a blog post on this but goes about using classes and i'm not sure how to go about even creating a class just for a specific object or if you even need one..)
2- Currently, my pi can kind of detect the object (a specific cube) in the still images but isnt very accurate or consistent, it often detects around the edges of the object as well as incorrectly detecting other things in the background or shadows that are part of the image, as the object as well. It tends to find more than one of the cube (lots of small rectangles mostly around - in close proximity) and in the object so it says its detecting 2+ cubes in an image (sometimes 15-20 or more) rather than just the one cube. I am wandering how I could reduce this error and increase the accuracy and consistency of the pi so it detects just the one, or at least doesn't wrongfully detect background shadows or other things in the image? I understand that lighting affects the result but I am wandering if its due to the quality of the original image i took with the picamera of the cube I used to train the haar cascade (it was quite a dark photo due to insufficient lighting), or maybe the size of the image itself (cropped it down to the edges so it is just the cube and resized it to 50x50), or maybe that I didnt train more than one image of the object against negatives when training the cascade file..? do the images you supply for training the pi have to taken with the picamera or could you take clearer pictures say with your phone and use them to train the cascade for detection via the picamera?I tried upgrading the resolution in the code but that made the data analysis take too long and didnt make much difference. Apologies for the long post as I am new to all this and wandering if theres any way to improve the results or is the only way for higher accuracy to retrain the cascade which I'd rather not do as it took two days to complete due to working with a pi zero W board!
Much Appreciated!
My specs: A raspberry pi Zero W board with a 16gb SD Card on Mac, running openCV 3.2 and Python 2.7.
Code for object detection in an image taken using the pi camera:
import io
import picamera
import cv2
import numpy as np
stream = io.BytesIO()
with picamera.PiCamera() as camera: camera.resolution = (320, 240) camera.capture(stream, format='jpeg')
buff = numpy.fromstring(stream.getvalue(), dtype=numpy.uint8)
image = cv2.imdecode(buff, 1)
cube_cascade = cv2.CascadeClassifier('/home/pi/data/cube1-cascade-10stages.xml')
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
Cube = cube_cascade.detectMultiScale(gray, 1.1, 5)
print "Found "+str(len(Cube))+" cube(s)"
for (x,y,w,h) in Cube: cv2.rectangle(image, (x,y), (x+w,y+h), (255,255,0), 2)
cv2.imwrite('result.jpg',image)
Thanks in advance.

Categories