openCL cv2.UMat object is not iterable - python

well actually i dont really understand how to use this T-API opencl and still newbie at it, in the documentation
https://www.learnopencv.com/opencv-transparent-api/
it use cv2.UMat to the .image file and then read it. In my problem i want to use the opencl T-API to my reconizer.predict line because the image is taken/processing while streaming the camera
recognizer = cv2.face.LBPHFaceRecognizer_create()
#colec = cv2.face.MinDistancePredictCollector()
recognizer.read("trainer_data_array.yml")
labels = {"persons_name":0}
with open("labels.pickle", "rb") as f:
og_labels = pickle.load(f)
labels = {v:k for k,v in og_labels.items()}
cap = cv2.VideoCapture(0)
while(True):
#video cap
ret, frame = cap.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.5, minNeighbors=5)
for (x,y,w,h) in faces:
#print(x,y,w,h)
roi_gray = gray[y:y+h, x:x+w]
roy_color = frame[y:y+h, x:x+w]
#recognize how?
id_ , conf = recognizer.predict(roi_gray) #some error, some say cuz its opencv 3.1.0 bug
#solution : up opencv to 3.3 or just use MinDistancePredictCollector(...)
if conf>=45 and conf<=85:
print(idppl)
print(labels[idppl])
font = cv2.FONT_HERSHEY_SIMPLEX
name = labels[idppl]
color = (255,255,255)
stroke = 2
cv2.putText(frame,name,(x,y),font,1,color,stroke,cv2.LINE_AA)
elif conf > 85:
print("unknown")
can someone help me how to do it, if just put it raw like id_ , conf = cv2.UMat(recognizer.predict(roi_gray))
it give me error cv2.UMat' object is not iterable
well without the T-API mybe this line program still give a good frame rate, but after given many modification or implementation/process it'll run in low frame rate when detecting/recog- people face.
this why i want to use openCl so when it run in gpu mybe will give me a pretty good frame rate

Related

OpenCV Python kernel crashes when clicking the trackbar

I am trying to create a simple trackbar to test some edge detection, and I've been following the official opencv tutorial from here in Python. When I run the code, the window is created and I can see the sliders, but when I click the sliders, the kernel crashes.
I tried this with some other code example from the internet and it crashed then as well. Basically the moment I click in the region of the slider, the kernel crashes. I know that one thing you seem to need to do in macs is increase the waitKey time and I did do that.
How can I make this work?
def canny_threshold(low_val, src, src_gray):
low_threshold = low_val
img_blur = cv.blur(src_gray, (3,3))
detected_edges = cv.Canny(img_blur, low_threshold, low_threshold * RATIO)
mask = detected_edges != 0
dst = src * (mask[:,:, None].astype(src.dtype))
return dst
src = cv.imread("magpie_house.jpeg")
src_gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
def nothing(x):
pass
cv.namedWindow(WINDOW_NAME)
cv.startWindowThread()
cv.createTrackbar(TITLE_TRACK_BAR, WINDOW_NAME, 0, MAX_LOW_THRESHOLD, nothing)
cv.setTrackbarPos(TITLE_TRACK_BAR, WINDOW_NAME, 50)
while True:
COUNTER += 1
if COUNTER >= 700:
break
low_val = cv.getTrackbarPos(TITLE_TRACK_BAR, WINDOW_NAME)
dst = canny_threshold(low_val, src, src_gray)
cv.imshow(WINDOW_NAME, dst)
if cv.waitKey(10) & 0xFF == ord("q"):
break
cv.waitKey(1)
cv.destroyAllWindows()
It appears that there is a known issue on macs regarding trackbars.

'NoneType' object has no attribute 'size' - how to face detection using mtcnn?

i'm trying to build face recognition in real time in neural network(facenet network) using pytorch and face detection using MTCNN
i've tried this for detecting faces in real time (from webcam) but doesnt work
read frames then going through mtcnn detector
import cv2
capture = cv2.VideoCapture(0)
while(True):
ret, frame = capture.read()
frames_tracked = []
print('\rTracking frame: {}'.format(i + 1), end='')
boxes,_ = mtcnn.detect(frame)
frame_draw = frame.copy()
draw = ImageDraw.Draw(frame_draw)
for box in boxes:
draw.rectangle(box.tolist(), outline=(255, 0, 0), width=6)
frames_tracked.append(frame_draw.resize((640, 360), Image.BILINEAR))
d = display.display(frames_tracked[0], display_id=True)
i = 1
try:
while True:
d.update(frames_tracked[i % len(frames_tracked)])
i += 1
except KeyboardInterrupt:
pass
if cv2.waitKey('q') == 27:
break
capture.release()
cv2.destroyAllWindows()
but it will rise this error :
this is the entire traceback http://dpaste.com/0HR58RQ
AttributeError: 'NoneType' object has no attribute 'size'
is there a solution for this problem ? what caused this error? thanks for your advice
Let's take a look at that error again.
AttributeError: 'NoneType' object has no attribute 'size'
so, somewhere in your code you(or mtcnn) are trying to call size attribute from a None variable. you are passing frame to mtcnn using following command :
boxes,_ = mtcnn.detect(frame)
this is exactly where you see that error. because you are passing a None variable to mtcnn. in order to prevent it, you can prevent it before calling this method. in other words :
ret, frame = capture.read()
if frame == None:
continue

Screenshot an area with openCV via python 3.7.3

The end goal of the project is to take in a capture of the screen and output circles in the screenshots locations(midpoint and radius). So very start of this project is capturing the screen and sending it through a circle finding function.
I started here: Screen Capture with OpenCV and Python-2.7
This works for its functionality and on my machine does the cv2.imshow sucessfully displays the screenshots as it should. However, I want it to work with this example: https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_houghcircles/py_houghcircles.html
Basically, the code in that example works for cv2.imshow, however, I want it to work with cv2.imread so it's compatible with the example I want to copy.
I've tried a few basic things to no avail, for reference see below!
Attempt 1: http://prntscr.com/n8tpyh
printscreen_pil = Imagegrab()
printscreen_numpy = np.array(printscreen_pil.getdata(),dtype='uint8')
img = cv2.imread(printscreen_humpy , 0)
Errors on cv2.imread with message
TypeError: bad argument type for built-in operation
Attempt 2: http://prntscr.com/n8tqtp
from mss import mss
mon = {'top':160 , 'left': 160 , 'width': 200, 'height': 200 }
sct = mss()
sct.get_pixels(mon)
Errors on sc.getpixels with message AttributeError: 'MSS' object has no attribute `get_pixels'
Attempt 3: https://prnt.sc/n8tw7w
img_grab = ImageGrab.grab(bbox=(0,0,500,500))
img = np.array(img_grab)
#img = cv2.imread(img)
img = cv2.medianBlur(img,5)
cimg = cv2.cvtColor(img,cv2.COLOR_GRAY2BGR)
Errors on cimg = cv2.cvtColor(img,cv2.COLOR_GRAY2BGR) with a very long message which I will summarize into (-2:Unspecified error) and Invalid number of channels in input image: 'VScn::contains(scn)' where 'scn' is 3 for more info please open the screenshot, if not drop a comment and I'll type that chunk for ya!
Attempt 4: http://prntscr.com/n8u0jc
cords = {'top':40 , 'left': 0 , 'width': 800, 'height': 640 }
with mss() as sct :
img = np.array(sct.grab(cords))
img = cv2.medianBlur(img,5)
cimg = cv2.cvtColor(img , cv2.COLOR_GRAY2BGR)
Errors on cimg = cv2.cvtColor(img , cv2.COLOR_GRAY2BGR) with message I will again summarize to Invalid number of channels in input image: `VScn::contains(scn)' where 'scn' is 4
Thanks Everyone!!!!
Based on your attempt 4, use this to define cimg:
cimg = cv2.cvtColor(img, cv2.COLOR_BGRA2GRAY)

Face Recognition with LBPHFaceRecognizer always predict as same person.Even when anonymous person to face the camera?

I have a data set for myself.
My code works perfectly when i go to the camera. But I test again with unknown person the program predicts again as me. It should return -1 or null !!!
I run in python3 and latest version of cv2 from opencv.
->detector.py
import cv2,os
import numpy as np
from PIL import Image
import pickle,time
# Root directory
ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
recognizer = cv2.face.LBPHFaceRecognizer_create()#cv2.createLBPHFaceRecognizer()
recognizer.read('trainer/trainer.yml')
cascadePath = "Classifiers/face.xml"
faceCascade = cv2.CascadeClassifier(cascadePath);
path = 'dataSet'
cam = cv2.VideoCapture(0)
print(cam.isOpened())
#font = cv2.InitFont(cv2.CV_FONT_HERSHEY_SIMPLEX, 1, 1, 0, 1, 1)
#Creates a font
font = cv2.FONT_HERSHEY_SIMPLEX
while True:
ret, im =cam.read()
print('im: ',im,' ;ROOT_DIR:',ROOT_DIR)
print('ret: ',ret)
gray=cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
faces=faceCascade.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=5, minSize=(100, 100), flags=cv2.CASCADE_SCALE_IMAGE)
for(x,y,w,h) in faces:
nbr_predicted, conf = recognizer.predict(gray[y:y+h,x:x+w])
cv2.rectangle(im,(x-50,y-50),(x+w+50,y+h+50),(225,0,0),2)
print("nbr_predicted: ",nbr_predicted)
if(nbr_predicted==7 or nbr_predicted==8):
nbr_predicted='Vishesh 1'
else:
nbr_predicted="Unknown Person"
cv2.putText(im,str(nbr_predicted)+"--"+str(conf), (x,y+h),font, 0.8, (0, 255, 0), 2, cv2.LINE_AA) #Draw the text
cv2.imshow('im',im)
cv2.waitKey(10)
Only the person in middle must be Vishesh. But even my bros are predicted as Vishesh. Where could this be possibly going wrong ??
ecognizer.predict(gray[y:y+h,x:x+w]) returns the prediction index that shows the number of the person in training set and confidence for it for all persons in the training set with a confidence value.
Since your photo is the only one in the training set, it returns nbr_predicted is always your ID and confidence shows the "probability" that the image send to predict function is you.
hence update your code as:
if(nbr_predicted==7 and conf<120):
nbr_predicted='Vishesh 1'
else:
nbr_predicted="Unknown Person"
the value of confidence usually depends on your data, but the lower the better.
you should adjust the threshold

python opencv - what is the best way to use video input to an image path interface api

I have an api take img_path as input as it use cv2.imread() to load image.
def detect(net, classes, img_path, CONF_THRESH = 0.8, NMS_THRESH = 0.3):
outputs = []
im = cv2.imread(img_path)
......
......
Now I want to create a small tool to directly load video and call the api function.However, while the cap.read() is done. I can't directly pass the image object into the api function.
def detect_video(net, classes, video, CONF_THRESH = 0.8, NMS_THRESH =0.3):
"""detect an input video"""
try:
cap = cv2.VideoCapture('video')
except Exception, e:
print e
return None
while(True):
ret, frame = cap.read()
# try to call the api function
What the best way to do so that I don't have to change the api function? My idea is to imwrite the video capture image and reload it again. but this seems stupid and slow.
if you want to pass a frame as argument to your api detect function, save it first and then call the api function as usual
img_path = 'image.jpg'
...
ret, frame = cap.read()
cv2.imwrite(img_path, frame)
# and now try to call the api function
detect(net, classes, img_path, CONF_THRESH = 0.8, NMS_THRESH = 0.3)

Categories