stop face recognition in python as soon as face recognized - python

this is my code. it detects the faces and recognize the faces. but i want it to stop as soon as the face is recognized. More clearly as soon as the face is detected recognizer should try to recognize it and after recognizing it, it should not do it again and again.
in short, for every face detected fisherface should run only once(for every face).
# facerec.py
import cv2, sys, numpy, os
import json
size = 4
fn_haar = 'haarcascade_frontalface_default.xml'
fn_dir = 'att_faces'
path2='/home/irum/Desktop/Face-Recognition/thakarrecog/UNKNOWNS'
path='/home/irum/Desktop/Face-Recognition/thakarrecog/att_faces'
# Part 1: Create fisherRecognizer
print('Training...')
# Create a list of images and a list of corresponding names
(images, lables, names, id) = ([], [], {}, 0)
for (subdirs, dirs, files) in os.walk(fn_dir):
for subdir in dirs:
names[id] = subdir
subjectpath = os.path.join(fn_dir, subdir)
for filename in os.listdir(subjectpath):
path = subjectpath + '/' + filename
lable = id
images.append(cv2.imread(path, 0))
lables.append(int(lable))
id += 1
(im_width, im_height) = (112, 92)
# Create a Numpy array from the two lists above
(images, lables) = [numpy.array(lis) for lis in [images, lables]]
# OpenCV trains a model from the images
model = cv2.createFisherFaceRecognizer()
model.train(images, lables)
# Part 2: Use fisherRecognizer on camera stream
haar_cascade = cv2.CascadeClassifier(fn_haar)
# Capturing camera feed
webcam = cv2.VideoCapture(0)
webcam.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH, 1920)
webcam.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT, 1080)
while True:
# Reading Frames from live stream
(rval, frame) = webcam.read()
frame=cv2.flip(frame,1,0)
#Convert frame into gray
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (21, 21), 0)
# Resize the gary
mini = cv2.resize(gray, (gray.shape[1] / size, gray.shape[0] / size))
# Detecting the face
faces = haar_cascade.detectMultiScale(mini,1.3, 5)
for i in range(len(faces)):
face_i = faces[i]
(x, y, w, h) = [v * size for v in face_i]
# Croping face
face = gray[y:y + h, x:x + w]
face_resize = cv2.resize(face, (im_width, im_height))
# Eualize Histogram
eq = cv2.equalizeHist(face_resize)
# Try to recognize the face
prediction = model.predict(eq)
print "Recognition Prediction" ,prediction
# Draw rectangle around the face
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 3)
# Write the name of recognized face
result = {
'face': {
'distance': prediction,
'coords': {
'x': str(faces[0][0]),
'y': str(faces[0][1]),
'width': str(faces[0][2]),
'height': str(faces[0][3])
}
}
}
print "1 Result of Over all Prediction" ,result
if prediction[0]>0 and prediction[1]<600:
result = {
'face': {
'distance': prediction[1],
'coords': {
'x': str(faces[0][0]),
'y': str(faces[0][1]),
'width': str(faces[0][2]),
'height': str(faces[0][3])
}
}
}
dist = result['face']['distance']
print "Known Face DISTANCE" , dist
cv2.putText(frame,
'%s - %.0f' % (names[prediction[0]],prediction[1]),
(x-10, y-10), cv2.FONT_HERSHEY_DUPLEX,1,(255, 255, 0))
else:
print "for prediction more than 600"
print "prediction", prediction
result = {
'face': {
'distance': prediction[1],
'coords': {
'x': str(faces[0][0]),
'y': str(faces[0][1]),
'width': str(faces[0][2]),
'height': str(faces[0][3])
}
}
}
dist = result['face']['distance']
print "UNKNOWN FACE" , dist
cv2.putText(frame,
'Unknown',
(x-10, y-10), cv2.FONT_HERSHEY_PLAIN,1,(255, 255, 0))
pin=sorted([int(n[:n.find('.')]) for n in os.listdir(path2)
if n[0]!='.' ]+[0])[-1] + 1
cv2.imwrite('%s/%s.jpg' % (path2, pin), eq)
cv2.imshow('OpenCV', frame)
key = cv2.waitKey(10)
if key == 27:
break

Related

i am working on program which select's the ROI of wobbly video and extract the ROI in diff window as stable ROI, want to improve its computation speed

The problem is, program is really lengthy and computationally expensive.
so is there any way to make this program faster or any other way to write this code?
I am beginner in python and would love to take all suggestions or different approach then this program
also i am new to the stack overflow so if anything is wrong in this post or any issue in program please point out in comment .
first section of code is
#TEST V2.1 multitracker
import cv2
import numpy as np
#path = (input("enter the video path: "))
cap = cv2.VideoCapture(" YOUR VIDEO PATH ")
# creating the dictionary to add all the wanted trackers in OpenCV that can be used for tracking in future
OBJECT_TRACKING_MACHINE = {
"csrt": cv2.legacy.TrackerCSRT_create,
"kcf": cv2.legacy.TrackerKCF_create,
"boosting": cv2.legacy.TrackerBoosting_create,
"mil": cv2.legacy.TrackerMIL_create,
"tld": cv2.legacy.TrackerTLD_create,
"medianflow": cv2.legacy.TrackerMedianFlow_create,
"mosse": cv2.legacy.TrackerMOSSE_create
}
# Creating the MultiTracker variable object to store the
trackers = cv2.legacy.MultiTracker_create()
here I started the loop
while True:
frame = cap.read()[1]
#print("freame start",frame)
if frame is None:
print("error getting the video,please check the input")
break
frame = cv2.resize(frame,(1080,720))
Thresh = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
#Thresh = cv2.adaptiveThreshold(gray, 185, cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY_INV, 11, 6)
#print(trackers.update(Thresh))
(success, boxes) = trackers.update(Thresh)
# loop over the bounding boxes and draw them on the frame
if success == False:
bound_boxes = trackers.getObjects()
idx = np.where(bound_boxes.sum(axis= 1) != 0)[0]
bound_boxes = bound_boxes[idx]
trackers = cv2.legacy.MultiTracker_create()
for bound_box in bound_boxes:
trackers.add(tracker,Thresh,bound_box)
x,y,w,h = cv2.boundingRect(Thresh)
k = cv2.waitKey(50)
And I am guessing this is the section which is making the program slow
if is there any different way to represent this part or any idea different then this
for i,box in enumerate(boxes):
(x, y, w, h) = [int(v) for v in box]
#cv2.rectangle(Thresh, (x, y), (x + w, y + h), (255, 255, 255), 2)
#cv2.putText(Thresh,('TRACKING BOX NO-'+str(i)),(x+10,y-3),cv2.FONT_HERSHEY_PLAIN,1.0,(255,255,0),2)
arr = boxes.astype(int)
if i == 0 :
Roi = Thresh[(arr[i,1]):(arr[i,1]+arr[i,3]),(arr[i,0]):(arr[i,0]+arr[i,2])]
murg = cv2.resize(Roi,(300,200))
cv2.imshow("horizon", murg)
#print(murg)
if i == 1 :
Roi1 = Thresh[(arr[i,1]):(arr[i,1]+arr[i,3]),(arr[i,0]):(arr[i,0]+arr[i,2])]
Roi = Thresh[(arr[(i-1),1]):(arr[(i-1),1]+arr[(i-1),3]),(arr[(i-1),0]):(arr[(i-1),0]+arr[(i-1),2])]
murg = cv2.resize(Roi,(300,200))
murg1 = cv2.resize(Roi1,(300,200))
hori = np.concatenate((murg,murg1),axis=1)
cv2.imshow("horizon",hori)
#print(hori)
elif i == 2 :
Roi2 = Thresh[(arr[i,1]):(arr[i,1]+arr[i,3]),(arr[i,0]):(arr[i,0]+arr[i,2])]
Roi1 = Thresh[(arr[(i-1),1]):(arr[(i-1),1]+arr[(i-1),3]),(arr[(i-1),0]):(arr[(i-1),0]+arr[(i-1),2])]
Roi = Thresh[(arr[(i-2),1]):(arr[(i-2),1]+arr[(i-2),3]),(arr[(i-2),0]):(arr[(i-2),0]+arr[(i-2),2])]
murg = cv2.resize(Roi,(300,200))
murg1 = cv2.resize(Roi1,(300,200))
murg2 = cv2.resize(Roi2,(300,200))
hori = np.concatenate((murg,murg1,murg2),axis=1)
cv2.imshow("horizon",hori)
#print(hori)
elif i == 3 :
Roi3 = Thresh[(arr[i,1]):(arr[i,1]+arr[i,3]),(arr[i,0]):(arr[i,0]+arr[i,2])]
Roi2 = Thresh[(arr[(i-1),1]):(arr[(i-1),1]+arr[(i-1),3]),(arr[(i-1),0]):(arr[(i-1),0]+arr[(i-1),2])]
Roi1 = Thresh[(arr[(i-2),1]):(arr[(i-2),1]+arr[(i-2),3]),(arr[(i-2),0]):(arr[(i-2),0]+arr[(i-2),2])]
Roi = Thresh[(arr[(i-3),1]):(arr[(i-3),1]+arr[(i-3),3]),(arr[(i-3),0]):(arr[(i-3),0]+arr[(i-3),2])]
murg = cv2.resize(Roi,(300,200))
murg1 = cv2.resize(Roi1,(300,200))
murg2 = cv2.resize(Roi2,(300,200))
murg3 = cv2.resize(Roi3,(300,200))
hori = np.concatenate((murg,murg1,murg2,murg3),axis=1)
cv2.imshow("horizon",hori)
#print(hori)
this section is so that I can print the ROI matrix and to select the ROI
if k == ord("1"):
print(murg)
if k == ord("2"):
print(murg1)
if k == ord ("3"):
print(murg2)
if k == ord("4"):
print(murg3)
cv2.imshow('Frame', Thresh)
if k == ord("e"):
break
if k == ord("s"):
roi = cv2.selectROI("Frame", Thresh, fromCenter=False,showCrosshair=False)
tracker = OBJECT_TRACKING_MACHINE['mosse']()
trackers.add(tracker, Thresh, roi)
#print(boxes,success)
cap.release()
cv2.destroyAllWindows()
when you will run this code you can extract 4 ROI frames which will track your ROI's (I haven't added the precaution for empty matrix so it will give you error if you select more than 4 roi's)
my end goal is to extract those ROI videos for Image processing (this code is not done yet and there's more image processing is going to happen in letter part) **

module 'cv2' has no attribute LBPHFaceRecognizer_create()

I am trying to learn face detection and I got this code from GeeksforGeeks tutorial. However When I run one of the two files, it shows the error AttributeError: module 'cv2' has no attribute 'LBPHFaceRecognizer_create'. I tried uninstalling open cv, installing pip install opencv-contrib-python as well as reinstalling open cv and running it. I am currently running open cv2 4.5.5. The tutorial advised to remove the '.face' from cv2.face.LBPHFaceRecognizer_create() for running cv2, however when I run it with .face, it displays module 'cv2' has no attribute 'face'. Please, someone, help me with this
# It helps in identifying the faces
import cv2, sys, numpy, os
from cv2 import *
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.LBPHFaceRecognizer_create()
model.train(images, labels)
for i in range[0, 20]:
if i<10:
print(i)
i += 1
else:
print('Done wit it')
# Part 2: Use fisherRecognizer on camera stream
face_cascade = cv2.CascadeClassifier(haar_file)
webcam = cv2.VideoCapture(0)
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)
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
I think that you may need to explicitly state "cv2.face" not just "face..."
model = cv2.face.LBPHFaceRecognizer_create()
before doing so...did you confirm that you have a version of Opencv installed that contains the module Face? You can check like this:
import cv2
functions = dir(cv2)
for f in functions:
print (f)
and if not...install like this:
pip uninstall opencv-contrib-python
pip install opencv-contrib-python

Why is the groupRectangle() function attempting to convert a value?

Im using Python, cv2, numpy and pyautogui to bot a simple game it detects apples and stars coming onto the screen it worked fine but got confused when the game sped up as it was only searching for 1 item at a time so I changed to this to detect multiple at a time which works fine however it needs some grouping due to multiple detections of the same object this works sometimes but then after a random amount of time I get the following error...
Error line 76 cv.groupRectangles() param1 is attempting to convert a value.
while(True):
scr = np.array(screenshot.grab(dimensions))
scr_no_alpha = scr[:,:,:3]
result = cv.matchTemplate(scr_no_alpha, needle, cv.TM_CCOEFF_NORMED)
result2 = cv.matchTemplate(scr_no_alpha, needle2, cv.TM_CCOEFF_NORMED)
_, max_val, _, max_loc = cv.minMaxLoc(result)
_, max_val2, _, max_loc2 = cv.minMaxLoc(result2)
src = scr.copy()
x_top_row, y_top_row = 145,140
x_middle_row, y_middle_row = 185,185
x_bottom_row, y_bottom_row = 185,270
cv.rectangle(src, (x_top_row, y_top_row), (x_top_row+w, y_top_row+h), (0,255,0), 2)
cv.rectangle(src, (x_middle_row, y_middle_row), (x_middle_row+w, y_middle_row+h), (0,255,0), 2)
cv.rectangle(src, (x_bottom_row, y_bottom_row), (x_bottom_row+w, y_bottom_row+h), (0,255,0), 2)
x_star_row, y_star_row = 10,120
cv.rectangle(src, (x_star_row, y_star_row), (x_star_row+w2, y_star_row+h2), (0,255,0), 2)
threshold = 0.6
apple_locations = np.where(result >= threshold)
apple_locations = list(zip(*apple_locations[::-1]))
threshold = 0.4
star_locations = np.where(result2 >= threshold)
star_locations = list(zip(*star_locations[::-1]))
apple_colour = (0,0,255)
star_colour = (0,255,255)
line_type = cv.LINE_4
if len(apple_locations):
apples_group = []
for loc in apple_locations:
rect = [int(loc[0]), int(loc[1]), w, h]
print(rect)
apples_group.append(rect)
apples_group.append(rect)
print(apples_group)
apples_group, weights = cv.groupRectangles(apples_group, 2, 0.5)
print(apples_group)
print(f'{len(apples_group)} Needle(s) of type Apple found.')
for (x, y, w, h) in apples_group:
cv.rectangle(src, (x, y), (x+w, y+h), apple_colour, line_type)
for apple in apples_group:
if apple[0] in range(x_top_row, y_top_row) and apple[1] in range(x_top_row+w, y_top_row+h):
pyautogui.press('w')
if apple[0] in range(x_middle_row, y_middle_row) and apple[1] in range(x_middle_row+w, y_middle_row+h):
pyautogui.press('s')
if apple[0] in range(x_bottom_row, y_bottom_row) and apple[1] in range(x_bottom_row+w, y_bottom_row+h):
pyautogui.press('d')
cv.imshow('Matches', src)
if len(star_locations):
stars_group = []
for loc in star_locations:
rect = [int(loc[0]), int(loc[1]), w2, h2]
stars_group.append(rect)
stars_group.append(rect)
stars_group, weights = cv.groupRectangles(stars_group, 2, 0.5)
print(f'{len(stars_group)} Needle(s) of type Star found.')
for (x, y, w, h) in stars_group:
cv.rectangle(src, (x, y), (x+w, y+h), star_colour, line_type)
for star in stars_group:
if star[0] in range(x_star_row, y_star_row) and star[1] in range(x_star_row+w, y_star_row+h):
pyautogui.press('a')
cv.imshow('Matches', src)
cv.waitKey(1)
if keyboard.is_pressed('q'):
cv.destroyAllWindows()
break
For some unknown reason the w and h that are entered into the rect list are not always an int value so casting them to an int int(w), int(h) fixes the problem.

Disparity Map just shows contouring

The problem:
The goal is to create a disparity map for two parallel cameras. Currently the calculation itself is working, and I have a live disparitymap. It just shows contouring instead of information for every pixel, which is not what a disparity map should be doing.
.
What I have tried:
I tried the tsuka example, the lines are commented out, but they work. So this proves that the used functions work.
The result of my code is here: https://imgur.com/a/bIDmdkk (I probably don't have the reputation needed to upload images)
As can be seen in that image just the outline, the contour, of my face is visible. This contour reacts to my actual distance - with getting brighter or darker - but the rest of the image is dark.
With all parameters commented out (as is the example) it does now work either but has lots and lots of speckles laying over.
I also tried almost any combination of numDisparities and blocksize.
Changing the position of the cameras to one another alters the result but does not change it massively. I made sure to have them in a line with each other, looking in parallel.
Edit: I tinkered a bit and got this result: https://imgur.com/a/m2o9FOE compared to the previous result there are more features, but also more noise. (This one has fewer disparities and another color convertion)
SOLVED: [I tried running the stereo.compute within the while-loop with BGR-Images, but that does not work. The tsuka-example images are colored though, so there might be some case of wrong datatype that I do not see.
Everything is uint8 currently.] => I forgot that imread("",0) reads an image as grayscale. So everything behaves as it should in this regard.
.
So what is the difference between my left/right images and the ones resulting in https://docs.opencv.org/master/disparity_map.jpg ?
.
The code:
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
cap1 = cv.VideoCapture(1)
cap3 = cv.VideoCapture(3)
#imgR = cv.imread('tsuL.png',0)
#imgL = cv.imread('tsuR.png',0)
#stereoTest = cv.StereoBM_create(numDisparities=16, blockSize=15)
#disparityTest = stereoTest.compute(imgL,imgR)
while True:
# save current camera image
ret1, frame1 = cap1.read()
ret3, frame3 = cap3.read()
# switch from BGR to gray
grayFrame1 = cv.cvtColor(frame1, cv.COLOR_BGR2GRAY)
grayFrame3 = cv.cvtColor(frame3, cv.COLOR_BGR2GRAY)
# disparity params
stereo = cv.StereoBM_create(numDisparities=128, blockSize=5)
stereo.setTextureThreshold(600)
#stereo.setSpeckleRange(4)
#stereo.setSpeckleWindowSize(9)
stereo.setMinDisparity(0)
# calculate both variants (Camera 1 Left, Camera 2 Right and Camera 1 right, Camera 2 left)
disparity = stereo.compute(grayFrame1,grayFrame3)
disparity2 = stereo.compute(grayFrame3,grayFrame1)
#res = cv.cvtColor(disparity,cv.COLOR_GRAY2BGR)
# Should have been 65535 from int16 to int8, but 4095 works..
div = 65535.0/16
res = cv.convertScaleAbs(disparity, alpha=(255.0/div))
res2= cv.convertScaleAbs(disparity2, alpha=(255.0/div))
# Show disparity map
cv.namedWindow("Disparity")
cv.moveWindow("Disparity", 450, 20)
cv.imshow('Disparity', np.hstack([res,res2]))
keyboard = cv.waitKey(30)
if keyboard == 'q' or keyboard == 27:
break
cap.release()
cv.destroyAllWindows()
New Code
I got the camera calibration data from boofcv and copied some lines from https://stackoverflow.com/a/29151300/13150965 to my code.
Schwarz S/W
Xc 311,0 323,3
Yc 257,1 261,9
fx 603,0 593,6
fy 604,3 596,5
skew
radial 1,43e-01 1,1e-01
-3,03e-01 -2,43e-01
tangential 1,37e-02 1,25e-02
-9,77e-03 -9,79e-04
These are the values I received for each Camera (Schwarz and S/W are just names for each camera, they have different cables, that's how I recognize them)
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
cap1 = cv.VideoCapture(0)
cap3 = cv.VideoCapture(1)
cameraMatrix1 = np.array(
[[603.0, 0, 311.0],
[0, 604.3, 257.1],
[0, 0, 1]]
)
cameraMatrix2 = np.array(
[[593.6, 0, 323.3],
[0, 596.5, 261.9],
[0, 0, 1]]
)
distCoeffs1 = np.array([[0.143, -0.303, 0.0137, -0.00977, 0.0]])
distCoeffs2 = np.array([[0.11, -0.243, 0.0125, -0.000979, 0.0]])
R = np.array(
[[1.0, 0.0, 0.0],
[0.0, 1.0, 0.0],
[0.0, 0.0, 1.0]]
)
T = np.array(
[[98.0],
[0.0],
[0.0]]
)
# Params from camera calibration
camMats = [cameraMatrix1, cameraMatrix2]
distCoeffs = [distCoeffs1, distCoeffs2]
camSources = [0,1]
for src in camSources:
distCoeffs[src][0][4] = 0.0 # use only the first 2 values in distCoeffs
xOff = 450
div = 64.0
i = 0
while True:
# save current camera image
ret1, frame1 = cap1.read()
ret3, frame3 = cap3.read()
w, h = frame1.shape[:2]
# The rectification process
newCams = [0,0]
roi = [0,0]
frames = [frame1, frame3]
i = i + 1
if i > 10:
for src in camSources:
newCams[src], roi[src] = cv.getOptimalNewCameraMatrix(cameraMatrix = camMats[src],
distCoeffs = distCoeffs[src],
imageSize = (w,h),
alpha = 0)
rectFrames = [0,0]
for src in camSources:
rectFrames[src] = cv.undistort(frames[src], camMats[src], distCoeffs[src])
R1,R2,P1,P2,Q,roi1,roi2 = cv.stereoRectify(
cameraMatrix1 =camMats[0],
cameraMatrix2 =camMats[1],
distCoeffs1 =distCoeffs1,
distCoeffs2 =distCoeffs2,
imageSize = (w,h),
R=R,
T=T,
alpha=1
)
# show camera images
cv.namedWindow("RectFrames")
cv.moveWindow("RectFrames", xOff, 532)
cv.imshow('RectFrames', np.hstack([rectFrames[0],rectFrames[1]]))
# switch from BGR to gray
grayFrame1 = cv.cvtColor(rectFrames[0], cv.COLOR_BGR2GRAY)
grayFrame3 = cv.cvtColor(rectFrames[1], cv.COLOR_BGR2GRAY)
# disparity params
stereo = cv.StereoBM_create(numDisparities=16, blockSize=15)
# calculate both variants (Camera 1 Left, Camera 2 Right and Camera 1 right, Camera 2 left)
disparity = stereo.compute(grayFrame1,grayFrame3)
disparity2 = stereo.compute(grayFrame3,grayFrame1)
# Should have been 65535 from int16 to int8, but 4095 works..
res = cv.convertScaleAbs(disparity, alpha=(255.0/(div-1)))
res2= cv.convertScaleAbs(disparity2, alpha=(255.0/(div-1)))
# Show disparity map
cv.namedWindow("Disparity")
cv.moveWindow("Disparity", xOff, 20)
cv.imshow('Disparity', np.hstack([res,res2]))
keyboard = cv.waitKey(30)
if keyboard == 'q' or keyboard == 27:
break
cap.release()
cv.destroyAllWindows()
I can see, that the images are being undistorted. https://imgur.com/a/SBmv7IY
But I am still doing something wrong.
The R and T are made up, as they look parallel (No Rotation) and are 9.8cm apart from another.
The Values for R and T calculated via the script from StereoCalibration in OpenCV on Python resulted in the unity-matrix for R and an empty vector for T. The latter cannot be right.
I now got the R and T values for a given calibration of the cameras. But it does in fact not solve my problem. So either there is still an error in that calculation or this problem has to be solved differently.
I rewrote the entire script, to see at which step it misbehaves - and do tidy things up. At is stands, the calibration works up to the cv2.initUndistortRectifyMap , if I use this map with cv2.remap onto my camera image, I just get a black image.
import numpy as np
import cv2
from VideoCapture import Device
from PIL import Image
import glob
print("Importing Images")
image_listR = []
image_listL = []
w = 640
h = 480
for filename in glob.glob('StereoCalibrate\imageR*'): #assuming gif
im=Image.open(filename).convert('RGB')
cvim= np.array(im)
cvim = cvim[:, :, ::-1].copy()
image_listR.append(cvim)
for filename in glob.glob('StereoCalibrate\imageL*'): #assuming gif
im=Image.open(filename).convert('RGB')
cvim= np.array(im)
cvim = cvim[:, :, ::-1].copy()
image_listL.append(cvim)
imagesR = len(image_listR)
imagesL = len(image_listL)
print("Found {%d} images for Left camera" % imagesL)
print("Found {%d} images for Right camera" % imagesR)
if imagesR == imagesL:
print("Number of Images match")
else:
print("Number of Images do not match")
print("Using loaded images")
board_w = 8
board_h = 5
board_sz = (8,5)
board_n = board_w*board_h
# termination criteria
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
# Arrays to store object points and image points from all the images.
object_points = [] # 3d point in real world space
imagePoints1 = [] # 2d points in image plane.
imagePoints2 = [] # 2d points in image plane.
corners1 = []
corners2 = []
obj = np.zeros((5*8,3), np.float32)
obj[:,:2] = np.mgrid[0:8,0:5].T.reshape(-1,2)
vidStreamL = cv2.VideoCapture(1) # index of your camera
vidStreamR = cv2.VideoCapture(0) # index of your camera
success = 0
found1 = False
found2 = False
i=0
while (success < imagesR*0.9):
#Loop through the image list
if i >= imagesL:
i = 0
img1 = image_listL[i]
img2 = image_listR[i]
#Convert images to grayscale
gray1 = cv2.cvtColor(img1,cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)
#Check for Chessboard Pattern
found1, corners1 = cv2.findChessboardCorners(img1, board_sz)
found2, corners2 = cv2.findChessboardCorners(img2, board_sz)
#Draw Chessboard in image
if (found1):
cv2.cornerSubPix(gray1, corners1, (11, 11), (-1, -1),criteria)
cv2.drawChessboardCorners(gray1, board_sz, corners1, found1)
if (found2):
cv2.cornerSubPix(gray2, corners2, (11, 11), (-1, -1), criteria)
cv2.drawChessboardCorners(gray2, board_sz, corners2, found2)
#Show grayscale image with chessboard marker
cv2.imshow('image1', gray1)
cv2.imshow('image2', gray2)
if (found1 != 0 and found2 != 0):
#Remove successful detected images from list
image_listL.pop(i)
image_listR.pop(i)
imagesL-=1
imagePoints1.append(corners1);
imagePoints2.append(corners2);
object_points.append(obj);
success+=1
print("{", success, "} / {",imagesR*0.9,"} calibration images detected")
if (success >= imagesR*0.9):
break
i = i + 1
cv2.waitKey(1)
cv2.destroyAllWindows()
print("Calibrating")
cx1 = 327.0
cy1 = 247.9
fx1 = 608.3
fy1 = 607.7
rx1 = 0.129
ry1 = -0.269
tx1 = 0.00382
ty1 = -0.00151
camMat1 = np.array(
[[fx1, 0, cx1],
[0, fy1, cy1],
[0, 0, 1]])
cx2 = 329.8
cy2 = 249.0
fx2 = 601.7
fy2 = 601.1
rx2 = 0.149
ry2 = -0.322
tx2 = 0.0039
ty2 = -0.000837
camMat2 = np.array(
[[fx2, 0, cx2],
[0, fy2, cy2],
[0, 0, 1]])
disCoe1 = np.array([[0.0,0.0,0.0,0.0,0.0]])
disCoe2 = np.array([[0.0,0.0,0.0,0.0,0.0]])
R = np.zeros(shape=(3,3))
T = np.zeros(shape=(3,3))
E = np.zeros(shape=(3,3))
F = np.zeros(shape=(3,3))
retval, camMat1, disCoe1, camMat2, disCoe2, R, T, E, F = cv2.stereoCalibrate(object_points, imagePoints1, imagePoints2, camMat1, disCoe1, camMat2, disCoe2, (w, h), flags = cv2.CALIB_USE_INTRINSIC_GUESS)
print("Done Calibration\n")
R1 = np.zeros(shape=(3,3))
R2 = np.zeros(shape=(3,3))
P1 = np.zeros(shape=(3,4))
P2 = np.zeros(shape=(3,4))
print("T:")
print('\n'.join([' '.join(['{:4}'.format(item) for item in row])
for row in T]))
print("E:")
print('\n'.join([' '.join(['{:4}'.format(item) for item in row])
for row in E]))
print("F:")
print('\n'.join([' '.join(['{:4}'.format(item) for item in row])
for row in F]))
print("R:")
print('\n'.join([' '.join(['{:4}'.format(item) for item in row])
for row in R]))
print("CAM1:")
print('\n'.join([' '.join(['{:4}'.format(item) for item in row])
for row in camMat1]))
print("CAM2:")
print('\n'.join([' '.join(['{:4}'.format(item) for item in row])
for row in camMat2]))
print("DIS1:")
print('\n'.join([' '.join(['{:4}'.format(item) for item in row])
for row in disCoe1]))
print("DIS2:")
print('\n'.join([' '.join(['{:4}'.format(item) for item in row])
for row in disCoe2]))
print("Rectifying cameras")
cv2.stereoRectify(camMat1, disCoe1, camMat2, disCoe2,(w, h), R, T)
#print("Undistort image")
#map1x, map1y = cv2.initUndistortRectifyMap(camMat1, disCoe1, R1, camMat1, (w, h), cv2.CV_32FC1)
#map2x, map2y = cv2.initUndistortRectifyMap(camMat2, disCoe2, R2, camMat2, (w, h), cv2.CV_32FC1)
print("Settings complete\n")
i = 1
j = 1
while(True):
retL, img1 = vidStreamL.read()
retR, img2 = vidStreamR.read()
img1 = cv2.undistort(img1, camMat1, disCoe1)
img2 = cv2.undistort(img2, camMat2, disCoe2)
cv2.imshow("ImgCam", np.hstack([img1,img2]));
#imgU1 = np.zeros((h,w,3), np.uint8)
#imgU2 = np.zeros((h,w,3), np.uint8)
#imgU1 = cv2.remap(img1, map1x, map1y, cv2.INTER_LINEAR, imgU1, cv2.BORDER_CONSTANT, 0)
#imgU2 = cv2.remap(img2, map2x, map2y, cv2.INTER_LINEAR, imgU2, cv2.BORDER_CONSTANT, 0)
#cv2.imshow("ImageCam", np.hstack([imgU1,imgU2]));
#imgU1 = cv2.cvtColor(imgU1, cv2.COLOR_BGR2GRAY)
#imgU2 = cv2.cvtColor(imgU2, cv2.COLOR_BGR2GRAY)
img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
img2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
stereo = cv2.StereoBM_create(numDisparities=16, blockSize=15)
disparity = stereo.compute(img1,img2)
disparit2 = stereo.compute(img2,img1)
res = cv2.convertScaleAbs(disparity, alpha=(255.0/512.0))
re2 = cv2.convertScaleAbs(disparit2, alpha=(255.0/512.0))
cv2.namedWindow("Disparity")
cv2.imshow('Disparity', np.hstack([res,re2]))
cv2.waitKey(1)
Output:
Importing Images
Found {90} images for Left camera
Found {90} images for Right camera
Number of Images match
Using loaded images
{ 1 } / { 81.0 } calibration images detected
{ 2 } / { 81.0 } calibration images detected
...
{ 81 } / { 81.0 } calibration images detected
Calibrating
Done Calibration
T:
-3.4549164747952514
-0.15507627811210184
-0.058176064658149625
E:
0.0009397723130476023 0.05762864132890782 -0.15527769659160615
-0.01780225919479015 0.01349075458635349 3.455334047732434
-0.008356129824974412 -3.458367965240172 0.010848591597549652
F:
3.59441069386539e-08 2.1966757991956236e-06 -0.0032581679670958268
-6.799554333159719e-07 5.135279707045414e-07 0.060534502577423176
6.856712419870922e-06 -0.061575681061419536 1.0
R:
0.9988149170858261 -0.0472903202575948 -0.01150595570860947
0.047251107481307925 0.998876350140538 -0.0036564971909233096
0.011665943966274269 0.0031084947887139625 0.9999271188499311
CAM1:
457.8949692862012 0.0 333.02411929079784
0.0 459.45537763505865 239.7961684844508
0.0 0.0 1.0
CAM2:
460.4374113961873 0.0 342.68117331116434
0.0 461.07367491328057 244.62051778708334
0.0 0.0 1.0
DIS1:
0.06391854958023913 -0.2191286122082927 -0.000947168228999159 0.004660285089171575 0.08044318478168837
DIS2:
0.011643796283126952 0.14239490114798584 0.001548517080560543 0.011862118627062223 -0.5191998209097282
Rectifying cameras
Settings complete
You missed the Calibration and Rectification process, which is the first step of a disparity algorithm.
Below steps help you get your disparity map:
Calibrate your camera and find the intrinsic and extrinsic of the camera.
With the available camera and distortion matrix from the calibration, rectify your images.
Pass the images to your algorithm.
Get the disparity map.
Note: raw disparity map will be bad in a textureless region.

Type Error: The return type must be a string, dict, tuple, Response instance, or WSGI callable, but it was a list

I'm making a Flask App that would take an image input ,process it and save the results in a JSON file,but after processing the image it gives me a Type Error mentioned in the title.To add more,it prints only one line and then stops;
Below is my Flask API that I'm using;
#app.route('/upload',methods=['GET','POST'])
def upload_analyze():
if request.method == 'POST':
# check if a file was passed into the POST request
if 'file' not in request.files:
flash('No file was uploaded.')
return redirect(request.url)
f = request.files['file']
filename = secure_filename(f.filename)
f.save(filename)
image = cv2.imread(filename)
#f.save(secure_filename(f.filename))
#return 'file uploaded successfully'
# image_file = request.files['image']
clt = KMeans(n_clusters = 3)
dataset = pd.read_csv('bb22.csv')
X = dataset.iloc[:, 1: 8].values
sc = StandardScaler()
global orig , r
# load the image, convert it to grayscale, and blur it slightly
#images = np.array(Image.open(image_file))
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (7, 7), 0)
# perform edge detection, then perform a dilation + erosion to
# close gaps in between object edges
edged = cv2.Canny(gray, 50, 100)
edged = cv2.dilate(edged, None, iterations=1)
edged = cv2.erode(edged, None, iterations=1)
# find contours in the edge map
cnts = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if imutils.is_cv2() else cnts[1]
# sort the contours from left-to-right and initialize the
# 'pixels per metric' calibration variable
(cnts, _) = contours.sort_contours(cnts)
pixelsPerMetric = None
object_num = 0
r=object_num
objects = []
idx=0
orig = image.copy()
counter = 0
leng = [0] * 400
width = [0] *400
# loop over the contours individually
for c in cnts:
# if the contour is not sufficiently large, ignore it
if cv2.contourArea(c) < 50:
continue
# compute the rotated bounding box of the contour
box = cv2.minAreaRect(c)
box = cv2.cv.BoxPoints(box) if imutils.is_cv2() else cv2.boxPoints(box)
box = np.array(box, dtype="int")
# order the points in the contour such that they appear
# in top-left, top-right, bottom-right, and bottom-left
# order, then draw the outline of the rotated bounding box
box = perspective.order_points(box)
cv2.drawContours(orig, [box.astype("int")], -1, (0, 255, 0), 2)
box.astype
# unpack the ordered bounding box, then compute the midpoint
# between the top-left and top-right coordinates, followed by
# the midpoint between bottom-left and bottom-right coordinates
(tl, tr, br, bl) = box
(tltrX, tltrY) = midpoint(tl, tr)
(blbrX, blbrY) = midpoint(bl, br)
# compute the midpoint between the top-left and top-right points,
# followed by the midpoint between the top-righ and bottom-right
(tlblX, tlblY) = midpoint(tl, bl)
(trbrX, trbrY) = midpoint(tr, br)
# compute the Euclidean distance between the midpoints
dA = dist.euclidean((tltrX, tltrY), (blbrX, blbrY))
dB = dist.euclidean((tlblX, tlblY), (trbrX, trbrY))
# if the pixels per metric has not been initialized, then
# compute it as the ratio of pixels to supplied metric (in this case, inches)
if pixelsPerMetric is None:
pixelsPerMetric = dB / 22.599 #previously its /22.50
# compute the size of the object
area = round(cv2.contourArea(c) / (pixelsPerMetric**2), 3)
perimeter = round(cv2.arcLength(c, True)/ pixelsPerMetric, 3)
hull = cv2.convexHull(c)
hull_area = round(cv2.contourArea(hull) / (pixelsPerMetric**2), 3)
(x,y),(ma,MA),angle = cv2.fitEllipse(c)
eccentricity = round(np.sqrt(1-(ma/MA)**2),3)
C = round(4*np.pi*area/perimeter**2, 3)
dimA = round(dA / pixelsPerMetric, 3)
dimB = round(dB / pixelsPerMetric, 3)
if (dimA >= dimB):
temp=dimA
dimA=dimB
dimB=temp
leng[counter] = str(dimB)
width[counter] = str(dimA)
counter = counter +1
x,y,w,h = cv2.boundingRect(c)
idx+=1
mask = np.zeros(image.shape[:2],np.uint8)
cv2.drawContours(mask, [c],-1, 255, -1)
dst = cv2.bitwise_and(image, image, mask=mask)
new_img=dst[y-20:y+h+20,x-20:x+w+20]
# pre-process the image for classification
if len(new_img) == 0:
WB = 0
continue
object_num = object_num+1
image1 = cv2.cvtColor(new_img, cv2.COLOR_BGR2RGB)
image1 = new_img.reshape((image1.shape[0] * new_img.shape[1], 3))
#classify color
clt.fit(image1)
count = 0
global dominant_color
dominant_color = [0,0,0]
for (color) in (clt.cluster_centers_):
a = [color.astype("uint8").tolist()[0], color.astype("uint8").tolist()[1],
color.astype("uint8").tolist()[2]]
count = count+1
if(count == 2) and (a != [0, 0, 0]):
dominant_color = a
#prepare image for broken classification
new_img = cv2.resize(new_img, (64, 64))
new_img = new_img.astype("float") / 255.0
new_img = img_to_array(new_img)
new_img = np.expand_dims(new_img, axis=0)
# classify the input image
with graph.as_default():
(yes, no) = model.predict(new_img)[0]
# build the label
if (yes > no):
WB = 0
y_new = "Broken"
else:
if object_num == 1:
print("true")
continue
WB = 1
X_new = array([[dimA, dimB, area, perimeter, hull_area, eccentricity, C]])
X=sc.fit_transform(X)
X_new = sc.transform(X_new)
y_new = type_model.predict(X_new)
print("X=%s, Predicted=%s" % (X_new[0], y_new))
obj_num=object_num-1 # because one item on the left most side we have for the pixel constant value
content = {
"Object_number": obj_num,
"Width": dimA,
"Length": dimB,
#"Area": area,
#"Perimeter": perimeter,
#"hull_area": hull_area,
#"eccentricity": eccentricity,
#"compactness": C,
"WB": WB # Whole or Broken
#"Type": str(y_new[0]),
#"color_rgb": dominant_color,
#"color_hex": rgb2hex(dominant_color[2], dominant_color[1], dominant_color[0])
}
objects.append(content)
return(objects)
objects=analyze()
with open('test6.json', 'w') as fout:
json.dump(objects , fout)
print(objects)
print(type(objects))
return 'ok'
Also in console only this 1 line gets printed:
X=[ 0.38739663 -0.25583995 0.22674784 -0.2933872 0.19980647 -0.03758974
0.4759277 ], Predicted=[4]
I'm returning this message to make sure that the JSON file is created but it doesn't gets created..I can't figure out what is wrong with the return type ..kindly help.
The views in Flask require a hashable return type. You can always convert your return values to hashable types viz string, dict, tuple etc and then transform from the result.
return { "data": [ { "name": "my name", age: "27" } ] }
User oz19 commented
You need to serialize objects before returning. import json and then json.dumps(objects)
and also
You have a return(objects) at the end of for c in cnts. That could be the problem
So the solution if, not using jsonify, is to call json.dumps on the list before returning it.
If you are using this below method, you can easily get required data in json format
# don't forgot to import jsonify
from flask import Flask, request, redirect, jsonify
#app.route('/sample', methods = ['GET', 'POST'])
def sample():
if(request.method == 'GET'): # i am using get you can change whatever you want
data = [{"A": "a",
"B": "b",
"C": "c",
}]
return jsonify({'data': data})
# now you can start your json dumping process here after
Hope it helps!

Categories

Resources