Related
I'm codiing an application that moves a ServoMotor according to the license plate identification, and it will only close the gate if the sensor distance is greater than 120! The code recognizes the board, turns the motor, but when it goes to capture the sensor to validate if it can turn the motor again, it is giving the following error:
Traceback (most recent call last):
File "C:/Users/Star/Desktop/Arquivos Programação Phyton/TCC/app.py", line 48, in <module>
reconhecePlaca()
File "C:/Users/Star/Desktop/Arquivos Programação Phyton/TCC/app.py", line 32, in reconhecePlaca
if(UNO.Sensor().capturaSensor() == True):
File "C:\Users\Star\Desktop\Arquivos Programação Phyton\TCC\arduino.py", line 43, in __init__
Config.__init__(self)
File "C:\Users\Star\Desktop\Arquivos Programação Phyton\TCC\arduino.py", line 10, in __init__
self.board = pymata4.Pymata4()
File "C:\Users\Star\anaconda3\envs\Py38\lib\site-packages\pymata4\pymata4.py", line 235, in __init__
self._find_arduino()
File "C:\Users\Star\anaconda3\envs\Py38\lib\site-packages\pymata4\pymata4.py", line 404, in _find_arduino
raise RuntimeError(f'arduino_instance_id does not match '
RuntimeError: arduino_instance_id does not match a value on the boards.
These are my main classes:
import time
import cv2
import processamento_img as pi
import reconhecimento_caracter as rc
import arduino as UNO
def reconhecePlaca():
# portao = UNO.Portao()
# sensor = UNO.Sensor()
reconhece_caracter = rc.Reconhece()
webcam = cv2.VideoCapture(0)
if webcam.isOpened():
validacao, frame = webcam.read()
while validacao:
validacao, frame = webcam.read()
conts = pi.encontrar_contornos(pi.preProcessamentoContornos(frame))
for c in conts:
peri = cv2.arcLength(c, True)
if peri > 120:
aprox = cv2.approxPolyDP(c, 0.03 * peri, True)
if len(aprox) == 4:
(x, y, alt, larg) = cv2.boundingRect(c)
cv2.rectangle(frame, (x, y), (x + alt, y + larg), (0, 255, 0), 2)
roi = frame[y + 3:(y + larg) - 3, x + 5:(x + alt) - 5]
pi.preProcessamentoPlaca(roi)
if (reconhece_caracter.validaPlaca()):
UNO.Portao().abrePortao()
#print('reconheceu')
time.sleep(4)
if(UNO.Sensor().capturaSensor() == True):
time.sleep(3)
UNO.Portao().fechaPortao()
else:
print("SINAL NÃO ABRE PORTÃO")
cv2.imshow("SmartEntry", frame)
key = cv2.waitKey(50)
if key == 27:
break
webcam.release()
cv2.destroyAllWindows()
if __name__ == "__main__":
reconhecePlaca()
Class that controls Arduino:
import sys
from pymata4 import pymata4
import time
class Config():
def __init__(self):
self.pin = 7
self.triggerPin = 11
self.echoPin = 12
self.board = pymata4.Pymata4()
self.board.set_pin_mode_servo(self.pin)
self.i = 0
self.distance = 0
class Portao(Config):
def __init__(self):
Config.__init__(self)
def rotateServo(self, angle):
self.board.servo_write(self.pin, angle)
time.sleep(0.003)
def abrePortao(self):
try:
for i in range(self.i, 180):
self.rotateServo(i)
except KeyboardInterrupt:
self.board.shutdown()
sys.exit(0)
def fechaPortao(self):
try:
for i in range(180, 1, -1):
self.rotateServo(i)
except KeyboardInterrupt:
self.board.shutdown()
sys.exit()
class Sensor(Config):
def __init__(self):
Config.__init__(self)
def the_callback(self, data):
self.distance = data[2]
def capturaSensor(self):
self.board.set_pin_mode_sonar(self.triggerPin, self.echoPin, self.the_callback)
while(self.distance <= 120):
try:
time.sleep(2)
self.board.sonar_read(self.triggerPin)
except Exception:
self.board.shutdown()
if(self.distance > 120):
return True
I'm Brazilian, here are some terms in the code to make your life easier:
Portao = Gate
Sensor = Sensor
abrePortao = openGate
fechaPortao = closeGate
capturaSensor = captureSensor
This is my code, i know its long and messy code, but basically. At start its pretty fast and stuff, but after while you can notice really huge performance jumps, after 6 hours, i came back. and one click of keyboard button took like 10 seconds, can anybody help me find why is it slowing so much.
If you dont understand the code because i know its very messy and no comments. Its basically while loop that runs arround pressings buttons, and when it encounters pokemon, it reads its name and if its the one i want, it notifies me. Or if it errors, it notifies me too.
If i dont want it, it kills it
while active:
gc.collect()
gc.collect()
gc.collect()
time.sleep(0.1)
def waitclick():
while True:
if keyboard.read_key() == "f6":
global active
active = False
thread = threading.Thread(target=waitclick).start()
im = numpy.asarray(pyautogui.screenshot(region=hpcheck))
# Define the blue colour we want to find - remember OpenCV uses BGR ordering
color = [175, 65, 63]
X, Y = numpy.where(numpy.all(im == color, axis=2))
x = list(X)
if lenght:
cnt = 0
if len(x) <= lenght * (3 / 4):
while len(x) <= lenght* (5 / 6):
if cnt > 20:
pyautogui.click(2119, 793)
pyautogui.keyDown('4')
time.sleep(0.01)
pyautogui.keyUp('4')
pyautogui.click(2050, 1120)
pyautogui.click(1720, 1030)
break
cnt += 1
time.sleep(1)
pyautogui.moveTo(potion[0],potion[1], random.uniform(0.5,1))
pyautogui.click(potion[0],potion[1])
time.sleep(0.01)
pyautogui.click(potion[0],potion[1])
time.sleep(0.1)
pyautogui.moveTo(mainpoke[0],mainpoke[1],random.uniform(0.5,1))
pyautogui.click(mainpoke[0],mainpoke[1])
pyautogui.click(mainpoke[0], mainpoke[1])
im = Image.fromarray(im)
im.save("health.png")
im.close()
im = numpy.asarray(pyautogui.screenshot(region=(hpcheck)))
# Define the blue colour we want to find - remember OpenCV uses BGR ordering
color = [175, 65, 63]
X, Y = numpy.where(numpy.all(im == color, axis=2))
x = list(X)
lenght = len(x)
else:
lenght = len(x)
key = keys[0] if steps % 2 == 0 else keys[1]
pyautogui.keyDown(key)
pixels = []
battle = False
timeup = False
def wait():
global stepsleft
global steps
global battle
counter = 0
for i in range(stepsleft):
if battle:
break
counter += 1
time.sleep(onetile-(random.uniform(0.001,0.002)))
stepsleft = stepsleft - counter
if stepsleft == 0:
steps += 1
stepsleft = tiles
global timeup
timeup = True
thread = threading.Thread(target=wait).start()
while True:
if timeup:
break
im = numpy.asarray(pyautogui.screenshot(region=(check)))
if list(im[0, 0]) == [230, 230, 230]:
battle = True
break
pyautogui.keyUp(key)
stepcount += 1
im = numpy.asarray(pyautogui.screenshot(region=(check)))
# im = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
if stepcount > 15:
if fails > 100:
call = client.calls.create(twiml='<Response><Say>Ahoy, World!</Say></Response>',
to='+421949847318', from_='+18596961895')
payload = {
"content": f"Step Fail, continuing."
}
r = requests.post(f"https://discord.com/api/v9/channels/{channel_id}/messages",
data=payload,
headers=header)
gc.collect()
fails = 0
stepfails += 1
if stepfails > 10:
break
pyautogui.click(2119, 793)
pyautogui.keyDown('4')
time.sleep(0.01)
pyautogui.keyUp('4')
pyautogui.click(2050,1120)
pyautogui.click(1720, 1030)
time.sleep(1)
fails += 1
if battle == True:
breaks += 1
stepcount = 0
c = 0
e = False
while True:
if c > 600:
e = True
break
else:
im = numpy.asarray(pyautogui.screenshot(region=(namecheck)))
if list(im[0, 0]) == [254, 254, 254]:
break
c += 1
if e:
pyautogui.keyDown('4')
time.sleep(0.01)
pyautogui.keyUp('4')
pyautogui.click(2050, 1120)
time.sleep(1)
else:
encounters += 1
im = numpy.asarray(pyautogui.screenshot(region=(mon)))
im = cv2.resize(im, None, fx=1.2, fy=1.2, interpolation=cv2.INTER_CUBIC)
im = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
kernel = numpy.ones((1, 1), numpy.uint8)
im = cv2.threshold(cv2.bilateralFilter(im, 5, 75, 75), 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
im = cv2.dilate(im, kernel, iterations=1)
im = cv2.erode(im, kernel, iterations=1)
im = ~im
text = pytesseract.image_to_string(im)
text = text.strip().replace("\n","")
ime = Image.fromarray(im)
ime.save(f"Wild {text}.png")
ime.close()
if text == "":
ime = Image.fromarray(im)
ime.save("fail.png")
ime.close()
im = numpy.asarray(pyautogui.screenshot(region=(mon)))
im = cv2.resize(im, None, fx=1.6, fy=1.6, interpolation=cv2.INTER_CUBIC)
im = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
kernel = numpy.ones((1, 1), numpy.uint8)
im = cv2.threshold(cv2.bilateralFilter(im, 5, 75, 75), 0, 255,
cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
im = cv2.dilate(im, kernel, iterations=1)
im = cv2.erode(im, kernel, iterations=1)
im = ~im
text = pytesseract.image_to_string(im).strip()
print(">" + text + "<")
if text == "":
ime = Image.fromarray(im)
ime.save("fail2.png")
ime.close()
im = numpy.asarray(pyautogui.screenshot(region=mon))
print(">" + text + "<")
im = cv2.resize(im, None, fx=2, fy=2, interpolation=cv2.INTER_CUBIC)
im = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
kernel = numpy.ones((1, 1), numpy.uint8)
im = cv2.threshold(cv2.bilateralFilter(im, 5, 75, 75), 0, 255,
cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
im = cv2.dilate(im, kernel, iterations=1)
im = cv2.erode(im, kernel, iterations=1)
im = ~im
text = pytesseract.image_to_string(im).strip()
if text == "":
im = numpy.asarray(pyautogui.screenshot(region=check))
if list(im[0, 0]) != [230, 230, 230]:
pass
else:
Image.fromarray(im)
ime.save("fail3.png")
ime.close()
print(">" + text + "<")
payload = {
"content": f"Go look at this bro, i failed again."
}
r = requests.post(f"https://discord.com/api/v9/channels/{channel_id}/messages", data=payload,
headers=header)
active = False
call = client.calls.create(twiml='<Response><Say>Ahoy, World!</Say></Response>',
to='+421949847318', from_='+18596961895')
gc.collect()
break
if text.replace("[S]","").replace("[E]","").replace("\n","") not in pokemonlist:
ime = Image.fromarray(im)
ime.save("fail.png")
ime.close()
im = numpy.asarray(pyautogui.screenshot(region=mon))
im = cv2.resize(im, None, fx=1.6, fy=1.6, interpolation=cv2.INTER_CUBIC)
im = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
kernel = numpy.ones((1, 1), numpy.uint8)
im = cv2.threshold(cv2.bilateralFilter(im, 5, 75, 75), 0, 255,
cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
im = cv2.dilate(im, kernel, iterations=1)
im = cv2.erode(im, kernel, iterations=1)
im = ~im
text = pytesseract.image_to_string(im).strip().replace("\n","")
print(">" + text + "<")
if text.replace("[S]","").replace("\n","").replace("[E]","") not in pokemonlist:
ime = Image.fromarray(im)
ime.save("fail2.png")
ime.close()
im = numpy.asarray(pyautogui.screenshot(region=mon))
im = cv2.resize(im, None, fx=2, fy=2, interpolation=cv2.INTER_CUBIC)
im = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
kernel = numpy.ones((1, 1), numpy.uint8)
im = cv2.threshold(cv2.bilateralFilter(im, 5, 75, 75), 0, 255,
cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
im = cv2.dilate(im, kernel, iterations=1)
im = cv2.erode(im, kernel, iterations=1)
im = ~im
text = pytesseract.image_to_string(im).strip()
print(">" + text + "<")
if text.replace("[S]","").replace("\n","").replace("[E]","") not in pokemonlist:
ime = Image.fromarray(im)
ime.save("fail3.png")
ime.close()
print(">" + text + "<")
payload = {
"content": f"Go look at this bro, i failed again."
}
r = requests.post(f"https://discord.com/api/v9/channels/{channel_id}/messages", data=payload,
headers=header)
active = False
call = client.calls.create(twiml='<Response><Say>Ahoy, World!</Say></Response>',
to='+421949847318', from_='+18596961895')
gc.collect()
break
encounter_time = datetime.datetime.utcnow()
times.append(encounter_time)
if not ram or encounters < 5:
ram = process.memory_info().rss
if encounters < 15:
recentspeed = "None yet"
else:
recentspeed = str(round(
(15 / (encounter_time - times[encounters - 15]).total_seconds()) * 60, 2)) + "/min"
print(
f"Pokemon: {text} #{encounters}\nSpeed: {round((encounters / (encounter_time - start).total_seconds()) * 60, 2)}/min \nRecent Speed: {recentspeed}\nRam usage is {process.memory_info().rss} Starting usage was {process.memory_info().rss-ram} Garbage is {gc.get_count()}")
payload = {
"content": f"{'-'*20}\nPokemon: {text} #{encounters}\nSpeed: {round((encounters / (encounter_time - start).total_seconds()) * 60, 2)}/min \nRecent Speed: {recentspeed}\n Ram Change: `{(process.memory_info().rss-ram)//1000000}MB`\nRam usage: `{process.memory_info().rss//1000000}MB`\nStarting usage: `{ram//1000000}MB`\nGarbage: {gc.get_count()}\nCPU: {psutil.cpu_percent()}"
}
r = requests.post(f"https://discord.com/api/v9/channels/{logs_id}/messages", data=payload,
headers=header)
gc.collect()
#json
with open("encounters.json", "r") as a_file:
json_object = json.load(a_file)
a_file.close()
try:
json_object[text] += 1
except:
json_object[text] = 1
with open("encounters.json", "w") as a_file:
json.dump(json_object, a_file)
a_file.close()
c = 0
e = False
while True:
if c > 500:
pyautogui.click(2119, 793)
pyautogui.keyDown('4')
time.sleep(0.01)
pyautogui.keyUp('4')
pyautogui.click(2050, 1120)
pyautogui.click(1720, 1030)
time.sleep(1)
e = True
break
im = numpy.asarray(pyautogui.screenshot(region=battlecheck))
if list(im[0, 0]) == [240, 211, 92]:
break
c += 1
if e == True:
continue
if (text.startswith("[S]") if shinies else text.replace("[E]","") in shinywanted) or text.replace("[S]","").replace("[E]","") in wanted:
time.sleep(2)
end = datetime.datetime.utcnow()
done = end - start
timed = humanize.naturaldelta(done)
print("Done! in " + timed)
im = numpy.asarray(pyautogui.screenshot(region=win))
ime = Image.fromarray(im)
ime.save(f"{text}.png")
ime.close()
# File
files = {
"file": (f"{text}.png", open(f"{text}.png", 'rb'))
# The picture that we want to send in binary
}
# Optional message to send with the picture
payload = {
"content": f"Found {text} in {timed} of searching. It took {encounters} encounters"
}
active = False
r = requests.post(f"https://discord.com/api/v9/channels/{channel_id}/messages", data=payload,
headers=header, files=files)
gc.collect()
call = client.calls.create(twiml='<Response><Say>Ahoy, World!</Say></Response>',to='+421949847318',from_='+18596961895')
time.sleep(25)
if remote:
pyautogui.click(3804, 15)
break
playsound('ringtone.mp3')
elif text.startswith("[E]") or text.replace("[S]","").replace("[E]","") in avoid:
run()
c = 0
while True:
if c > 300:
pyautogui.click(2119, 793)
pyautogui.click(1720, 1030)
pyautogui.keyDown('4')
time.sleep(0.01)
pyautogui.keyUp('4')
pyautogui.click(2050, 1120)
time.sleep(1)
break
else:
im = numpy.asarray(pyautogui.screenshot(region=check))
if list(im[0, 0]) != [230, 230, 230]:
break
c += 1
else:
#time.sleep(random.randint(50, 70) / 100)
kill(text.replace("[S]","").replace("[E]",""))
c = 0
time.sleep(1)
while True:
if c > 750:
pyautogui.click(2119, 793)
pyautogui.click(1720, 1030)
pyautogui.keyDown('4')
time.sleep(0.01)
pyautogui.keyUp('4')
pyautogui.click(2050, 1120)
time.sleep(1)
break
else:
im = numpy.asarray(pyautogui.screenshot(region=check))
if list(im[0, 0]) != [230, 230, 230]:
break
c += 1
The code is barely legible, split it in functions or classes, and avoid global variables. Chances are you are overflowing the RAM of your computer or something like that, if you are appending information to a variable, remember deleting it after if it grows to much or storing it in a database-like system.
Something similar (or worst) applies to threads if you create too many without deleting them at some point.
I understand that it would be much simpler to just train YOLOv4 accordingly but:
I have limited computational resources and was hoping I could combine pre-trained models I found online, saving my time, or train a model and combine it with other models available online.
If I have one '.weights' file of a custom object detector that detects traffic signs and another '.weights' file of detector that detect pedestrians. Is there a way to combine these models, so that when run on a video/image (or in real-time capture), it detects pedestrians and traffic signs simultaneously.
By combining I mean, either to edit the 'weights' file somehow to achieve this, or editing the python code (while running the detector) that gets this done. (or any other way)
If not possible - is there any way to make them run in a sequence, efficiently?
Yes, It is possible to do that. Create two different python files and load the model in them. Then create a new file and initialise both of them in the new file. Then take the continous video / image feed as an input, the file will give output of detected traffic signs. Use this output as an input to your pedestrian problem.
import numpy as np
import pandas as pd
import cv2
import time
margin = 20
import detection_cls
run = detection_cls.Ppe_Detection_1()
class Ppe_Detection():
def __init__(self):
self.weightfile = 'yolov4_pretrained.weights'
self.cfgfile = 'cfg/yolov4_pretrained.cfg'
self.PpeNet = cv2.dnn.readNet(self.weightfile,self.cfgfile)
self.classes = self.get_classes()
layer_names = self.PpeNet.getLayerNames()
self.output_layers = [layer_names[i - 1] for i in self.PpeNet.getUnconnectedOutLayers()]
# = [self.PpeNet.getLayerNames()[(i[0] - 1)] for i in self.PpeNet.getUnconnectedOutLayers()]
def get_classes(self):
# self.classes = []
with open("coco.names","r") as f:
self.classes_val = [line.strip() for line in f.readlines()]
return self.classes_val
def detection(self,img):
start = time.perf_counter()
height,width,channels = img.shape
# Detecting objects
blob = cv2.dnn.blobFromImage(img,0.00392,(416,416),(0,0,0),True,crop=False)
self.PpeNet.setInput(blob)
outs = self.PpeNet.forward(self.output_layers)
time_took = time.perf_counter() - start
fps = str(int(1/time_took))
# getting the list
class_ids = []
confidences = []
boxes = []
for out in outs:
for detection in out:
# print(detection)
scores = detection[5:]
class_id = np.argmax(scores)
confidence = scores[class_id]
if confidence > 0.4:
# object detected
center_x = int(detection[0]*width)
center_y = int(detection[1]*height)
w = int(detection[2]*width)
h = int(detection[3]*height)
# Rectangle Coordinates
x = int(center_x-w/2)
y = int(center_y-h/2)
boxes.append([x,y,w,h])
confidences.append(float(confidence))
class_ids.append(class_id)
indexes = cv2.dnn.NMSBoxes(boxes,confidences,0.4,0.4)
info = []
if len(indexes) > 0:
for i in indexes.flatten():
x,y = boxes[i][0], boxes[i][1]
w,h = boxes[i][2], boxes[i][3]
conf = confidences[i]
if x<0:
x = 0
if y < 0:
y = 0
type = '{}'.format(self.classes[class_ids[i]])
info.append([x,y,w,h,type,conf])
new_frame_time = time.time()
font = cv2.FONT_HERSHEY_PLAIN
for i in range(len(boxes)):
for i in indexes:
x,y,w,h = boxes[i]
label = str(self.classes[class_ids[i]])
color = (0,0,145)
# cv2.rectangle(img,(x,y),(x+w,y+h),color,2)
cv2.putText(img,fps,(10,30),font,3,color,3)
cv2.putText(img,label,(x,y+30),font,3,color,3)
# print(boxes,confidences,class_ids)
# print("opened")
# print(info)
return info
def cropping_detection(self):
count = 0
cropped_frame = []
value_img = []
cap = cv2.VideoCapture(0)
while cap.isOpened():
r,f = cap.read()
# counts +=1
detection = ppe.detection(f)
try:
x,y,w,h,cls,conf = detection[0]
except Exception as e:
pass
# for i in range(len(detection)):
# print(detection[i])
try:
if cls=='person':
print("Person detected")
cropped_img = f[y-margin:y+h+margin,x-margin:x+w+margin]
# print(cropped_img)
# value = ppe.detection(cropped_img)
final = run.detection(cropped_img)
print('final',final)
# print(value)
# print(cropped_img)
# value_img.append(value)
# cropped_frame.append(cropped_img)
# cv2.imwrite("data/frame%d.jpg" % count, cropped_img)
cv2.imshow("Hi",cropped_img)
if cv2.waitKey(1) & 0xff==ord('q'):
break
# count += 1
else:
pass
except Exception as e:
print("In except part")
# cap.release()
# cv2.destroyAllWindows()
# print(cropped_img)
return value,cropped_img
ppe = Ppe_Detection()
ppe.cropping_detection()
# ppe.get_classes()
# ppe.run_video()
# take_photo()
# inference_image()
The function that I've imported here can be found below
import numpy as np
import pandas as pd
import cv2
import time
class Ppe_Detection():
def __init__(self):
self.weightfile = 'backup/yolov3_best.weights'
self.cfgfile = 'yolov3.cfg'
self.PpeNet = cv2.dnn.readNet(self.weightfile,self.cfgfile)
self.classes = self.get_classes()
layer_names = self.PpeNet.getLayerNames()
self.output_layers = [layer_names[i - 1] for i in self.PpeNet.getUnconnectedOutLayers()]
# = [self.PpeNet.getLayerNames()[(i[0] - 1)] for i in self.PpeNet.getUnconnectedOutLayers()]
def get_classes(self):
# self.classes = []
with open("obj.names","r") as f:
self.classes_val = [line.strip() for line in f.readlines()]
return self.classes_val
def print_all(self):
print(self.classes)
def detection(self,img):
start = time.perf_counter()
height,width,channels = img.shape
# Detecting objects
blob = cv2.dnn.blobFromImage(img,0.00392,(416,416),(0,0,0),True,crop=False)
self.PpeNet.setInput(blob)
outs = self.PpeNet.forward(self.output_layers)
time_took = time.perf_counter() - start
fps = str(int(1/time_took))
# getting the list
class_ids = []
confidences = []
boxes = []
for out in outs:
for detection in out:
scores = detection[5:]
class_id = np.argmax(scores)
confidence = scores[class_id]
if confidence > 0.4:
# object detected
center_x = int(detection[0]*width)
center_y = int(detection[1]*width)
w = int(detection[2]*width)
h = int(detection[3]*height)
# Rectangle Coordinates
x = int(center_x-w/2)
y = int(center_y-h/2)
boxes.append([x,y,w,h])
confidences.append(float(confidence))
class_ids.append(class_id)
indexes = cv2.dnn.NMSBoxes(boxes,confidences,0.4,0.4)
info = []
if len(indexes) > 0:
for i in indexes.flatten():
x,y = boxes[i][0], boxes[i][1]
w,h = boxes[i][2], boxes[i][3]
conf = confidences[i]
if x<0:
x = 0
if y < 0:
y = 0
type = '{}'.format(self.classes[class_ids[i]])
info.append([x,y,w,h,type,conf])
new_frame_time = time.time()
font = cv2.FONT_HERSHEY_PLAIN
for i in range(len(boxes)):
for i in indexes:
x,y,w,h = boxes[i]
label = str(self.classes[class_ids[i]])
color = (0,255,145)
cv2.rectangle(img,(x,y),(x+w,y+h),color,2)
cv2.putText(img,fps,(10,30),font,3,color,3)
cv2.putText(img,label,(x,y+30),font,3,color,3)
# print(boxes,confidences,class_ids)
# print("opened")
print(info)
return info
ppe = Ppe_Detection()
ppe.get_classes()
ppe.print_all()
#############
def inference_image():
img = cv2.imread("sumit_off.jpg")
ppe.detection(img)
cv2.imshow("Image",img)
cv2.waitKey(0)
cv2.destroyAllWindows()
def run_video():
cap = cv2.VideoCapture(0)
while cap.isOpened():
r,f = cap.read()
try:
info = ppe.detection(f)
except Exception as e:
print("______",e)
cv2.imshow("image",f)
if cv2.waitKey(1) & 0xFF == ord("q") :
break
cap.release()
cv2.destroyAllWindows()
run_video()
I wanted to find out how the video frame length was calculated in the below code.
[UPD] Before I was thinking it was done by Yolo, but later I realized it was OpenCV that dealt with number of frames in a video file.
"""
Class definition of YOLO_v3 style detection model on image and video
"""
import colorsys
import os
from timeit import default_timer as timer
import numpy as np
from keras import backend as K
from keras.models import load_model
from keras.layers import Input
from PIL import Image, ImageFont, ImageDraw
from yolo3.model import yolo_eval, yolo_body, tiny_yolo_body
from yolo3.utils import letterbox_image
import os
from keras.utils import multi_gpu_model
class YOLO(object):
_defaults = {
"model_path": 'model_data/yolo.h5',
"anchors_path": 'model_data/yolo_anchors.txt',
"classes_path": 'model_data/coco_classes.txt',
"score" : 0.3,
"iou" : 0.45,
"model_image_size" : (416, 416),
"gpu_num" : 1,
}
#classmethod
def get_defaults(cls, n):
if n in cls._defaults:
return cls._defaults[n]
else:
return "Unrecognized attribute name '" + n + "'"
def __init__(self, **kwargs):
self.__dict__.update(self._defaults) # set up default values
self.__dict__.update(kwargs) # and update with user overrides
self.class_names = self._get_class()
self.anchors = self._get_anchors()
self.sess = K.get_session()
self.boxes, self.scores, self.classes = self.generate()
def _get_class(self):
classes_path = os.path.expanduser(self.classes_path)
with open(classes_path) as f:
class_names = f.readlines()
class_names = [c.strip() for c in class_names]
return class_names
def _get_anchors(self):
anchors_path = os.path.expanduser(self.anchors_path)
with open(anchors_path) as f:
anchors = f.readline()
anchors = [float(x) for x in anchors.split(',')]
return np.array(anchors).reshape(-1, 2)
def generate(self):
model_path = os.path.expanduser(self.model_path)
assert model_path.endswith('.h5'), 'weights must be a .h5 file.'
# Load model, or construct model and load weights.
num_anchors = len(self.anchors)
num_classes = len(self.class_names)
is_tiny_version = num_anchors==6 # default setting
try:
self.yolo_model = load_model(model_path, compile=False)
except:
self.yolo_model = tiny_yolo_body(Input(shape=(None,None,3)), num_anchors//2, num_classes) \
if is_tiny_version else yolo_body(Input(shape=(None,None,3)), num_anchors//3, num_classes)
self.yolo_model.load_weights(self.model_path) # make sure model, anchors and classes match
else:
assert self.yolo_model.layers[-1].output_shape[-1] == \
num_anchors/len(self.yolo_model.output) * (num_classes + 5), \
'Mismatch between model and given anchor and class sizes'
print('{} model, anchors, and classes loaded.'.format(model_path))
# Generate colors for drawing bounding boxes.
hsv_tuples = [(x / len(self.class_names), 1., 1.)
for x in range(len(self.class_names))]
self.colors = list(map(lambda x: colorsys.hsv_to_rgb(*x), hsv_tuples))
self.colors = list(
map(lambda x: (int(x[0] * 255), int(x[1] * 255), int(x[2] * 255)),
self.colors))
np.random.seed(10101) # Fixed seed for consistent colors across runs.
np.random.shuffle(self.colors) # Shuffle colors to decorrelate adjacent classes.
np.random.seed(None) # Reset seed to default.
# Generate output tensor targets for filtered bounding boxes.
self.input_image_shape = K.placeholder(shape=(2, ))
if self.gpu_num>=2:
self.yolo_model = multi_gpu_model(self.yolo_model, gpus=self.gpu_num)
boxes, scores, classes = yolo_eval(self.yolo_model.output, self.anchors,
len(self.class_names), self.input_image_shape,
score_threshold=self.score, iou_threshold=self.iou)
return boxes, scores, classes
def detect_image(self, image):
start = timer()
if self.model_image_size != (None, None):
assert self.model_image_size[0]%32 == 0, 'Multiples of 32 required'
assert self.model_image_size[1]%32 == 0, 'Multiples of 32 required'
boxed_image = letterbox_image(image, tuple(reversed(self.model_image_size)))
else:
new_image_size = (image.width - (image.width % 32),
image.height - (image.height % 32))
boxed_image = letterbox_image(image, new_image_size)
image_data = np.array(boxed_image, dtype='float32')
print(image_data.shape)
image_data /= 255.
image_data = np.expand_dims(image_data, 0) # Add batch dimension.
out_boxes, out_scores, out_classes = self.sess.run(
[self.boxes, self.scores, self.classes],
feed_dict={
self.yolo_model.input: image_data,
self.input_image_shape: [image.size[1], image.size[0]],
K.learning_phase(): 0
})
print('Found {} boxes for {}'.format(len(out_boxes), 'img'))
font = ImageFont.truetype(font='font/FiraMono-Medium.otf',
size=np.floor(3e-2 * image.size[1] + 0.5).astype('int32'))
thickness = (image.size[0] + image.size[1]) // 300
for i, c in reversed(list(enumerate(out_classes))):
predicted_class = self.class_names[c]
box = out_boxes[i]
score = out_scores[i]
label = '{} {:.2f}'.format(predicted_class, score)
draw = ImageDraw.Draw(image)
label_size = draw.textsize(label, font)
top, left, bottom, right = box
top = max(0, np.floor(top + 0.5).astype('int32'))
left = max(0, np.floor(left + 0.5).astype('int32'))
bottom = min(image.size[1], np.floor(bottom + 0.5).astype('int32'))
right = min(image.size[0], np.floor(right + 0.5).astype('int32'))
print(label, (left, top), (right, bottom))
if top - label_size[1] >= 0:
text_origin = np.array([left, top - label_size[1]])
else:
text_origin = np.array([left, top + 1])
# My kingdom for a good redistributable image drawing library.
for i in range(thickness):
draw.rectangle(
[left + i, top + i, right - i, bottom - i],
outline=self.colors[c])
draw.rectangle(
[tuple(text_origin), tuple(text_origin + label_size)],
fill=self.colors[c])
draw.text(text_origin, label, fill=(0, 0, 0), font=font)
del draw
end = timer()
print(end - start)
return image
def close_session(self):
self.sess.close()
def detect_video(yolo, video_path, output_path=""):
import cv2
video_path = './input.mp4'
vid = cv2.VideoCapture(video_path)
if not vid.isOpened():
raise IOError("Couldn't open webcam or video")
video_FourCC = int(vid.get(cv2.CAP_PROP_FOURCC))
video_fps = vid.get(cv2.CAP_PROP_FPS)
video_size = (int(vid.get(cv2.CAP_PROP_FRAME_WIDTH)),
int(vid.get(cv2.CAP_PROP_FRAME_HEIGHT)))
isOutput = True if output_path != "" else False
if isOutput:
print("!!! TYPE:", type(output_path), type(video_FourCC), type(video_fps), type(video_size))
out = cv2.VideoWriter(output_path, video_FourCC, video_fps, video_size)
accum_time = 0
curr_fps = 0
fps = "FPS: ??"
prev_time = timer()
while True:
return_value, frame = vid.read()
image = Image.fromarray(frame)
image = yolo.detect_image(image)
result = np.asarray(image)
curr_time = timer()
exec_time = curr_time - prev_time
prev_time = curr_time
accum_time = accum_time + exec_time
curr_fps = curr_fps + 1
if accum_time == 10 : mouseBrush(image)
if accum_time > 1:
accum_time = accum_time - 1
fps = "FPS: " + str(curr_fps)
curr_fps = 0
cv2.putText(result, text=fps, org=(3, 15), fontFace=cv2.FONT_HERSHEY_SIMPLEX,
fontScale=0.50, color=(255, 0, 0), thickness=2)
cv2.namedWindow("result", cv2.WINDOW_NORMAL)
cv2.imshow("result", result)
if isOutput:
out.write(result)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
yolo.close_session()
Actually, this code is just one part of the all Yolo3 model, but I think the part that deals with the number of video frames is included here.
If you mean the current FPS. This is the part showing the current FPS in string.
while True:
return_value, frame = vid.read()
image = Image.fromarray(frame)
image = yolo.detect_image(image)
result = np.asarray(image)
curr_time = timer()
exec_time = curr_time - prev_time
prev_time = curr_time
accum_time = accum_time + exec_time
curr_fps = curr_fps + 1
if accum_time > 1:
accum_time = accum_time - 1
fps = "FPS: " + str(curr_fps)
curr_fps = 0
cv2.putText(result, text=fps, org=(3, 15), fontFace=cv2.FONT_HERSHEY_SIMPLEX,
fontScale=0.50, color=(255, 0, 0), thickness=2)
cv2.namedWindow("result", cv2.WINDOW_NORMAL)
cv2.imshow("result", result)
if curr_fps == 10: # Stops at 10th frame.
time.sleep(60) # Delay for 1 minute (60 seconds).
if isOutput:
out.write(result)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
I needed the frame number to control every 10th frame in the video file, and thanks to above comments, I figured out that the line I was looking for is:
curr_fps = curr_fps + 1
UPD: The following line calculated the number of frames in a video file.
NumberOfFrame = int(vid.get(cv2.CAP_PROP_FRAME_COUNT))
I've a problem with my software in Python. It's a big while cicle where I took a intel realsense (USB camera) stream. Using opencv I make a couple of findContours and I send the results of contours to another software.
The problem is that there is a memory consuption. In fact the RAM usage increase every 2-3 seconds by 0.1%.
II don't know what to do...
This is the code (sorry if it's not beautifull but I'm testing a lot of things)
import numpy as np
import random
import socket
import cv2
import time
import math
import pickle
import httplib, urllib
from xml.etree import ElementTree as ET
import logging
logging.basicConfig(level=logging.INFO)
try:
import pyrealsense as pyrs
except:
print("No pyralsense Module installed!")
#funzione per registrare gli eventi del mouse
def drawArea(event,x,y, flag, param):
global fx,fy,ix,iy
if event == cv2.EVENT_LBUTTONDOWN:
ix,iy = x,y
elif event == cv2.EVENT_LBUTTONUP:
fx,fy = x,y
def RepresentsInt(s):
try:
int(s)
return True
except ValueError:
return False
quit = False
read = False
while read == False:
file = open('default.xml', 'r')
tree = ET.parse(file)
root = tree.getroot()
for child in root:
if child.tag == "intel":
intel = int(child[0].text)
elif child.tag == "output":
portOut = int(child[2].text)
elif child.tag =="source":
video_source = child.text
file.close()
root.clear()
ix,iy = -1,-1
fx,fy = -1,-1
timeNP = 10
last = time.time()
smoothing = 0.9
fps_smooth = 30
#video_source = video_source.split(",")
read = True
if RepresentsInt(video_source):
video_source = int(video_source)
if intel == 1:
pyrs.start()
dev = pyrs.Device(video_source)
master = 1
address = ('', 3333)
broadSockListe = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
broadSockListe.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
broadSockListe.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
broadSockListe.bind(('',3333))
while True:
if master == 0:
datas, address = broadSockListe.recvfrom(1024)
if str(datas) == "8000":
separator = ":"
seq = (address[0],"8081")
masterAddr = separator.join(seq)
IP = str([l for l in (
[ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if not ip.startswith("127.")][:1], [
[(s.connect(('8.8.8.8', 53)), s.getsockname()[0], s.close()) for s in
[socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1]]) if l][0][0])
params = separator.join(("addUnit",IP,str(portOut),"camera","generalList.xml"))
params = urllib.urlencode({"Python":params})
headers = {}
conn = httplib.HTTPConnection(masterAddr)
conn.request("POST",masterAddr ,params, headers)
params = separator.join(("masterIP",address[0],str(portOut)+"/","default.xml"))
params = urllib.urlencode({"Python":params})
headers = {}
myip = IP + ":8081"
conn = httplib.HTTPConnection(myip)
#eseguo una post al mio server
conn.request("POST", myip, params, headers)
broadSockListe.close()
#imposto master a 1 per dire che l'ho registrato e posso partire col programma
master = 1
read = False
while read == False:
'''# leggo le varie impostazioni dal file default
file = open('default.xml','r+')
tree = ET.parse(file)
root = tree.getroot()
for child in root:
if child.tag == "modifica" and child.text == "1":
child.text = "0"
tree.write('default.xml')
root.clear()
file.close()'''
read = True
prev,prevprev,dirX,dirY = 0,0,0,0
spostamento = 15
UDP_IP = ["", ""]
UDP_PORT = ["", ""]
UDP_IP[0] = "127.0.0.1"
UDP_PORT[0] = 3030
IP_left = "127.0.0.1"
IP_right = "127.0.0.1"
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(("",portOut))
message = ""
sep = "-"
font = cv2.FONT_HERSHEY_SIMPLEX
kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (3, 3))
#rettangoli = [x,y,width,height,angle,box, area, contours]
rettangoli = []
cnt = 0
letto = 0
while True:
now = time.time()
if letto < now - 2 or letto == 0 or now < letto:
letto = now
print(now)
read = False
while read == False:
file = open('default.xml', 'r')
tree = ET.parse(file)
root = tree.getroot()
for child in root:
if child.tag == "output":
UDP_IP[1] = child[0].text
UDP_PORT[1] = int(child[1].text)
if child.tag == "effects":
erode = int(child[0].text)
erodePos = int(child[1].text)
erode2 = int(child[2].text)
erodePos2 = int(child[3].text)
dilate1 = int(child[4].text)
dilatePos1= int(child[5].text)
dilate2 = int(child[6].text)
dilatePos2 = int(child[7].text)
blur = int(child[8].text)
blurPos = int(child[9].text)
if child.tag == "intel":
val1Min = int(child[1].text)
val1Max = int(child[2].text)
val2Min = int(child[3].text)
val2Max = int(child[4].text)
val3Min = int(child[5].text)
val3Max = int(child[6].text)
if child.tag == "modifica":
if child.text == "1":
break
#definisco dimensioni per collisioni
if child.tag == "size":
blobSize= int(child[0].text)
dimBordoBlob= int(child[1].text)
if child.tag == "visualizza":
visualizza= child.text
if child.tag == "feedback":
SFB = int(child.text)
root.clear()
file.close()
read = True
dev.wait_for_frame()
c = dev.colour
c = cv2.cvtColor(c, cv2.COLOR_RGB2BGR)
d = dev.depth * dev.depth_scale * -60
d = d[5:485, 25:635]
d = cv2.applyColorMap(d.astype(np.uint8), cv2.COLORMAP_HSV)
c = cv2.resize(c, (320 ,240), interpolation=cv2.INTER_AREA)
d = cv2.resize(d, (320,240), interpolation=cv2.INTER_AREA)
#trasformo i colori in HSV per filtrarli
frame = cv2.cvtColor(d, cv2.COLOR_BGR2HSV)
lower_red = np.array([val1Min, val2Min, val3Min])
upper_red = np.array([val1Max, val2Max, val3Max])
frame = cv2.inRange(frame, lower_red, upper_red)
dimensions = frame.shape
widthStream = dimensions[1]
heightStream = dimensions[0]
roomFrame = np.zeros(( heightStream,widthStream, 3), np.uint8)
roomFrame[:] = (0, 0, 0)
fgmask = frame
halfheight = int(heightStream / 2)
halfwidth = int(widthStream / 2)
for i in range(0, 15):
if erode >= 1 and erodePos == i:
fgmask = cv2.erode(fgmask, kernel, iterations=erode)
if dilate1 >= 1 and dilatePos1 == i:
fgmask = cv2.dilate(fgmask, kernel, iterations=dilate1)
if erode2 >= 1 and erodePos2 == i:
fgmask = cv2.erode(fgmask, kernel, iterations=erode2)
if dilate2 >= 1 and dilatePos2 == i:
fgmask = cv2.dilate(fgmask, kernel, iterations=dilate2)
if blur == 1 and blurPos == 1:
fgmask = cv2.GaussianBlur(fgmask, (5, 5), 0)
if ix > fx:
temp = fx
fx = ix
ix = temp
if iy > fy:
temp = fy
fy = iy
iy = temp
if cnt == 0:
ix,iy = 1,1
fx,fy = widthStream-1,heightStream-1
fgmask, contours, hierarchy = cv2.findContours(fgmask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
rettangoli = []
for cont in contours:
rect = cv2.minAreaRect(cont)
box = cv2.boxPoints(rect)
box = np.int0(box)
width = rect[1][0]
height = rect[1][1]
angle = rect[2]
if width > height:
angle = 180 + angle
else:
angle = 270 + angle
x, y, w, h = cv2.boundingRect(cont)
centerX = int(w / 2 + x)
centerY = int(h / 2 + y)
M = cv2.moments(cont)
area = int(M['m00'])
if area > blobSize:
if ix < centerX < fx and iy < centerY < fy:
cv2.drawContours(fgmask, [cont], 0, (100, 100, 100), dimBordoBlob)
cv2.drawContours(fgmask, [cont], 0, (255, 255, 255), -1)
rettangoli.append([centerX, centerY, w, h, angle, box, area, cont])
indice = 0
fgmask, contours, hierarchy = cv2.findContours(fgmask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_TC89_KCOS)
if intel == 1:
fgmask = cv2.cvtColor(fgmask, cv2.COLOR_GRAY2RGB)
rettangoli = []
for cont in contours:
rect = cv2.minAreaRect(cont)
box = cv2.boxPoints(rect)
box = np.int0(box)
width = rect[1][0]
height = rect[1][1]
angle = rect[2]
if width > height:
angle = 180 + angle
else:
angle = 270 + angle
x, y, w, h = cv2.boundingRect(cont)
centerX = int(w / 2 + x)
centerY = int(h / 2 + y)
M = cv2.moments(cont)
indice += 1
if M['m00'] > blobSize:
if ix < centerX < fx and iy < centerY < fy:
rettangoli.append([centerX, centerY, w, h, angle, box, int(M['m00']), cont])
cv2.drawContours(roomFrame, [cont], 0, (255, 255, 255), -1)
for rett in rettangoli:
seq = (message,np.array_str(rett[7]))
message = sep.join(seq)
temp = 0
while temp < len(UDP_IP):
sock.sendto(bytes(message), (UDP_IP[temp], UDP_PORT[temp]))
temp += 1
message = ""
if SFB == 1:
cv2.imshow("Camera Intel", roomFrame)
if cv2.waitKey(1) & 0xFF == ord('r'):
break
if cv2.waitKey(1) & 0xFF == ord('q'):
quit = True
break
name = "color.jpeg"
cv2.imwrite(name, c)
name = "bn.jpeg"
cv2.imwrite(name, roomFrame)
if intel == 0:
cap.release()
cv2.destroyAllWindows()
You are creating new objects in your while loop. Take now for example, you create a variable and then you assign a new object to it that only lives in that loop. If you declare the variables before your loop the same object will be overwritten instead of re-created.
By just declaring the variables ahead of time with name = None you will be able to make sure you reuse these variables.
I hope this works for you.