AttributeError with OpenCV in Python - python-3.x

Traceback (most recent call last):
File "test.py", line 10, in <module>
tracker = cv2.Tracker_create("MIL")
AttributeError: module 'cv2.cv2' has no attribute 'Tracker_create
I get the above error when I try to run:
import cv2
import sys
if __name__ == '__main__' :
# Set up tracker.
# Instead of MIL, you can also use
# BOOSTING, KCF, TLD, MEDIANFLOW or GOTURN
tracker = cv2.Tracker_create("MIL")
# Read video
video = cv2.VideoCapture(0)
# Exit if video not opened.
if not video.isOpened():
print ("Could not open video")
sys.exit()
# Read first frame.
ok, frame = video.read()
if not ok:
print ('Cannot read video file')
sys.exit()
# Define an initial bounding box
bbox = (287, 23, 86, 320)
# Uncomment the line below to select a different bounding box
# bbox = cv2.selectROI(frame, False)
# Initialize tracker with first frame and bounding box
ok = tracker.init(frame, bbox)
while True:
# Read a new frame
ok, frame = video.read()
if not ok:
break
# Update tracker
ok, bbox = tracker.update(frame)
# Draw bounding box
if ok:
p1 = (int(bbox[0]), int(bbox[1]))
p2 = (int(bbox[0] + bbox[2]), int(bbox[1] + bbox[3]))
cv2.rectangle(frame, p1, p2, (0,0,255))
# Display result
cv2.imshow("Tracking", frame)
# Exit if ESC pressed
k = cv2.waitKey(1) & 0xff
if k == 27 : break
I found an answer here: How to add "Tracker" in openCV python 2.7
But this confused me more. I'm on MacOSX and I'm just getting started with OpenCV and I'm not really sure how to recompile OpenCV with the correct modules.
Thanks in advance, and sorry if I'm missing something obvious.

So it wasn't a case of the installation, but the constructor name had changed.
tracker = cv2.Tracker_create("MIL")
Should be:
tracker = cv2.TrackerMIL_create()

Related

'Exception in tkinter callback' and '[Errno 24] Too many open files.'

quite new to Python and come across a problem that I'm struggling to diagnose.
I am working on a project involving a Tkinter menu and using an ADC connected to a potentiometer (which will hopefully be replaced by a muscle sensor once I've gotten the essential code working). I am using a raspberry Pi and breadboard for this, with my IDE as Thonny.
The imports are:
from time import sleep
import busio
import digitalio
import board
import adafruit_mcp3xxx.mcp3008 as ADC
from adafruit_mcp3xxx.analog_in import AnalogIn
import tkinter as tk
from tkinter import Menu
import easygui
import RPi.GPIO as GPIO
The overall menu and code works until I try to use the Run() function, which uses all of the files and compares AnalogIn to a threshold value previously found. When the Run button is clicked, it comes up with the error:
Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python3.9/tkinter/__init__.py", line 1892, in __call__
File "/home/pi/Documents/NEA_Python/NEA2023.py", line 280, in Run
File "/usr/local/lib/python3.9/dist-packages/adafruit_mcp3xxx/analog_in.py", line 53, in value
File "/usr/local/lib/python3.9/dist-packages/adafruit_mcp3xxx/mcp3xxx.py", line 80, in read
File "/usr/local/lib/python3.9/dist-packages/adafruit_bus_device/spi_device.py", line 93, in __enter__
File "/usr/local/lib/python3.9/dist-packages/busio.py", line 335, in configure
File "/usr/local/lib/python3.9/dist-packages/adafruit_platformdetect/board.py", line 650, in any_embedded_linux
File "/usr/local/lib/python3.9/dist-packages/adafruit_platformdetect/board.py", line 532, in any_raspberry_pi
File "/usr/local/lib/python3.9/dist-packages/adafruit_platformdetect/board.py", line 205, in _pi_rev_code
File "/usr/local/lib/python3.9/dist-packages/adafruit_platformdetect/__init__.py", line 42, in get_cpuinfo_field
OSError: [Errno 24] Too many open files: '/proc/cpuinfo'
Run() Function code:
def Run():
threshold_valid = False
output_valid = False
#validity checks for all necessary fields
if threshold_valid == False:
thres = open('Threshold.txt', 'r')
threshold = thres.read()
if threshold == '':
print("Missing threshold voltage. Please refer to Main Menu/Options/Edit Muscle Data/Find threshold voltage")
else:
threshold_valid = True
if output_valid == False:
output = open('OutputOption.txt', 'r')
outputOption = output.read()
if outputOption == '':
print("Missing output option. Please refer to Main Menu/Options/Edit Muscle Data/Choose output/ in order to select output")
elif outputOption == 'notification':
with open('Message.txt', 'r') as message:
if message.read() == '':
print("Missing message to display. Please refer to Main Menu/Options/Edit Muscle Data/Choose output/Display message/")
else:
output_valid = True
message.close()
elif outputOption() == 'LED':
output_valid = True
else:
print("Something went wrong. Try deleting stored data at Main Menu/Options/Edit Muscle Data/Delete Data/ and try again")
while threshold_valid == True and output_valid == True:
spiBus = busio.SPI(clock=board.SCK, MISO=board.MISO, MOSI=board.MOSI)
# create the chip select
chipSelect = digitalio.DigitalInOut(board.D22)
#creates the object for adc
adc = ADC.MCP3008(spiBus, chipSelect)
#creates analogue input channel on ADC's pin 0
analogueInChan = AnalogIn(adc, ADC.P0)
instantaneousAIn = analogueInChan.value
if instantaneousAIn> int(threshold):
if outputOption == 'LED':
output_flashLED()
elif outputOption == 'notification':
output_notification()
thres.close()
output.close()
All of the validity checks for this work fine, but it fails once it reaches the part inside the 'while threshold_valid == True and output_valid == True:' statement.
The menu is a menubar with cascade menus coming off of it.
The Tkinter menu code is:
#Root window
root = tk.Tk()
root.title("Main Menu")
#Creates a menubar
menubar = Menu(root, bg = 'powderblue', activebackground = '#84b7c4', tearoff = 0)
root.config(menu = menubar)
#Creates the main menu with the menubar as its parent window
#bg is the natural background colour, activebackground is the colour when the mouse hovers over it
main_menu = Menu(menubar, bg = 'lightcyan', activebackground = 'powderblue', tearoff = 0)
#Adds option to main_menu
main_menu.add_command(
label = "Instructions",
command = instructions
)
main_menu.add_command(
label= "Run",
command = Run
)
#Adds the main_menu as cascade to the menubar
menubar.add_cascade(
label = "Options",
menu = main_menu
)
#Creates menu muscleData_menu with main_menu as parent window
muscleData_menu = Menu(main_menu, tearoff = 0, bg = 'lightcyan', activebackground = 'powderblue')
#Adds option to muscleData_menu
muscleData_menu.add_command(
label = "Instructions",
command = instructions
)
muscleData_menu.add_command(
label = "Find threshold voltage",
command = findThreshold
)
#Creates menu output_menu with muscleData_menu as parent window
output_menu = Menu(muscleData_menu, tearoff = 0, bg = 'lightcyan', activebackground = 'powderblue')
#Adds option to output_menu
output_menu.add_command(
label = "Flash LED",
command = menuoption_flashLED
)
output_menu.add_command(
label = "Display message",
command = menuoption_notification
)
#Adds output_menu as cascade within muscleData_menu
muscleData_menu.add_cascade(
label = "Choose output",
menu = output_menu
)
#Creates menu deleteData_menu with muscleData_menu as parent window
deleteData_menu = Menu(muscleData_menu, tearoff = 0, bg = 'lightcyan', activebackground = 'powderblue')
#Adds option to deleteData_menu
deleteData_menu.add_command(
label = "Delete stored threshold voltage",
command = deleteThreshold
)
deleteData_menu.add_command(
label = "Delete stored output option",
command = deleteOutput
)
deleteData_menu.add_command(
label = "Delete stored notification message",
command = deleteMessage
)
deleteData_menu.add_command(
label = "Delete all stored data",
command = wipeData
)
#adds deleteData_menu as cascade to the muscleData_menu
muscleData_menu.add_cascade(
label = "Delete stored data",
menu = deleteData_menu
)
muscleData_menu.add_command(
label = "Run",
command = Run
)
#Adds muscleData_menu as cascade within main_menu
main_menu.add_cascade(
label = "Edit Muscle Data",
menu = muscleData_menu,
)
#Ends menu program
#root.destroy completely erases root/menu
main_menu.add_command(
label = "Quit",
command=root.destroy,
)
#Runs menu continuously until quit, awaiting user inputs
root.mainloop()
The actual menu works fine, the issue resides inside of the Run() function, however it is a Tkinter related issue. As I understand it, the menu works by the root looping continuously in the background whilst allowing other parts of the code to work, so this may be the issue but I'm not sure how to fix it. I have checked and in all instances of me opening the textfiles across the code, I have closed them again directly after. I have changed the ulimit and it continues to show the same error. I couldn't find a working solution in other stackoverflow answers and so believed it was an issue more localised to my exact code, but apologies if this is a repetition.
The full code is in this google doc, if anyone finds it relevant:
https://docs.google.com/document/d/1Oj5M6jSTXepXSBm9kjj4o_41AN4IhGcgc63iedZSMdQ/edit?usp=sharing
Can you limit the number of files that have to be open at the same time?
I was also reading from this thread,
IOError: [Errno 24] Too many open files:
Please have a look , it might help.
You need to use a with block to deal with your files, so they actually get closed and you won't run out of file descriptors.
Replace things like
thres = open('Threshold.txt', 'r')
threshold = thres.read()
with
with open('Threshold.txt', 'r') as f:
threshold = f.read()

I am getting this error in my python code fr_height, fr_width, _ = frame.shape AttributeError: 'NoneType' object has no attribute 'shape'

The error I am getting:
C:\Users\KGB\PycharmProjects\Screen_rec\venv\Scripts\python.exe C:/Users/KGB/PycharmProjects/Screen_rec/main.py
[ WARN:0] global D:\a\opencv-python\opencv-python\opencv\modules\videoio\src\cap_msmf.cpp (438) `anonymous-namespace'::SourceReaderCB::~SourceReaderCB terminating async callback
Traceback (most recent call last):
File "C:\Users\KGB\PycharmProjects\Screen_rec\main.py", line 24, in <module>
fr_height, fr_width, _ = frame.shape
AttributeError: 'NoneType' object has no attribute 'shape'
Process finished with exit code 1
My code is given here:
import datetime
from PIL import ImageGrab
import numpy as np
import cv2
from win32api import GetSystemMetrics
import sys
width = GetSystemMetrics(0)
height = GetSystemMetrics(1)
time_stamp = datetime.datetime.now().strftime('%Y-%m-%d %H-%M-%S')
file_name = f'{time_stamp}.mp4'
fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')
captured_video = cv2.VideoWriter(file_name, fourcc, 20.0, (width, height))
webcam = cv2.VideoCapture(1)
while True:
img = ImageGrab.grab(bbox=(0, 0, width, height))
img_np = np.array(img)
img_final = cv2.cvtColor(img_np, cv2.COLOR_BGR2RGB)
_, frame = webcam.read()
fr_height, fr_width, _ = frame.shape
img_final[0:fr_height, 0: fr_width, :] = frame[0: fr_height, 0: fr_width, :]
cv2.imshow('Secret Capture', img_final)
# cv2.imshow('webcam', frame)
captured_video.write(img_final)
if cv2.waitKey(10) == ord('q'):
break
I am trying to build a python program that screen records.
I have been looking for many solutions online but none of them I found would work, this program is my first advanced project as a student
I found the answer, I just had to change the webcam = cv2.VideoCapture(1) to webcam = cv2.VideoCapture(0)
Hope this helps everyone who has the same and/or 'similar' issue

Datamatrix with raspberry

I am trying to read datamatrix code by rasp using python.
I'm using pylibdmtx to read the code, but it only works on my notebook. When I put the same code on the raspberry it can't read the code. At the moment my raspberry is reading only qrcode and barcode.
I have two rasp one with raspbian and the other with ubuntu core, neither of which worked.
An example code below
import cv2
import time
from pylibdmtx.pylibdmtx import decode
data = None
video = cv2.VideoCapture(0)
video.set(cv2.CAP_PROP_FPS, 19)
while video.isOpened():
time.sleep(1/9)
ret, frame = video.read()
if ret is False:
break
decodeObjects = decode(frame,
timeout=1000,
max_count=1,
corrections=3)
for obj in decodeObjects:
if obj.data:
data = obj
if data:
break
video.release()
cv2.destroyAllWindows()
print(data)
pylibdmtx is just a wrapper for libdmtx. To make it work, you have to install the native library first.
The .whl file has already contained the .DLL file for Windows:
As for macOS and Linux, you can install the library via command-line tools.
Mac OS X:
brew install libdmtx
Linux:
sudo apt-get install libdmtx0a
I suppose there's no pre-built library for Raspberry Pi. So you can build it by yourself. Here is the source code:
https://github.com/dmtx/libdmtx
Take 3 steps to build and install the libdmtx library:
$ ./configure
$ make
$ sudo make install
After installing the libdmtx library, your Python code should work.
import cv2
import time
from pylibdmtx.pylibdmtx import decode
data = None
video = cv2.VideoCapture(0)
video.set(cv2.CAP_PROP_FPS, 19)
# Add
saveFilename = "./liveImage.jpg"
while video.isOpened():
time.sleep(1/9)
ret, frame = video.read()
if ret is False:
break
# Add - save Live Image
liveImage = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cv2.imwrite(saveFilename, liveImage)
# Add - open File
loadImage = cv2.imread(saveFilename)
# Modify
decodeObjects = decode(loadImage,
timeout=1000,
max_count=1,
corrections=3)
for obj in decodeObjects:
if obj.data:
data = obj
if data:
break
video.release()
cv2.destroyAllWindows()
print(data)
import cv2
import time
from pylibdmtx.pylibdmtx import decode
data = None
video = cv2.VideoCapture(0)
video.set(cv2.CAP_PROP_FPS, 19)
# Add
saveFilename = "./liveImage.jpg"
while video.isOpened():
time.sleep(1/9)
ret, frame = video.read()
if ret is False:
break
# Add - save Live Image
liveImage = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cv2.imwrite(saveFilename, liveImage)
# Add - open File
loadImage = cv2.imread(saveFilename)
# Modify
decodeObjects = decode(loadImage,
# Delete timeout=1000,
max_count=1,
corrections=3)
for obj in decodeObjects:
if obj.data:
data = obj
if data:
break
video.release()
cv2.destroyAllWindows()
print(data)

Video runs for a few frames then gives error

I'm working on raspberry pi3 model b+
I installed opencv 3.4.4 on my raspberry pi , and it installed fine. I'm just running a basic code to see my camera output . (i have plugged in two cameras)
Here is the code .
import cv2
import time
def show_webcam(mirror=False):
frame_rate = 30
prev = 0
cam = cv2.VideoCapture(0)
cam1 = cv2.VideoCapture(1)
ff= 0.5
fxx = ff
fyy = ff
while True:
ret_val, img = cam.read()
img2 = cam1.read()[1]
time_elapsed = time.time() - prev
# print('data type of frame', type(img))
if time_elapsed > 1/frame_rate:
prev = time.time()
cv2.rectangle(img,(100,100),(500,500),(255,255,0),2)
small_frame = cv2.resize(img, (0, 0), fx=fxx, fy=fyy)
cv2.resize(img2,(0, 0), fx = fxx, fy = fyy)
#print("helo")
#if mirror:
# img = cv2.flip(img, 1)
cv2.imshow('my webcam', img)
cv2.imshow('my 2nd webcam', img2)
#if cv2.waitKey(1) == 27:
# break # esc to quit
if cv2.waitKey(1) == 27:
break
cv2.destroyAllWindows()
print (cam)
def main():
show_webcam(mirror=True)
if __name__ == '__main__':
main()
The videos appear for a few frames but after a few seconds i get this error
select timeout
VIDIOC_DQBUF: Resource temporarily unavailable
Traceback (most recent call last):
File "camera.py", line 39, in <module>
main()
File "camera.py", line 36, in main
show_webcam(mirror=True)
File "camera.py", line 21, in show_webcam
small_frame = cv2.resize(img, (0, 0), fx=fxx, fy=fyy)
cv2.error: OpenCV(3.4.4) /home/pi/packaging/opencv-python/opencv/modules/imgproc/src/resize.cpp:3784: error: (-215:Assertion failed) !ssize.empty() in function 'resize'
This same code works fine when i implement it on my laptop. What can i do to correct this error and ensure the video is not interrupted ?
have tried doing cv2.waitKey(30) doesn't work
why you are using a time_elapsed variable while you can just use the waitkey function and pass to it the milli-sec you want to wait, 1000/framePerSecond. and about your error, the frame you try to resize is empty, sometimes that happens. so before you do any image processing try to check if image image not empty then proceed what you want to do.
Same code works on laptop but not on pi. This means you have issues to lesser memory and / or cpu on a smaller device.
Try reducing the framerate to adjust how many frames you can work with a smaller device.
You should check if the ret_val of both cam.read() is true simultaneously before continuing processing. So when a frame is not properly grabbed, it is dropped and the process is retried instead of throwing an error and exiting.
This does not technically resolve the error, but it does solve your problem, provided the resulting framerate is sufficient for your application.

raspberry pi3 b+ slideshow program not working

I wanted to turn my raspberry pi into a slideshow device but I barely know python 3 could anyone help me fix this code I found online? It's supposed to display the images in the list I created but it doesn't run. The only changes I made to this code was the creation of the list so I have no idea why it does not work. The error I'm getting is
Traceback (most recent call last):
File "bro.py", line 82, in <module>
slideshow.start()
File "bro.py", line 56, in start
self.main()
File "bro.py", line 48, in main
self.set_image()
File "bro.py", line 42, in set_image
self.image_name = next(self.images)
StopIteration
Here is the code:
#!/usr/bin/env python3
"""Display a slideshow from a list of filenames"""
import os
import tkinter
from itertools import cycle
from PIL import Image, ImageTk
class Slideshow(tkinter.Tk):
"""Display a slideshow from a list of filenames"""
def __init__(self, images, slide_interval):
"""Initialize
images = a list of filename
slide_interval = milliseconds to display image
"""
tkinter.Tk.__init__(self)
self.geometry("+0+0")
self.slide_interval = slide_interval
self.images = images
self.set_images(images)
self.slide = tkinter.Label(self)
self.slide.pack()
def set_images(self, images):
self.images = cycle(images)
def center(self):
"""Center the slide window on the screen"""
self.update_idletasks()
w = self.winfo_screenwidth()
h = self.winfo_screenheight()
size = tuple(int(_) for _ in self.geometry().split('+')[0].split('x'))
x = w / 2 - size[0] / 2
y = h / 2 - size[1] / 2
self.geometry("+%d+%d" % (x, y))
def set_image(self):
"""Setup image to be displayed"""
self.image_name = next(self.images)
filename, ext = os.path.splitext(self.image_name)
self.image = ImageTk.PhotoImage(Image.open(self.image_name))
def main(self):
"""Display the images"""
self.set_image()
self.slide.config(image=self.image)
self.title(self.image_name)
self.center()
self.after(self.slide_interval, self.start)
def start(self):
"""Start method"""
self.main()
self.mainloop()
if __name__ == "__main__":
slide_interval = 2500
# use a list
images = [
"/~/definitely/1550099164562.png",
"/~/definitely/1550770995551.png",
"/~/definitely/1550771217013.png",
"/~/definitely/1550771726391.jpg"]
# all the specified file types in a directory
# "." us the directory the script is in.
# exts is the file extentions to use. it can be any extention that pillow supports
# http://pillow.readthedocs.io/en/3.3.x/handbook/image-file-formats.html
import glob
images = glob.glob("*.jpg")
path = "."
exts = ["jpg", "bmp", "png", "gif", "jpeg"]
images = [fn for fn in os.listdir(path) if any(fn.endswith(ext) for ext in exts)]
# start the slideshow
slideshow = Slideshow(images, slide_interval)
slideshow.start()
Try next(iter(images)) instead of next(images).
BTW, I have Raspberry Pi slideshows for both Tkinter and Kivy on my tachyonlabs GitHub ... they also download photos from Instagram, but if you don't hook that up or there's no Internet connection they will just cycle through the images in the image directory you specify, with your chosen order and duration.

Resources