I have written the following python script for EEG p300 detection. It takes input from the filepath, uses numpy, matplotlib, pandas, and saves some figures.
program.py
# https://web.archive.org/web/20181105231756/http://developer.choosemuse.com/tools/available-data#Absolute_Band_Powers
# ref: https://alexandre.barachant.org/blog/2017/02/05/P300-with-muse.html
import pandas as pd
import argparse
#parser = argparse.ArgumentParser(description='A program for p300 detection in continuous EEG signal')
#parser.add_argument('-f', '--file', type = str, default = 'museMonitor_845.csv', help = 'input csv file')
#args = parser.parse_args()
csv_path = input("Enter the csv filename (keep the csv file in the same folder or pass the absolute path):")
df = pd.read_csv(csv_path.strip())
print(df)
def p300_segment(a_tp10, b_tp10, g_tp10, d_tp10, t_tp10, window = 420, scaling_factor = 0.6):
"""
takes an eeg signal (filtered)
detects a sudden peak from a valley in a close proximity with a ratio range
"""
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
import numpy as np
plt.plot(a_tp10)
plt.xlabel('time index')
plt.ylabel('amp')
plt.title('Alpha TP-10')
plt.savefig("Alpha_TP-10.png", dpi = 400)
plt.clf()
#plt.show()
plt.plot(b_tp10)
plt.xlabel('time index')
plt.ylabel('amp')
plt.title('Beta TP-10')
#plt.show()
plt.clf()
plt.savefig("Beta_TP-10.png", dpi = 400)
plt.plot(g_tp10)
plt.xlabel('time index')
plt.ylabel('amp')
plt.title('Gamma TP-10')
plt.savefig("Gamma_TP-10.png", dpi = 400)
plt.clf()
#plt.show()
plt.plot(d_tp10)
plt.xlabel('time index')
plt.ylabel('amp')
plt.title('Delta TP-10')
plt.savefig("Delta_TP-10.png", dpi = 400)
plt.clf()
#plt.show()
plt.plot(t_tp10)
plt.xlabel('time index')
plt.ylabel('amp')
plt.title('Theta TP-10')
plt.savefig("Theta_TP-10.png", dpi = 400)
plt.clf()
#plt.show()
sum_sig = a_tp10 + b_tp10 + g_tp10 + d_tp10 + t_tp10
mean_base = np.mean(sum_sig)
std_base = np.std(sum_sig) * scaling_factor
# making epochs
p300_locs = []
p300_mins = []
p300_maxs = []
for epoch_s in range(len(sum_sig)):
epoch = sum_sig[epoch_s:min(len(sum_sig), epoch_s + window)]
seg_1 = epoch[:len(epoch)//2]
seg_2 = epoch[len(epoch)//2:]
# check for p300 conditions
if np.max(seg_1) < mean_base and np.min(seg_1) < 1.7:
if np.min(seg_2) > mean_base and np.max(seg_2) > (mean_base + std_base):
# this is a p300
p300_locs.append(epoch_s)
p300_mins.append(np.min(seg_1))
p300_maxs.append(np.max(seg_2))
epoch_s += window
print(p300_locs)
# check if two adjacent p300 waves are too close or not
if len(p300_locs) > 1:
for i in range(1, len(p300_locs)):
prev_p300 = p300_locs[i-1]
cur_p300 = p300_locs[i]
if cur_p300 - prev_p300 < window * 2:
p300_locs[i-1] = p300_locs[i] # replace with the latter one, as there will be some delay in EVP
p300_mins[i-1] = p300_mins[i]
p300_maxs[i-1] = p300_maxs[i]
plt.plot(sum_sig)
for i in range(len(p300_locs)):
plt.gca().add_patch(Rectangle((p300_locs[i],p300_mins[i]),window, p300_maxs[i] - p300_mins[i],
edgecolor='orange',
facecolor='none',
lw=4))
plt.axhline(y=mean_base, color='r', linestyle='-')
plt.xlabel('time index')
plt.ylabel('amp')
plt.title('Avg TP-10 Signal')
plt.savefig("Avg_TP-10_300.png", dpi = 400)
plt.clf()
#plt.show()
p300_segment(df["Alpha_TP10"], df["Beta_TP10"], df["Gamma_TP10"], df["Delta_TP10"], df["Theta_TP10"])
I use the following command to make the script into an exe.
pyinstaller --onefile -w program.py
But once I get the exe, I can not run it. I get the following error:
Unhandled exception in script
input() lost sys.stdin
So, the problem was the w flag.
When, I just ran, pyinstaller --onefile program.py, it worked fine.
Short information:
If you want to keep the traceback and get rid of the console at same time, you can try bundle using the flags: --w --debug=all.
More background info about:
I've been maintaining a program where I have a config.sys file to make some settings, and if this file have any missing value the program should not open, and raise an error.
Normally I like to use pyinstaller with --windowed, and when setting-up the program in another PC, if something in config.sys is wrong I used to get the window with the traceback correctly, so I could adjust the config.sys file to include the missing setting... but after sometime I have experienced moments when I trying to setting-up this program in another PCs and don't get the "Unhandled exception in script" window to appear as I expected.
In these specific episodes, even the log.txt that my script creates with "logging" package didn't showed up, so I couldn't understand what was going wrong.
So far, I haven't made tests enough to figure out why this behavior have changed... could it be a issue from something I changed in my code, something about the py->exe process, or something in that PCs that behavior in a different way.
Sure, removing the --windowed mode takes back the tracebacks (in the console), and the .txt log file started to work again, but I got disappointed with the situation, since I was used to create just one .exe file, get the a nice GUI without a ugly console behind it, and get traceback windows when needed.
So, after read some threads in stack overflow, as this: Problem with making a .exe without a console window (PyInstaller)
What I did is try to bundle using: --windowed --debug=all
I have tested bundling the .exe with this "--debug=all" flag and appears to be working as I expected: when the config.sys isn't ok I get a "Unhandled exception in script" window with the traceback.
As far as today(3 months after), it worked to me.
Related
I am running a rocky9 Linux terminal and trying to download/clone a git repo. This works, but when trying to plot a graph using the following python script, nothing happens. It works fine on Windows, but the graph does not pop up or display in the terminal.
Heres the Py script:
import matplotlib.pyplot as plt
import numpy as np
# create a dictionary of data from a file in csv format
def createData(filename):
data = {}
with open(filename) as f:
for line in f:
(key, val) = line.split(',')
data[int(key)] = int(val)
return data
def plotData(data):
x = []
y = []
for key in data:
x.append(key)
y.append(data[key])
plt.plot(x,y)
plt.show(block=True)
plots = createData('graphPlots.txt')
plotData(plots)
The graphPlots.txt file is indeed in the same dir and has the following contents:
2,2400
3,2900
4,2800
5,4300
6,8100
7,20300
8,28400
9,41000
10,31600
11,34900
12,52700
13,58200
14,69600
15,85400
16,131200
17,124900
.....
This does change due to another Java file running, but I think the Python script is the issue. Any help is appreciated.
I found a similar solution stating I needed to add the "block=True" parameter to the plt.show. I tried this but this didn't work either.
I am trying to read cpu temperature and plot it on a graph, I already installed vcgencmd but it still shows the error.
import os
import matplotlib.pyplot as plt
from drawnow import *
tempC = []
plt.ion()
cnt=0
def plotTempC():
plt.ylim(20,80)
plt.title('Raspberry Pi core temperture')
plt.grid(True)
plt.ylabel('Temp C')
plt.plot(tempC, 'rx-', label='Degrees C')
plt.legend(loc='upper right')
#pre-load dummy data
for i in range(0,26):
tempC.append(0)
while True:
ostemp = os.popen('vcgencmd measure_temp').readline()
temp = (ostemp.replace("temp=", "").replace("'C\n", ""))
print(temp)
tempC.append(temp)
tempC.pop(0)
drawnow(plotTempC)
plt.pause(.5)
Here is the error that I am getting
'vcgencmd' is not recognized as an internal or external command,
operable program or batch file.```
I have tried all the way to get the realtime temp of cpu but none of them working please give me a any other idea if there to get the realtime temperature of cpu.
I have made a program with python 3.7 using tkinter aswell. Since I am using external pictures I need to include them when I compile everything to one exe. I have tried doing --add-data "bg.png;files" but I still get this error:
_tkinter.TclError: couldn't open "files/bg.png": no such file or directory
Here is the code:
image = PhotoImage(file="files/bg.png")
w = image.width()
h = image.height()
x = 316
y = 246
mainGui.geometry("%dx%d+%d+%d" % (w, h, x, y))
panel = Label(mainGui, image=image)
panel.pack(side='top', fill='both', expand='yes')
What am I doing wrong? I have tried --add-binary as well, adding the file to my spec file. Seriously can't figure this out!
Sorry, I thought that only -F/--one-file makes such behavior, but looks like any bundling with pyinstaller needs such changes.
You need to change your code like this, as explained in this answer:
import sys
if getattr(sys, 'frozen', False):
image = PhotoImage(file=os.path.join(sys._MEIPASS, "files/bg.png"))
else:
image = PhotoImage(file="files/bg.png")
And then bundle it with pyinstaller like this:
pyinstaller --clean -y -n "output_name" --add-data="files\bg.png;files" script.py
First time asking, I havent found any answers to this after some days of looking. Also im absolutely not a programming pro so I might have missed something obvious.
I am running a code that goes through a large library of images (some 2M) and extracts information from them. The code runs fine for several iterations (20-10000ish) but then the program just stops without any errors reported.
The main code exits (terminates?) most of the time at an OpenCV edge detection or houghlines, but not all the time. about 10% of the time it is at some other point in the code.
Using:
OpenCV 4.1.1
Python 3.7.1
Windows 10
Image at: https://www.dropbox.com/s/5lfzkw6sqmu73eb/Image_00_00_00_00.bmp?dl=0
I have tried to get an exception from the Opencv code in some ways, but nothing pops up. The latest attempt is in the code below.
I have tried to use the trace and log modules but I cant really get them to do anything useful.
import numpy as np
import cv2
import traceback
import sys
def cropping_points2(img):
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) # Gray image needed for edge detection
try:
edges = cv2.Canny(gray,20,70,apertureSize = 3)
except Exception as e:
print(traceback.format_exc())
print(sys.exc_info())
print(e, 'there was actually an exception!')
exit()
lines = []
try:
lines = cv2.HoughLines(edges,3,np.pi/180,65, 50, 10, min_theta = 1.4, max_theta = 1.75) # analyse image to find lines - thetha setting looks for horizontal
except Exception as e:
print(traceback.format_exc())
print(sys.exc_info())
print(e, 'there was actually an exception!')
exit()
if lines is None: # All black images return a NoneType image
print('no lines!') # Capture NoneType without crashiing
rect = []
has_lines = False
return rect , has_lines
has_lines = True
return lines[0][0], has_lines
if __name__ == "__main__":
img= cv2.imread('Image_00_00_00_00.bmp')
for index in range(10000):
rect, has_lines = cropping_points2(img)
print(rect)
print(index)
I expect the program to give me a hint of why it stops running =|
I've been trying to run the following code at startup on a Raspberry Pi:
#!/usr/bin/python3
import numpy
import math
import cv2
#this is python 3 specific
import urllib.request
from enum import Enum
from VisionProcessor import VisionProcessor
from GripPipeline import GripPipeline
from networktables import NetworkTables
import time
import logging
from networktables.util import ntproperty
#proper networktables setup
logging.basicConfig(level=logging.DEBUG)
NetworkTables.initialize(server='10.17.11.76')
#create the field to talk to on the network table
class NTClient(object):
angle_difference = ntproperty('/Raspberry Pi/angle difference', 0)
distance_from_target = ntproperty('/Raspberry Pi/distance from target', 0)
n = NTClient()
frame = cv2.VideoCapture('https://frc:frc#10.17.11.11/mjpg/video.mjpg')
if(frame == None):
print("error: camera not found. check connection")
#pipeline = GripPipeline()
pipeline = VisionProcessor()
print("pipeline created")
def get_image():
ret, img_array = frame.read()
# cv2.imwrite("frame.jpg", img_array)
return img_array
def find_distance(width, height, y):
#distances are in inches
KNOWN_WIDTH = 6.25
KNOWN_DISTANCE = 12.0
KNOWN_PIXELS = 135.5
KNOWN_HEIGHT = 424.0
focal_length = (KNOWN_PIXELS * KNOWN_DISTANCE)/KNOWN_WIDTH
#hypotenuse = (KNOWN_WIDTH * focal_length)/width
distance = (KNOWN_WIDTH * focal_length)/width
#0.2125 degrees per pixel vertical
# theta = (0.2125) * (240 - y)
# distance = KNOWN_HEIGHT * (math.tan((math.pi / 2) - math.radians(theta)))
return distance
x = True
while x:
print("while loop entered")
img = get_image()
print("image gotten")
center_point = [160, 120]
file = open('output.txt', 'a')
try:
current_point, size, y = pipeline.process(img)
#negative means turn left, positive means turn right
pixel_difference = center_point[0] - current_point[0]
#4.7761 pixels per degree
angle_difference = (float)(pixel_difference) / 4.7761
n.angle_difference = angle_difference
target_width = size[0]
target_height = size[1]
distance = find_distance(target_width, target_height, y)
n.distance_from_target = distance
print("angle")
file.write("angle: ")
print(n.angle_difference)
file.write(str(angle_difference))
print(" distance: ")
file.write("distance")
print(distance)
file.write(str(distance))
file.write("\n")
except UnboundLocalError:
print(":(")
except (TypeError, cv2.error) as e:
print(":(")
# x = False
I've been doing this by editing the /etc/rc.local file, and the script has been running "successfully". The Pi shows ~25% CPU usage upon startup, and it remains consistent while the script is running, so I can see when it is active (I'm not running any other processes on this Pi). Using ps -aux shows the active python3 process. However, it's not outputting anything, either to the output.txt file or to the networktables.
My end goal is to get it to output successfully to the networktable. If I run it normally (e.g. not at startup, via python3 pipeline-test.py in the terminal), it correctly outputs to both output.txt and the networktable. I added output.txt as a way to ensure that I'm getting correct output, and it's working just fine except when it's run at startup.
Does anyone have an idea of what could be wrong? If any more info is needed, I can do my best to provide it.
EDIT: for some reason, when I copied my code over from Github, it lost all the indentation. The code in use is here.
To start with, the /etc/rc.local script executes as root, thus in the root directory. You will need to add the full file path to your python program. This may or may not solve the issue.
python /dir/dir/python_program
You can record the output of this program in an error file. Make the file
sudo nano /home/pi/error.log
In that file, just type anything, and exit (ctrl + x) saving the changes. Then you edit the rc.local so that the messages are appended to the file
python /dir/dir/python_program > /home/pi/error.log &
now perform a reboot
sudo reboot
the pi will boot, and run the program, after a few minutes, pkill python and view the /home/pi/error.log file. This will give you a better idea of what's going on with your programs "Fail state"
I notice in your program you call a file. rather than output.txt, you will need the full path to the file, since the program is executed in the root directory at startup. this will need to be changed in all instances where your program calls any file.
if you then get a permissions error in the log file, run the following
sudo chmod 777 -R /filepath_to_your_script