OpenCV waitKey in python doesn't work on mac - python

I'm writing code to face recognition in python and i'm using open cv on mac (PyCharm).
I don't understand why:
if cv2.waitKey(1) & 0xFF == ord('q'):
break
doesn't work on mac, but on windows this code work.
In particular q doesn't trigger the if.
I try to change with:
k = cv2.waitKey(0)
if k == 27:
break
Below write my code
def run(self):
video_capture = cv2.VideoCapture(0)
try:
while self.active:
# Grab a single frame of video
ret, frame = video_capture.read()
# Convert the image from BGR color (which OpenCV uses) to RGB color (which face_recognition uses)
rgb_frame = frame[:, :, ::-1]
# Find all the faces and face enqcodings in the frame of video
face_locations = face_recognition.face_locations(rgb_frame)
face_encodings = face_recognition.face_encodings(rgb_frame, face_locations)
# Loop through each face in this frame of video
for (top, right, bottom, left), face_encoding in zip(face_locations, face_encodings):
# See if the face is a match for the known face(s)
matches = face_recognition.compare_faces(self.known_face_encodings, face_encoding)
name = "Unknown"
# If a match was found in known_face_encodings, just use the first one.
if True in matches:
first_match_index = matches.index(True)
name = self.known_face_names[first_match_index]
# Draw a box around the face
cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2)
# Draw a label with a name below the face
cv2.rectangle(frame, (left, bottom - 35), (right, bottom), (0, 0, 255), cv2.FILLED)
font = cv2.FONT_HERSHEY_DUPLEX
cv2.putText(frame, name, (left + 6, bottom - 6), font, 1.0, (255, 255, 255), 1)
if (name != "Unknown"):
self.reco.emit(name)
self.deactivate()
video_capture.release()
cv2.destroyAllWindows()
else:
self.unreco.emit()
self.deactivate()
video_capture.release()
cv2.destroyAllWindows()
# Display the resulting image
# cv2.imshow('Video', frame)
# Hit 'q' on the keyboard to quit!
if cv2.waitKey(1) & 0xFF == ord('q'):
break
except:
print("error while recognize")

Related

How do I add an image overlay to my live video using cv2?

This is my code, I've looked at some tutorials but can't find what I'm looking for
I want to overlay the Frame.png image on my webcam. I tried to add the image directly but it didn't work either. If possible, Is there a way to add an image, not to overlay but to keep the image at a certain coordinate in the live webcam window
import cv2
import numpy as np
def detect_and_save():
alpha = 0.2
beta = 1-alpha
cap = cv2.VideoCapture(0)
sciframe = cv2.imread('Frame.png')
classifier = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
while True:
ret ,frame = cap.read()
overlay = frame.copy()
output = frame.copy()
gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
faces = classifier.detectMultiScale(gray,1.5,5)
cv2.putText(output, "HUD Test",(175, 50), cv2.FONT_HERSHEY_SIMPLEX, 2, (255, 50, 50), 3)
cv2
for face in faces:
x,y,w,h = face
cv2.rectangle(overlay,(x,y),(x+w,y+h),(255,200,0),-1)
cv2.rectangle(overlay,(x,y),(x+w,y+h),(255,0,0),1)
cv2.rectangle(overlay,(x,y-20),(x+w,y),(25,20,0),-1)
cv2.addWeighted(overlay,alpha,output,beta,0,output)
cv2.putText(output,"Human",(x+10,y-10),cv2.FONT_HERSHEY_SIMPLEX,
0.35, (0, 0, 255), 1)
if not ret:
continue
cv2.imshow("HUD",output)
key = cv2.waitKey(1)
if key == ord('q'):
break
elif key == ord('s'):
cv2.imwrite('./images/CID_{}.png'.format(time.strftime('%d%m%y_%H_%M_%S')),output)
cap.release()
cv2.destroyAllWindows()
if __name__ == "__main__":
import time
detect_and_save()
You can directly add one image on top of another one at any coordinate easily in opencv.
cap = cv2.VideoCapture(0)
im_height = 50 #define your top image size here
im_width = 50
im = cv2.resize(cv2.imread("Frame.png"), (im_width, im_height))
while (True):
ret, frame = cap.read()
frame[0:im_width, 0:im_height] = im #for top-left corner, 0:50 and 0:50 for my image; select your region here like 200:250
cv2.imshow("live camera", frame)
if cv2.waitKey(1) == ord("q"):
break
cap.release()
cv2.destroyAllWindows()

AttributeError: 'cv2.VideoCapture' object has no attribute 'get_frame'

Traceback (most recent call last):
File "c:\Users\user\Desktop\face_recognition\face_recog.py", line 103, in <module>
frame = face_recog.get_frame()
File "c:\Users\user\Desktop\face_recognition\face_recog.py", line 41, in get_frame
frame = self.capture.get_frame(self)
AttributeError: 'cv2.VideoCapture' object has no attribute 'get_frame'def get_frame(self):
# Grab a single frame of video
frame = self.capture.get_frame()
# Resize frame of video to 1/4 size for faster face recognition processing
small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25)
# Convert the image from BGR color (which OpenCV uses) to RGB color (which face_recognition uses)
rgb_small_frame = small_frame[:, :, ::-1]
# Only process every other frame of video to save time
if self.process_this_frame:
# Find all the faces and face encodings in the current frame of video
self.face_locations = face_recognition.face_locations(rgb_small_frame)
self.face_encodings = face_recognition.face_encodings(rgb_small_frame, self.face_locations)
self.face_names = []
for face_encoding in self.face_encodings:
# See if the face is a match for the known face(s)
distances = face_recognition.face_distance(self.known_face_encodings, face_encoding)
min_value = min(distances)
# tolerance: How much distance between faces to consider it a match. Lower is more strict.
# 0.6 is typical best performance.
name = "Unknown"
if min_value < 0.6:
index = np.argmin(distances)
name = self.known_face_names[index]
self.face_names.append(name)
self.process_this_frame = not self.process_this_frame
# Display the results
for (top, right, bottom, left), name in zip(self.face_locations, self.face_names):
# Scale back up face locations since the frame we detected in was scaled to 1/4 size
top *= 4
right *= 4
bottom *= 4
left *= 4
# Draw a box around the face
cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2)
# Draw a label with a name below the face
cv2.rectangle(frame, (left, bottom - 35), (right, bottom), (0, 0, 255), cv2.FILLED)
font = cv2.FONT_HERSHEY_DUPLEX
cv2.putText(frame, name, (left + 6, bottom - 6), font, 1.0, (255, 255, 255), 1)
return frame
def get_jpg_bytes(self):
frame = self.get_frame()
# We are using Motion JPEG, but OpenCV defaults to capture raw images,
# so we must encode it into JPEG in order to correctly display the
# video stream.
ret, jpg = cv2.imencode('.jpg', frame)
return jpg.tobytes()
# show the frame
cv2.imshow("Frame", frame)
key = cv2.waitKey(1) & 0xFF
# if the `q` key was pressed, break from the loop
if key == ord("q"):
break
# do a bit of cleanup
cv2.destroyAllWindows()
print('finish')

cv2.waitKey() works for 'q' key but does not works for any other keys

I have this code which is actually a part of one of my projects for Sign Language Recognition.
So I am taking user's hand image in each frame and passing it to model and showing the prediction for the sign on the screen and I have added a feature where if user presses 's' key then prediction will get appended to string sen and similarily I will show that string sen on screen .
But after running the code, for key 'q' it closes the window without any problems but when I press key 's' nothing happens.
Instead of key 's' , I tried the same with other keys but still nothing happens.
Here's the code :
import cv2
import numpy as np
from model import predict
def capture():
sen = ''
cap = cv2.VideoCapture(0)
while True:
ret, frame = cap.read()
frame = cv2.flip(frame, 1)
frame_height = 480
frame_width = 640
# a standard frame window of size 640*480
frame = cv2.resize(frame, (frame_width, frame_height))
# drawing a rectangle in a frame which will capture hand
cv2.rectangle(frame, (300, 100), (500, 300), (0, 300, 0), 2)
# rectangle of background of text s
cv2.rectangle(frame, (0, 0), (300, 50), (0, 0, 0), -1)
frame = cv2.putText(frame, 'press q to exit', (30, 30), cv2.FONT_HERSHEY_SIMPLEX,
1, (255, 255, 255), 1, cv2.LINE_AA)
# region of interest i.e rectangle which we drawn earlier
roi = frame[100:300, 300:500]
roi = cv2.cvtColor(roi, cv2.COLOR_BGR2GRAY)
roi = cv2.GaussianBlur(roi, (5, 5), 0)
# applying edge detection on roi
roi_edges = cv2.Canny(roi, 100, 200)
# cv2.imshow('Edges', roi_edges)
# to make roid_edges of shape (200,200,1) , specifying color channel which is required for model
img = np.expand_dims(roi_edges, axis=2)
cv2.imshow('input for model', img)
frame = cv2.putText(frame, predict(img), (300, 400), cv2.FONT_HERSHEY_SIMPLEX,
1, (255, 255, 255), 1, cv2.LINE_AA)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
elif cv2.waitKey(1) & 0xFF == ord('s'):
sen += predict(img)
print(sen)
# printing whole sentence i.e. sen
frame = cv2.putText(frame, sen , (300, 500),
cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 1, cv2.LINE_AA)
cv2.imshow('Smile', frame)
cv2.destroyAllWindows()
cap.release()
capture()
So what could be the problem here?
The problem is you called the cv2.waitKey(1) method multiple times, in this case you should use variable for cv2.waitKey(1) because the waiting is that both function calls read the keyboard buffer so the second branch executed only if the software receives the s key right after the evaulation of the first branch (q). Here is the sample code:
keys = cv2.waitKey(1) & 0xFF
if keys == ord('q'):
break
elif keys == ord('s'):
print('s is pressed')

Real-time face_recognition can't indentify the right face

I want to build an attendance system by face_recognition with real-time. Therefore, I created a folder that have 20 pictures of some famous people to test the code. However, the result is bad, since the program can't really identify the right face. What should I do to improve the code such that I can identify the right faces?
I hope to get some advice from you. Thanks a lot.
# -*- coding: utf-8 -*-
#I have installed these package successfully
import face_recognition
import cv2
import datetime
import glob2 as gb
import numpy as np
video_capture = cv2.VideoCapture(0)
#There are 20 pictures in my local folder
img_path=gb.glob(r'F:\liuzhenya\photo\\*.jpg')
#Store the name of picture
known_face_names=[]
#Store the matrix from these pictures
known_face_encodings=[]
for i in img_path:
picture_name=i.replace('F:\liuzhenya\photo\\','')
picture_newname=picture_name.replace('.jpg','')
obama_img = face_recognition.load_image_file(i)
obama_face_encoding = face_recognition.face_encodings(obama_img)[0]
known_face_names.append(picture_newname)
known_face_encodings.append(obama_face_encoding)
face_locations = []
face_encodings = []
face_names = []
process_this_frame = True
while True:
ret, frame = video_capture.read()
small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25)
rgb_small_frame=small_frame[:,:,::-1]
if process_this_frame:
face_locations = face_recognition.face_locations(rgb_small_frame)
face_encodings = face_recognition.face_encodings(rgb_small_frame, face_locations)
face_names = []
for face_encoding in face_encodings:
match = face_recognition.compare_faces(known_face_encodings, face_encoding)
if True in match:
match_index=match.index(True)
name = "match"
#To print name and time
cute_clock = datetime.datetime.now()
print (known_face_names[match_index]+':'+str(cute_clock))
else:
name = "unknown"
face_names.append(name)
process_this_frame = not process_this_frame
for (top, right, bottom, left), name in zip(face_locations, face_names):
top *= 4
right *= 4
bottom *= 4
left *= 4
cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2)
cv2.rectangle(frame, (left, bottom - 35), (right, bottom), (0, 0, 255), 2)
font = cv2.FONT_HERSHEY_DUPLEX
cv2.putText(frame, name, (left+6, bottom-6), font, 1.0, (255, 255, 255), 1)
cv2.imshow('Video', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
video_capture.release()
cv2.destroyAllWindows()

OpenCV 3 Python 3 calibrate camera for radial distortion gives error

I have a problem while running a function in Python 3 with OpenCV 3, I want to calibrate a video with a calibration data .npz and it results in an error message on remapping matrix line.
The calibrated video output is great but it came with an error message, which prevents any further execution. How could I make the script ignore the error and continue?
Any answer will be greatly appreciated.
This is the code:
import cv2, time, sys
import numpy as np
import matplotlib.pyplot as plt
filename = 'vtest3.mp4'
filename_2 = 'vtest3_undistort.mp4'
crop = 0.5
#FIRST FUNCTION (UNDISTORTION)
def undistortion(filename):
print('Loading data files')
npz_calib_file = np.load('calibration_data.npz')
distCoeff = npz_calib_file['distCoeff']
intrinsic_matrix = npz_calib_file['intrinsic_matrix']
npz_calib_file.close()
print('Finished loading files')
print(' ')
print('Starting to undistort the video....')
# Opens the video import and sets parameters
video = cv2.VideoCapture(filename)
# Checks to see if a the video was properly imported
status = video.isOpened()
if status == True:
FPS = video.get(cv2.CAP_PROP_FPS)
width = video.get(cv2.CAP_PROP_FRAME_WIDTH)
height = video.get(cv2.CAP_PROP_FRAME_HEIGHT)
size = (int(width), int(height))
total_frames = video.get(cv2.CAP_PROP_FRAME_COUNT)
frame_lapse = (1 / FPS) * 1000
# Initializes the export video file
codec = cv2.VideoWriter_fourcc(*'DIVX')
video_out = cv2.VideoWriter(str(filename[:-4]) + '_undistort.mp4', codec, FPS, size, 1)
# Initializes the frame counter
current_frame = 0
newMat, ROI = cv2.getOptimalNewCameraMatrix(intrinsic_matrix, distCoeff, size, alpha=crop,
centerPrincipalPoint=1)
mapx, mapy = cv2.initUndistortRectifyMap(intrinsic_matrix, distCoeff, None, newMat, size, m1type=cv2.CV_32FC1)
while current_frame < total_frames:
success, image = video.read()
current_frame = video.get(cv2.CAP_PROP_POS_FRAMES)
dst = cv2.remap(image, mapx, mapy, cv2.INTER_LINEAR)
# dst = cv2.undistort(image, intrinsic_matrix, distCoeff, None)
video_out.write(dst)
video.release()
video_out.release()
else:
print('Error: Could not load video')
sys.exit()
#SECOND FUNCTION
def hauptprogramm(filename_2):
# Create an empty List for x- and y-Positions that will be filled in for-loop
# with the .append function
xposition = [] # Empty list for x-Positions
yposition = [] # Empty list for y-Positions
# Open the Video with die VideoCapture function
# Name the video that is opened cap
cap = cv2.VideoCapture(filename_2)
# set the framenumber to the last frame just to take a picture
cap.set(1, cap.get(cv2.CAP_PROP_FRAME_COUNT)); # Where frame_no is the frame you want
ret, frame = cap.read() # Read the frame
cv2.imwrite('kurve.jpg', frame)
# set the framenumber to 1, which is the first frame of the video
# from here we begin to analyse the video
cap.set(1, 1);
# cv2.imshow('window_name', frame) # show frame on window
# pos_frame = cap.get(cv2.CAP_PROP_POS_FRAMES)
# start an infinite while loop by setting while True
# the loop will go on until we break it
while True:
# read a frame of the video and name it frame0
# read the next frame of the video and name it frame1
# set both frames retangle by writing ret,frame
ret, frame0 = cap.read()
ret, frame1 = cap.read()
ret, frame2 = cap.read()
# the program will lateron compare every pixel from frame0 to frame1 and
# locate the areas where many pixels have changed
# we only are interested in the area where the missile is flying
# the moving of the catapult itself for exemple would cause trouble
# so we paint lines over the areas we are not interested in these lines
# will be painted every loop over frame1
cv2.line(frame1, (0, 0), (0, 511), (255, 0, 0), 200)
cv2.line(frame1, (0, 500), (1000, 500), (255, 0, 0), 350)
cv2.line(frame1, (0, 350), (150, 350), (255, 0, 0), 400)
# the same lines will be painted over frame2
cv2.line(frame2, (0, 0), (0, 511), (255, 0, 0), 200)
cv2.line(frame2, (0, 500), (1000, 500), (255, 0, 0), 350)
cv2.line(frame2, (0, 350), (150, 350), (255, 0, 0), 400)
# for the function that will compare frame1 and frame2 both frames have
# to be in black and white
# the next function will be used to convert frame1 and frame2 to black and
# white and will name them gray1 and gray2
gray1 = cv2.cvtColor(frame1, cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(frame2, cv2.COLOR_BGR2GRAY)
# the absdiff function will compare the gray1 and gray2 images and returns
# an image named diffimage
diffimage = cv2.absdiff(gray1, gray2)
# the result of that function returns a black and white image
# to get clear results the image will be converted to a binary image
# the new image called diffimage only has pixels that are white or black
ret, threshold = cv2.threshold(diffimage, 30, 255, cv2.THRESH_BINARY)
# to reduce the image noise we will make the threshold image blurry by using
# the blur function
threshold = cv2.blur(threshold, (25, 25))
# when converting the blurry image into a threshold image for a secound
# time the small noisy pixels of the image will be gone and the areas where
# a lot of pixels have changed in will be clearer and bigger
ret, threshold = cv2.threshold(threshold, 30, 255, cv2.THRESH_BINARY)
# ========================find the white areas ==================
# now we want to find the white areas in the picture that show
# our flying missile
# !exakte funktion noch nicht verstanden
image, contours, hierarchy = cv2.findContours(threshold.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# !exakte funktion noch nicht verstanden
for cnt in contours:
area = cv2.contourArea(cnt)
# to reduce the chance of tracking background noise that might be left
# even after reducing it with the blur and threshold functions
# we only track the position of if the white area is bigger than x=10
if area > 10:
# we are looking for the bounding rectangle that is around our area
# x and y equal the pixelposition of the top right point of the rectangle
# w and h equal the width and height of the rectangle
x, y, w, h = cv2.boundingRect(cnt)
# we are interested in the center of the rectangle so we add w/2 to x
# and h/2 to y
# because the x- and y-positions have to be integer we round the values
# and declare them as such
xpos = int(round(x + w / 2))
ypos = int(round(y + h / 2))
# to see if everything works fine wile running the program the positions
# can be printed in the console by removing the hashtag
# print("x= ", xpos)
# print("y= ", ypos)
# now the list of x- and y-positions will be extended by every loop
# with these list of positions we can work later on for the
# post-processing of the curve the object is flying
xposition.append(xpos)
yposition.append(ypos)
# not necessary to post-process but a nice visualisation and checking
# if everything works as it is supposed to
# a small circle will be painted on the x- and y-position
# therefore we take the "empty" frame0 that does not have the colored
# lines painted into
cv2.circle(frame0, (xpos, ypos), 5, (0, 255, 0), -1)
# a rectangle will be surrounding the center just to keep track of the
# moving object
cv2.rectangle(frame0, (x, y), (x + w, y + h), (255, 0, 0), 3)
# write the x- and y- position in each frame
cv2.putText(frame0, 'x = ' + str(xpos), (xpos - 20, ypos - 20), cv2.FONT_HERSHEY_SIMPLEX, 0.5,
(0, 0, 255), 2, cv2.LINE_AA)
cv2.putText(frame0, 'y = ' + str(ypos), (xpos - 20, ypos + 20), cv2.FONT_HERSHEY_SIMPLEX, 0.5,
(0, 0, 255), 2, cv2.LINE_AA)
# x-Positionen in Konsole mitschreiben
# print(xposition)
# ========================= Open Windows ====================
# the imshow functions open a window and show the selected frame each
# while loop (play the video)
# by removing the hashtag the selected video will open when running the
# program
# 1. Show the original frames and paint the previous visulisation
cv2.imshow('Orginal mit Verfolgung', frame0)
# 2. Show the threshold frames
cv2.imshow('threshold frames', threshold)
# 3. Show the painted lines in frame1 and frame2 (same parameters)
cv2.imshow('mit Balken', frame1)
# if we press the ESC button the loop will break
if cv2.waitKey(10) == 27: # mit ESC verlassen
break
# if we reach the total number of frames the loop will break
if cap.get(cv2.CAP_PROP_POS_FRAMES) == cap.get(cv2.CAP_PROP_FRAME_COUNT):
# If the number of captured frames is equal to the total number of frames,
# we stop
break
# after we break the loop we release the cap and force all windows to close
cap.release()
cv2.destroyAllWindows()
# does not make sense, just a way to fix a bug in opencv
cv2.waitKey(1)
cv2.waitKey(1)
cv2.waitKey(1)
cv2.waitKey(1)
cv2.waitKey(1)
cv2.waitKey(1)
cv2.waitKey(1)
cv2.waitKey(1)
cv2.waitKey(1)
cv2.waitKey(1)
cv2.waitKey(1)
cv2.waitKey(100)
# =================== Spielerei ====================
# cap2 = cv2.VideoCapture("vtest3.m4v")
# while True:
# cap2.set(1,cv2.CAP_PROP_FRAME_COUNT)
# ret, frame = cap.read()
# cv2.imshow('window_name', frame)
#
# if cv2.waitKey(10) == 27: # mit ESC verlassen
# break
#
# cap.release()
# cv2.destroyAllWindows()
# cv2.waitKey(1)
# cv2.waitKey(1)
# cv2.waitKey(1)
# cv2.waitKey(1)
# cv2.waitKey(1)
# cv2.waitKey(1)
# cv2.waitKey(1)
# ========== Plot öffnen und speichern ===================
plt.plot(np.asarray(xposition), np.asarray(yposition), 'g^')
plt.axis('equal')
plt.savefig('positionen.png')
# ============== Image lesen und auswerten ===============
image = cv2.imread('kurve.jpg')
for i in range(0, len(xposition)):
cv2.circle(image, (xposition[i], yposition[i]), 5, (0, 255, 0), -1)
cv2.imwrite('positionen2.png', image)
undistortion(filename)
hauptprogramm(filename_2)

Categories

Resources