I'm creating a function (in Python) that expects/receives a single image of multiple human faces in it, and returns multiple smaller images (one image per human face). I am able to do a cv2.imshow inside the function and see the expected smaller images, but when I attempt a cv2.imshow from outside the function, it does not work (unable to see the smaller image, and get a TypeError instead). Would appreciate some guidance.
def stills(user_image):
#sub_frames = []
fqp_image_src = (user_image)
raw_pic = cv2.imread(fqp_image_src)
mpic = cv2.resize(raw_pic,(0,0), fx=0.30, fy=0.30)
mpic_rgb = cv2.cvtColor(mpic, cv2.COLOR_BGR2RGB)
face_boxes = haar_cascade_face.detectMultiScale(mpic_rgb, scaleFactor = 1.2, minNeighbors = 5)
count = int(len(face_boxes))
for i in range(count):
face_box = face_boxes[i]
final = cv2.rectangle(mpic, (face_box[0], face_box[1]), ((face_box[0]+face_box[2]),(face_box[1]+face_box[3])), (0,255,0),2)
sub_frame = final[face_box[1]:(face_box[1]+face_box[3]), face_box[0]:(face_box[0]+face_box[2])]
#sub_frames.append(sub_frame)
cv2.imshow('frame', sub_frame) # this works
cv2.waitKey()
return (sub_frame, final)
# calling the function
something = stills("abc.jpg")
cv2.imshow('frame',something) # this does not work
cv2.waitKey()
TypeError: Expected cv::UMat for argument 'mat'
This will do what you expected, just whit some simplification and with full file paths
.
One of the key erros was give detectMultiScale a colored image, the imput shuld have 1 dimension, with brigtness (gray scales).
In order to display a colored image with the faces in a box a copy of the image is needed to convert into gar scales and detect, giving coordenates to draw in the colored image.
import cv2
import os
# Take as a global the dir in witch is this file
PATH = os.path.dirname(os.path.abspath(__file__))
haar_cascade_face = cv2.CascadeClassifier(os.path.join(PATH, 'haarcascade_frontalface_alt.xml'))
def stills(user_image):
image = os.path.join(PATH, user_image)
image = cv2.imread(image)
image = cv2.resize(image, (0, 0), fx=0.30, fy=0.30)
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
face_boxes = haar_cascade_face.detectMultiScale(gray_image, scaleFactor=1.073, minNeighbors=8)
final = image # make the funtion alwais give a image
sub_frames = []
# Check if there are faces
if len(face_boxes) > 0:
for x, y, w, h in face_boxes:
final = cv2.rectangle(image, (x, y), (x+w, y+h), (0, 255, 0), 2)
sub_frame = image[y:y+h, x:x+w]
sub_frames.append([x, y, x+w, y+h])
cv2.imshow('sub_frame', sub_frame)
# cv2.waitKey() # No need to wait the user
else:
print('No faces found')
return (sub_frames, final)
if __name__ == '__main__':
fragments, final = stills("abc.jpg")
cv2.imshow('frame', final)
cv2.waitKey()
Related
I made a License Plate Detect system and i have a problem. I have 2 question.
Q1. I want to print the plate in this section. How can i do?
def fix_dimension(img):
new_img = np.zeros((28,28,3))
for i in range(3):
new_img[:,:,i] = img
return new_img
def show_results():
dict = {}
characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
for i,c in enumerate(characters):
dict[i] = c
output = []
for i,ch in enumerate(char): #iterating over the characters
img_ = cv2.resize(ch, (28,28), interpolation=cv2.INTER_AREA)
img = fix_dimension(img_)
img = img.reshape(1,28,28,3) #preparing image for the model
classes_x=np.argmax(model.predict(img), axis=-1)#predicting the class
character = dict[output] #
output.append(character) #storing the result in a list
plate_number = ''.join(output)
return plate_number
print(show_results())
Output: unhashable type: 'list'
Q2: When I convert the output to string, I get this error in the output of the code below
plate_number = show_results()
output_img, plate = detect_plate(img, plate_number)
display(output_img, 'detected license plate number in the input image')
Output: error: OpenCV(4.5.5) D:\a\opencv-python\opencv-python\opencv\modules\objdetect\src\cascadedetect.cpp:1389: error: (-215:Assertion failed) scaleFactor > 1 && _image.depth() == CV_8U in function 'cv::CascadeClassifierImpl::detectMultiScale'
plate_cascade = cv2.CascadeClassifier('input/indian_license_plate.xml')
def detect_plate(img, text=''): # the function detects and perfors blurring on the number plate.
plate_img = img.copy()
roi = img.copy()
plate_rect = plate_cascade.detectMultiScale(plate_img, scaleFactor = 1.2, minNeighbors = 7) # detects numberplates and returns the coordinates and dimensions of detected license plate's contours.
for (x,y,w,h) in plate_rect:
roi_ = roi[y:y+h, x:x+w, :] # extracting the Region of Interest of license plate for blurring.
plate = roi[y:y+h, x:x+w, :]
cv2.rectangle(plate_img, (x+2,y), (x+w-3, y+h-5), (51,181,155), 3) # finally representing the detected contours by drawing rectangles around the edges.
if text!='':
plate_img = cv2.putText(plate_img, text, (x-w//2,y-h//2),
cv2.FONT_HERSHEY_COMPLEX_SMALL , 0.5, (51,181,155), 1, cv2.LINE_AA)
return plate_img, plate # returning the processed image.
code:
import face_recognition as fr
import os
import cv2
import face_recognition
import numpy as np
from time import sleep
def get_encoded_faces():
encoded = {}
for dirpath, dnames, fname in os.walk("./faces"):
for f in fname:
if f.endswith(".jpg") or f.endswith(".png"):
face = fr.load_image_file("faces/" + f)
encoding = fr.face_encodings(face)[0]
encoded[f.split(".")[0]] = encoding
return encoded, fname
def unknown_image_encoded(img):
face = fr.load_image_file("faces/" + img)
encoding = fr.face_encodings(face)[0]
return encoding
def classify_face(im):
faces, fname = get_encoded_faces()
faces_encoded = list(faces.values())
known_face_names = list(faces.keys())
img = cv2.imread(im, 1)
face_locations = face_recognition.face_locations(img)
unknown_face_encodings = face_recognition.face_encodings(img, face_locations)
face_names = []
for face_encoding in unknown_face_encodings:
matches = face_recognition.compare_faces(faces_encoded, face_encoding)
name = "Unknown"
face_distances = face_recognition.face_distance(faces_encoded, face_encoding)
best_match_index = np.argmin(face_distances)
if matches[best_match_index]:
name = known_face_names[best_match_index]
face_names.append(name)
for (top, right, bottom, left), name in zip(face_locations, face_names):
cv2.rectangle(img, (left-20, top-20), (right+20, bottom+20), (255, 0, 0), 2)
cv2.rectangle(img, (left-20, bottom -15), (right+20, bottom+20), (255, 0, 0), cv2.FILLED)
font = cv2.FONT_HERSHEY_DUPLEX
cv2.putText(img, name, (left -20, bottom + 15), font, 1.0, (255, 255, 255), 2)
return face_names, fname
cap = cv2.VideoCapture(0)
while True:
ret, image = cap.read()
recog, fname = classify_face(image)
print(recog)
cv2.imshow(fname, image)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
video.release()
cv2.destroyAllWindows()
Error:
Traceback (most recent call last):
File "face.py", line 70, in <module>
recog, fname = classify_face(image)
File "face.py", line 37, in classify_face
img = cv2.imread(im, 1)
SystemError: <built-in function imread> returned NULL without setting an error
[ WARN:0] global C:\Users\appveyor\AppData\Local\Temp\1\pip-req-build-wbmte9m7\opencv\modules\videoio\src\cap_msmf.cpp (435) `anonymous-namespace'::SourceReaderCB::~SourceReaderCB terminating async callback
The code works properly while using an image but now when I tried using it with video/real-time its throwing this error
I guess it requires the path instead of the image that is passed on to it, is there any other work around
I am trying to recognize faces in real time and the major issue with it was detecting unknown faces so when I started coding for real time I got this error.
The code and the error message don't agree. Are you running an older version of the code?
Error message:
File "face.py", line 37, in classify_face
img = cv2.imread(im, 1)
Code:
img = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
For debugging it may be helpful to display the received frame from the camera with code like the following:
ret, image = cap.read()
grey = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cv2.imshow('frame', grey)
cv2.waitKey()
cv2.imread(im, 1) requires im to be the filename (datatype: string) of the image that you want to read.
Using cap = cv2.VideoCapture(0), you don't need to read images from files anymore, since the image that you want to classify is returned as an array from cap.read().
To fix your code for using cv2.VideoCapture, remove img = cv2.imread(im, 1) from your classify_face method and change the method definition to
def classify_face(img):
instead of
def classify_face(im):
Note, that the 0 option of cv2.VideoCapture refers to reading the live video stream from a camera with index 0.
I have the picture below used in Tesseract OCR:
My code to process the picture is:
# HOCR
with image[450:6200, 840:3550] as cropped:
imgPage = wi(image = cropped)
imageBlob = imgPage.make_blob('png')
horas = gerarHocr(imageBlob)
def gerarHocr(imageBlob):
image = Image.open(io.BytesIO(imageBlob))
markup = pytesseract.image_to_pdf_or_hocr(image, lang='por', extension='hocr', config='--psm 6')
soup = BeautifulSoup(markup, features='html.parser')
spans = soup.find_all('span', {'class' : 'ocrx_word'})
listHoras = []
...
return listHoras
Although my OCR is getting sometimes confused and duplicating 8 with 3 and returning 07:44/14:183 instead of 07:44/14:13 for example.
I think if I remove the grey lines using Wand I improve the confidence of the OCR.
How do I do that, please?
Thank you,
If the system is using ImageMagick-6, you can call Image.threshold(), but might need to remove the transparency first.
with Image(filename='PWILE.png') as img:
img.background_color = 'WHITE'
img.alpha_channel = False
img.threshold(threshold=0.5)
img.save(filename='output_threshold.png')
If you're using ImageMagick-7 (anything above version 7.0.8-41), then Image.auto_threshold() will work.
with Image(filename='support/PWILE.png') as img:
img.auto_threshold(method='otsu')
I would use cv2 and/or numpy.array
to convert light gray colors to white
img[ img > 128 ] = 255
to convert dark gray colors to black
img[ img < 128 ] = 0
import cv2
folder = '/home/user/images/'
# read it
img = cv2.imread(folder + 'old_img.png')
# convert ot grayscale
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# reduce colors
img[ img > 128 ] = 255
img[ img < 128 ] = 0
# save it
cv2.imwrite(folder + 'new_img.png', img)
# display result
#cv2.imshow('window', img)
#cv2.waitKey(0) # press any key in window to close it
#cv2.destroyAllWindows()
Result
Ok, so I've been having a problem with some tracking code(I'm not too skilled, please bear this in mind). It is meant to track objects(Juggling balls) of one colour and output a .csv data file.
import cv2
import numpy as np
#h,s,v range of the object to be tracked
h,s,v,h1,s1,v1 = 31,91,0,74,255,255#GREEN
#h,s,v,h1,s1,v1 = 0, 161, 52, 26 ,255, 255 #Orange
#h,s,v,h1,s1,v1 = 90, 37, 0, 143, 180, 255 #Blue
threshold_value = 0
output_path = ('C:\\Python27')
cap = cv2.VideoCapture('Users\Tyson\Desktop\MillsMess.mp4')
#takes an image, and a lower and upper bound
#returns only the parts of the image in bounds
def only_color(frame, (b,r,g,b1,r1,g1)):
# Convert BGR to HSV
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
# define range of blue color in HSV
lower = np.array([b,r,g])
upper = np.array([b1,r1,g1])
# Threshold the HSV image to get only blue colors
mask = cv2.inRange(hsv, lower, upper)
# Bitwise-AND mask and original image
res = cv2.bitwise_and(frame,frame, mask= mask)
return res, mask
#finds the largest contour in a list of contours
#returns a single contour
def largest_contour(contours):
c = max(contours, key=cv2.contourArea)
return c[0]
#takes an image and the threshold value returns the contours
def get_contours(im, threshold_value):
imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
_ ,thresh = cv2.threshold(imgray,threshold_value,255,0)
_, contours, _ = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
return contours
#finds the center of a contour
#takes a single contour
#returns (x,y) position of the contour
def contour_center(c):
M = cv2.moments(c)
try: center = int(M['m10']/M['m00']), int(M['m01']/M['m00'])
except: center = 0,0
return center
frame_number = 0
positions = []
for i in range(1000000): positions.append((0,0))
#main loop of the program
while True:
#read image from the video
_, img = cap.read()
try: l = img.shape
except: break
#extract only the flesh tones
img, mask = only_color(img, (h,s,v,h1,s1,v1))
#find the contours in the image
contours = get_contours(img, threshold_value)
#if there are contours found in the image:
if len(contours)>0:
try:
#sort the contours by area
c = max(contours, key=cv2.contourArea)
img = cv2.drawContours(img, c ,-1, (0,0,255), 14)
positions[frame_number] = contour_center(c)
except: pass
frame_number += 1
#show the image and wait
#cv2.imshow('img', img)
cv2.imshow('img', cv2.resize(img, (480,700)))
k=cv2.waitKey(1)
if k==27: break
#release the video to avoid memory leaks, and close the window
cap.release()
cv2.destroyAllWindows()
#remove unused parts of the list
positions = positions[:frame_number]
print 'finished tracking'
#write data
import csv
with open(output_path, 'w') as csvfile:
fieldnames = ['x_position', 'y_position']
writer = csv.DictWriter(csvfile, fieldnames = fieldnames)
writer.writeheader()
for position in positions:
x, y = position[0], position[1]
writer.writerow({'x_position': x, 'y_position': y})
print 'finished writing data'
print output_path
And I get this Error
finished tracking
Traceback (most recent call last):
File "C:\Users\Tyson\Desktop\Code\Tracker.py", line 90, in <module>
with open(output_path, 'w') as csvfile:
IOError: [Errno 13] Permission denied: 'C:\\Python27'
I have tried fixing it, but nothing seems to work. Is there a native folder I could save it to that is writable? Or how can I give permission?
Thanks in advance!
The line output_path = ('C:\\Python27') later causes open(output_path, 'w') to fail. Set output_path to something else.
I wrote this code using other code that I found online. I don't get any errors, however I can't get the disparity map to show up using imshow. I saved the image and it is just black so I'm not doing something properly. Could someone please look through my code and see what's wrong with it? I may not be doing the stereocalibration properly but I am not sure.
Thank you!
import numpy as np
import cv2
import glob
import os
from matplotlib import pyplot as plt
print 'program starts'
from matplotlib import pyplot as plt
#termination criteria
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 20, 0.001)
#-------------------------------------------------------------------------
#INITIALIZATION VARIABLES
#prepare object points
objp = np.zeros((6*9,3), np.float32)
objp[:,:2] = np.mgrid[0:9,0:6].T.reshape(-1,2)
#Arrays to store object points and image points from all the images.
objpoints = [] #3D points in real world space
imgpointsL = [] #2D points in image plane.
imgpointsR = []
#-------------------------------------------------------------------------
os.chdir('/home/pi/Desktop/LeftImg')
images = sorted(glob.glob('*.png'))
#print images
for fname in images:
img = cv2.imread(fname)
grayL = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# find chess board corners
ret, cornersL = cv2.findChessboardCorners(grayL, (9,6))
# if found, add object points, image points (after refining them)
if ret == True:
objpoints.append(objp)
cv2.cornerSubPix(grayL, cornersL, (11,11),(-1,-1), criteria)
imgpointsL.append(cornersL)
print len(objpoints)
os.chdir('/home/pi/Desktop/RightImg')
images = sorted(glob.glob('*.png'))
#print images
for fname in images:
img = cv2.imread(fname)
grayR = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# find chess board corners
ret, cornersR = cv2.findChessboardCorners(grayR, (9,6))
# if found, add object points, image points (after refining them)
if ret == True:
prevobjp = objp
objpoints.append(objp)
cv2.cornerSubPix(grayR, cornersR,(11,11),(-1,-1), criteria)
imgpointsR.append(cornersR)
c[prevobjp & objp]
if c.all():
print 'True'
else:
print 'False'
#print len(objpointsR)
#Draw and display corners
#img = cv2.drawChessboardCorners(img, (9,6), cornersR,ret)
# cv2.drawChessboardCorners(img, (9,6), cornersR,ret)
# plt.imshow(img)
# plt.show()
# print type(img)
# cv2.imshow('img', img)
# cv2.waitKey(500)
print 'start'
cameraMatrix1 = cv2.cv.CreateMat(3,3, cv2.CV_64FC1)
cameraMatrix2 = cv2.cv.CreateMat(3,3, cv2.CV_64FC1)
retval, cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2, R, T, E, F = cv2.stereoCalibrate(objpoints, imgpointsL, imgpointsR, (384,288))
print cameraMatrix1, cameraMatrix2
print 'over'
R1= np.zeros(shape=(3,3))
R2= np.zeros(shape=(3,3))
P1= np.zeros(shape=(3,4))
P2= np.zeros(shape=(3,4))
Q= np.zeros(shape=(4,4))
map1x=[]
map1y=[]
map2x=[]
map2y=[]
#imgU1=[]
#imgU2=[]
#print cameraMatrix1
#print cameraMatrix1
os.chdir('/home/pi/Desktop')
imgL=cv2.imread('calLeft1.png')
imgR=cv2.imread('calRight1.png')
imgL = cv2.cvtColor(imgL, cv2.COLOR_BGR2GRAY)
imgR = cv2.cvtColor(imgR, cv2.COLOR_BGR2GRAY)
cv2.stereoRectify(cameraMatrix1,distCoeffs1,cameraMatrix2,distCoeffs2,(384,288),R,T,R1,R2,P1,P2,Q,flags=cv2.cv.CV_CALIB_ZERO_DISPARITY,alpha=-1,newImageSize=(0,0))
#cv2.reprojectImageTo3D(disp,points,Q)
print Q
map1x,map1y=cv2.initUndistortRectifyMap(cameraMatrix1,distCoeffs1,R1,P1,(384,288),cv2.CV_32FC1)
map2x,map2y=cv2.initUndistortRectifyMap(cameraMatrix2,distCoeffs2,R2,P2,(384,288),cv2.CV_32FC1)
#cv2.remap(imgL,map1x,map1y,cv2.INTER_LINEAR, imgU1, cv2.BORDER_CONSTANT,0)
#cv2.remap(imgR,map2x,map2y,cv2.INTER_LINEAR, imgU2, cv2.BORDER_CONSTANT,0)
imgU1 = cv2.remap(imgL,map1x,map1y,cv2.INTER_LINEAR)
imgU2 = cv2.remap(imgR,map2x,map2y,cv2.INTER_LINEAR)
#imgU1 = imgU1.astype(np.uint8)
#imgU2 = imgU2.astype(np.uint8)
stereo = cv2.StereoBM(1,16,15)
disp=stereo.compute(imgU1,imgU2,disptype=cv2.CV_32FC1)
norm_coeff = 255/disp.max()
cv2.imshow('disp', disp*norm_coeff/255)
cv2.imwrite('dispimage.png', disp*norm_coeff/255)
# When everything done, release the capture
#cap.release()
#cv2.destroyAllWindows()