cpp:1389 Error Assertion Failed detectmultiscale in face detection - python

Error:OpenCV(4.5.1) /tmp/pip-req-build-tk9iuyva/opencv/modules/objdetect/src/cascadedetect.cpp:1389: error: (-215:Assertion failed) scaleFactor > 1 && _image.depth() == CV_8U in function 'detectMultiScale'
I tried adding gray = np.array(gray, dtype='uint8') and the error disappears but the box that should appear when detecting a face does not appear
import tensorflow as tf
import keras
from tensorflow.keras.applications.mobilenet_v2 import preprocess_input
from tensorflow.keras.preprocessing.image import img_to_array
from tensorflow.keras.preprocessing.image import load_img
import numpy as np
import argparse
import cv2
import os
import matplotlib.pyplot as plt
%matplotlib inline
model = tf.keras.models.load_model("../input/modelh5/My_Model.h5")
images=['../input/face-mask1/examples/example_01.png', '../input/face-mask1/examples/example_02.png', '../input/face-mask1/examples/example_03.png' ]
face_cascade = cv2.CascadeClassifier('../input/haarcascade/haarcascade_frontalface_default.xml')
img = images[0] # Add path here
img = plt.imread(img,format='8UC1')
gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
# Draw the rectangle around each face
for (x, y, w, h) in faces:
face = img[y:y+h, x:x+w]
face = cv2.resize(face, (224, 224))
face = img_to_array(face)
face = preprocess_input(face)
face = np.expand_dims(face, axis=0)
(mask, withoutMask) = model.predict(face)[0]
mask = mask*100
withoutMask = withoutMask*100
font = cv2.FONT_HERSHEY_SIMPLEX
# Getting Text Size in pixel
print("Image Width: " , w)
textSize = cv2.getTextSize(text="No Mask: " + str("%.2f" % round(mask, 2)), fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=1, thickness=3)
print("Text Width: " , textSize[0][0])
if mask > withoutMask:
cv2.putText(img,
text = "Mask: " + str("%.2f" % round(mask, 2)),
org = (x-5,y-15),
fontFace=font,
fontScale = (2*w)/textSize[0][0],
color = (0, 255, 0),
thickness = 3,
lineType = cv2.LINE_AA)
cv2.rectangle(img, (x, y), (x+w, y+h), (0,255,0), 5)
else:
cv2.putText(img,
text = "No Mask: " + str("%.2f" % round(withoutMask, 2)),
org = (x-5,y-15),
fontFace=font,
fontScale = (1.8*w)/textSize[0][0],
color = (255, 0, 0),
thickness = 3,
lineType = cv2.LINE_AA)
cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 5)
# Display
plt.imshow(img)
img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)

Related

Python: removing black pixels from an image where the text to be extracted is black

I have the following code to extract text from an image
img = cv2.imread('download.jpg')
text = pytesseract.image_to_string(img, lang='lets', config='--psm 6 ')
solution = re.sub('[^0-9]','', text)
However using an image like below where it says 1981, the actual text that gets pulled back is 5139011
Any suggestions?
Most important part is to clean pepper noise. After some opencv operations (maybe not the best ones) i achieve this clean image:
To get expected text extraction i use this tesseract trained font:
Trained data
Here's the result:
And here's the code:
import cv2
import numpy as np
import pytesseract
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract'
img = cv2.imread('a.jpg')
grayImage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
(_, blackWhiteImage) = cv2.threshold(grayImage, 127, 255, cv2.THRESH_BINARY)
blackWhiteImage = cv2.copyMakeBorder(src=blackWhiteImage, top=50, bottom=50, left=50, right=50, borderType=cv2.BORDER_CONSTANT, value=(255,255,255))
blackWhiteImage = cv2.dilate(blackWhiteImage, cv2.getStructuringElement(cv2.MORPH_RECT, (1,4)))
blackWhiteImage = cv2.dilate(blackWhiteImage, cv2.getStructuringElement(cv2.MORPH_RECT, (4,1)))
blackWhiteImage = cv2.morphologyEx(blackWhiteImage, cv2.MORPH_CLOSE, np.ones((3,3),np.uint8))
blackWhiteImage = cv2.erode(blackWhiteImage, np.ones((7,7),np.uint8))
data = pytesseract.image_to_data(blackWhiteImage, lang="lets", config="-c tessedit_char_whitelist=0123456789 --psm 7")
originalImage = cv2.cvtColor(blackWhiteImage, cv2.COLOR_GRAY2BGR)
text = []
for z, a in enumerate(data.splitlines()):
if z != 0:
a = a.split()
if len(a) == 12:
x, y = int(a[6]), int(a[7])
w, h = int(a[8]), int(a[9])
cv2.rectangle(originalImage, (x, y), (x + w, y + h), (0, 255, 0), 1)
cv2.putText(originalImage, a[11], (x, y - 2), cv2.FONT_HERSHEY_DUPLEX, 0.5, (0, 0, 255), 1)
text.append(a[11]);
print("Text result: \n", text)
cv2.imshow('Image result', originalImage)
cv2.waitKey(0)

Combining Face Recognition with Face Emotion recognizer from webcam

I have a task where my job is to code a face recognizer which then analyses the pictures, compares it to a live webcam footage and displays the name of the person aswell as the dominant emotion.
What i currently have is this code snippet i took from this link: https://www.geeksforgeeks.org/face-detection-using-python-and-opencv-with-webcam/ and that i modified to this:
import cv2, sys, numpy, os
from keras.preprocessing.image import load_img, img_to_array
from keras.models import load_model
import matplotlib.pyplot as plt
import numpy as np
from deepface import DeepFace
size = 4
haar_file = 'haarcascade_frontalface_default.xml'
datasets = 'datasets'
# Part 1: Create fisherRecognizer
print('Recognizing Face Please Be in sufficient Lights...')
# Create a list of images and a list of corresponding names
(images, labels, names, id) = ([], [], {}, 0)
for (subdirs, dirs, files) in os.walk(datasets):
for subdir in dirs:
names[id] = subdir
subjectpath = os.path.join(datasets, subdir)
for filename in os.listdir(subjectpath):
path = subjectpath + '/' + filename
label = id
images.append(cv2.imread(path, 0))
labels.append(int(label))
id += 1
(width, height) = (130, 100)
# Create a Numpy array from the two lists above
(images, labels) = [numpy.array(lis) for lis in [images, labels]]
# OpenCV trains a model from the images
# NOTE FOR OpenCV2: remove '.face'
model = cv2.face.LBPHFaceRecognizer_create()
model.train(images, labels)
# Part 2: Use fisherRecognizer on camera stream
face_cascade = cv2.CascadeClassifier(haar_file)
webcam = cv2.VideoCapture(0)
emotion_dict = {
0: 'Surprise',
1: 'Happy',
2: 'Disgust',
3: 'Anger',
4: 'Sadness',
5: 'Fear',
6: 'Contempt'
}
while True:
(_, im) = webcam.read()
gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
for (x, y, w, h) in faces:
cv2.rectangle(im, (x, y), (x + w, y + h), (255, 0, 0), 2)
face = gray[y:y + h, x:x + w]
face_resize = cv2.resize(face, (width, height))
# Try to recognize the face
prediction = model.predict(face_resize)
cv2.rectangle(im, (x, y), (x + w, y + h), (0, 255, 0), 3)
max_index = np.argmax(prediction[0])
emotions = ('angry', 'disgust', 'fear', 'happy', 'sad', 'surprise', 'neutral')
predicted_emotion = emotions[max_index]
cv2.putText(im, predicted_emotion, (int(x), int(y)), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
if prediction[1]<500:
cv2.putText(im, '% s - %.0f' %
(names[prediction[0]], prediction[1]), (x-10, y-10),
cv2.FONT_HERSHEY_PLAIN, 1, (0, 255, 0))
else:
cv2.putText(im, 'not recognized',
(x-10, y-10), cv2.FONT_HERSHEY_PLAIN, 1, (0, 255, 0))
cv2.imshow('OpenCV', im)
key = cv2.waitKey(10)
if key == 27:
break
however, when i try to run it, it only says that my emotion is angry, even though i am smiling or frowning. Does anyone have a suggestion to why this is? I'm eager to figure it out so comments are greatly appreciated
I got it to work now by using fer (pip install fer).

My Code is only detecting single face only after applying For Loop also

I am trying to Detect Emotions using my model which takes images as an array, but my code is detecting faces using MTCNN in which the code is detecting only a single face, I have also applied for loop but still it is detecting single face only. Detecting Single face in Single Frame.
import keras
from keras.models import load_model
from time import sleep
from keras.preprocessing.image import img_to_array
from keras.preprocessing import image
import cv2
import numpy as np
from configs import Configs
from PIL import Image
from keras.applications.vgg16 import preprocess_input
from mtcnn.mtcnn import MTCNN
cfg = Configs()
detector = MTCNN()
model = load_model(cfg.model_path)
emotions = ['Angry', 'Disgust', 'Fear', 'Happy',
'Neutral', 'Pain', 'Sad', 'Surprise']
# Sample Video on which we have to Test
cap = cv2.VideoCapture(cfg.video_path)
while(cap.isOpened()):
ret, frame = cap.read()
faces = detector.detect_faces(frame)
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
if ret == False:
break
#for face in faces:
# x = faces[0]['box'][0]
# y = faces[0]['box'][1]
# w = faces[0]['box'][2]
# h = faces[0]['box'][3]
#face = x,y,w,h
for face in faces:
x = faces[0]['box'][0]
y = faces[0]['box'][1]
w = faces[0]['box'][2]
h = faces[0]['box'][3]
cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 255), 2)
roi_gray = gray[y:y+h, x:x+w]
roi_gray = cv2.resize(roi_gray, (48, 48), interpolation=cv2.INTER_AREA)
if np.sum([roi_gray]) != 0:
roi = roi_gray.astype('float')/255.0
roi = img_to_array(roi)
roi = np.expand_dims(roi, axis=0)
prediction = model.predict(roi)[0]
label = emotions[prediction.argmax()]
label_position = (x, y)
cv2.putText(frame, label, label_position,
cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
else:
cv2.putText(frame, 'No Faces', (30, 80),
cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
size = cv2.resize(frame[:, :, ::1], (560, 640))
cv2.imshow('Emotion Detector', size)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()

Getting an error in an OpenCV project (Project to recognize the face of a person using LBPH)

I am making a project to recognize the person by his/her face using OpenCV library in Python.
My code is :-
# Import OpenCV and sys libraries
import cv2
import sys
import os
import numpy as np
subjects = ["", "Daksh", "Ishika", "Dashya", "Shivang"]
#Create the haar cascade
faceCascade = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
def draw_rectangle(img, rect):
(x, y, w, h) = rect
cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2)
def draw_text(img, text, x, y):
cv2.putText(img, text, (x, y), cv2.FONT_HERSHEY_PLAIN, 1.5, (0, 255, 0), 2)
def imgdetect(gray,image):
#Detect faces in the image
faces = faceCascade.detectMultiScale(gray, 1.3, 5)
#Draw a rectangle around the faces
for (x, y, w, h) in faces:
cv2.rectangle(image, (x, y), (x+w, y+h), (0, 255, 0), 2)
roi_gray = gray[y:y+h, x:x+w]
roi_color = image[y:y+h, x:x+w]
return image
#for video capturing
vidCapture = cv2.VideoCapture(0)
while True:
# To capture video frame by frame
_, image = vidCapture.read()
#monochrome image capturing (color to gray)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
subjects = ["Daksh", "Ishika", "Shivang", "Dashya"]
canvas = imgdetect(gray, image)
gray, rect = detect_face(image)
label = face_recognizer.predict(gray)
label_text = subjects[label]
#draw a rectangle around face detected
draw_rectangle(canvas, rect)
#draw name of predicted person
draw_text(canvas, label_text, rect[0], rect[1]-5)
cv2.imshow("Attendence....", canvas)
#To break control by pressing 'q'
if cv2.waitKey(1) & 0xff == ord('q'):
break
#Release after processing is done
vidCapture.release()
cv2.destroyAllWindows()
But, I am getting the following error while proceeding with the code
---------------------------------------------------------------------------
error Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_13428/371309763.py in <module>
40 canvas = imgdetect(gray, image)
41 img, rect = detect_face(image)
---> 42 label = face_recognizer.predict(img)
43 label_text = subjects[label]
44
error: OpenCV(4.5.4) D:\a\opencv-python\opencv-python\opencv\modules\core\src\matrix.cpp:250: error: (-215:Assertion failed) s >= 0 in function 'cv::setSize'
I am unable to understand the error message.
Why am I getting this error and what can be the possible fixes for the error?

Read multi images in a folder python

I am trying to read read multi images on a folder and do some processing. I have a code that extracts facial landmark coordinates. But I can apply this code to only one image. I want the script to work with all images in the folder. I have read some solutions but they didn't work for me. Can you tell me how can I apply a loop for this?
This is my code:
import numpy as np
import cv2
import dlib
import os
from glob import glob
mouth_matrice= open("C:/Users/faruk/Desktop/matrices/mouth.txt","w")
lefteye_matrice= open("C:/Users/faruk/Desktop/matrices/lefteye.txt","w")
righteye_matrice= open("C:/Users/faruk/Desktop/matrices/righteye.txt","w")
cascPath = ("C:/opencv/sources/data/haarcascades_cuda/haarcascade_frontalface_default.xml")
all_matrice= open("C:/Users/faruk/Desktop/matrices/all.txt","w")
#imagePath = ("C:/Users/faruk/Desktop/Dataset/Testing/342_spontaneous_smile_4 (2-17-2018 8-37-58 PM)/342_spontaneous_smile_4 357.jpg")
mypath=os.path.join("c:", os.sep, "Users", "faruk", "Desktop", "Dataset","Testing2")
PREDICTOR_PATH = ("C:/Users/faruk/Desktop/Working projects/facial-landmarks/shape_predictor_68_face_landmarks.dat")
JAWLINE_POINTS = list(range(0, 17))
RIGHT_EYEBROW_POINTS = list(range(17, 22))
LEFT_EYEBROW_POINTS = list(range(22, 27))
NOSE_POINTS = list(range(27, 36))
#RIGHT_EYE_POINTS = list(range(36, 42))
RIGHT_EYE_POINTS = list([36,39])
ALL_POINTS= list([36,39,42,45,48,51,54,57])
##LEFT_EYE_POINTS = list(range(42, 48))
LEFT_EYE_POINTS = list([42, 45])
##MOUTH_OUTLINE_POINTS = list(range(48, 61))
MOUTH_OUTLINE_POINTS = list([48,51,54,57])
MOUTH_INNER_POINTS = list(range(61, 68))
# Create the haar cascade
faceCascade = cv2.CascadeClassifier(cascPath)
predictor = dlib.shape_predictor(PREDICTOR_PATH)
# Read the image
cv2.namedWindow('Landmarks found',cv2.WINDOW_NORMAL)
cv2.resizeWindow('Landmarks found', 800,800)
image = cv2.imread(imagePath)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# Detect faces in the image
faces = faceCascade.detectMultiScale(
gray,
scaleFactor=1.05,
minNeighbors=5,
minSize=(100, 100),
flags=cv2.CASCADE_SCALE_IMAGE
)
print("Found {0} faces!".format(len(faces)))
for (x, y, w, h) in faces:
cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)
# Converting the OpenCV rectangle coordinates to Dlib rectangle
dlib_rect = dlib.rectangle(int(x), int(y), int(x + w), int(y + h))
landmarks = np.matrix([[p.x, p.y]
for p in predictor(image, dlib_rect).parts()])
#landmarks_display = landmarks[LEFT_EYE_POINTS]
landmarks_display = np.matrix(landmarks[ALL_POINTS])
for idx, point in enumerate(landmarks_display):
pos = (point[0, 0], point[0, 1])
cv2.circle(image, pos, 2, color=(0, 255, 255), thickness=-1)
np.savetxt(all_matrice,landmarks_display,fmt='%.f',newline=',')
all_matrice.close()
# Draw a rectangle around the faces
cv2.imshow("Landmarks found", image)
cv2.waitKey(0)
You can use something like this to get paths of all images in a directory:
import os
# Folder with images
directory = 'c:/users/username/path/'
for filename in os.listdir(directory):
if filename.endswith(".jpg"):
image_path = os.path.join(directory, filename)
# Your code
continue
else:
continue
You need to add your code and process each path.
Hope this helps.
Edit:
I have no way to test it and it certainly needs a cleanup but might just work. Not sure what image extensions you want to include so i only included jpg.
import os
import numpy as np
import cv2
import dlib
# Chage directory path to the path of your image folder
directory = 'c:/users/admin/desktop/'
mouth_matrice= open("C:/Users/faruk/Desktop/matrices/mouth.txt","w")
lefteye_matrice= open("C:/Users/faruk/Desktop/matrices/lefteye.txt","w")
righteye_matrice= open("C:/Users/faruk/Desktop/matrices/righteye.txt","w")
cascPath = ("C:/opencv/sources/data/haarcascades_cuda/haarcascade_frontalface_default.xml")
all_matrice= open("C:/Users/faruk/Desktop/matrices/all.txt","w")
mypath=os.path.join("c:", os.sep, "Users", "faruk", "Desktop", "Dataset","Testing2")
PREDICTOR_PATH = ("C:/Users/faruk/Desktop/Working projects/facial-landmarks/shape_predictor_68_face_landmarks.dat")
JAWLINE_POINTS = list(range(0, 17))
RIGHT_EYEBROW_POINTS = list(range(17, 22))
LEFT_EYEBROW_POINTS = list(range(22, 27))
NOSE_POINTS = list(range(27, 36))
#RIGHT_EYE_POINTS = list(range(36, 42))
RIGHT_EYE_POINTS = list([36,39])
ALL_POINTS= list([36,39,42,45,48,51,54,57])
##LEFT_EYE_POINTS = list(range(42, 48))
LEFT_EYE_POINTS = list([42, 45])
##MOUTH_OUTLINE_POINTS = list(range(48, 61))
MOUTH_OUTLINE_POINTS = list([48,51,54,57])
MOUTH_INNER_POINTS = list(range(61, 68))
# Create the haar cascade
faceCascade = cv2.CascadeClassifier(cascPath)
predictor = dlib.shape_predictor(PREDICTOR_PATH)
for filename in os.listdir(directory):
if filename.endswith(".jpg"):
imagePath=os.path.join(directory, filename)
cv2.namedWindow('Landmarks found',cv2.WINDOW_NORMAL)
cv2.resizeWindow('Landmarks found', 800,800)
image = cv2.imread(imagePath)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# Detect faces in the image
faces = faceCascade.detectMultiScale(gray,
scaleFactor=1.05,
minNeighbors=5,
minSize=(100, 100),
flags=cv2.CASCADE_SCALE_IMAGE
)
print("Found {0} faces!".format(len(faces)))
for (x, y, w, h) in faces:
cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)
# Converting the OpenCV rectangle coordinates to Dlib rectangle
dlib_rect = dlib.rectangle(int(x), int(y), int(x + w), int(y + h))
landmarks = np.matrix([[p.x, p.y] for p in predictor(image, dlib_rect).parts()])
#landmarks_display = landmarks[LEFT_EYE_POINTS]
landmarks_display = np.matrix(landmarks[ALL_POINTS])
for idx, point in enumerate(landmarks_display):
pos = (point[0, 0], point[0, 1])
cv2.circle(image, pos, 2, color=(0, 255, 255), thickness=-1)
np.savetxt(all_matrice,landmarks_display,fmt='%.f',newline=',')
all_matrice.close()
# Draw a rectangle around the faces
cv2.imshow("Landmarks found", image)
cv2.waitKey(0)
continue
else:
continue
P.s You should try and learn basic programming concepts before you try to tackle something like face recognition or image processing.

Categories

Resources