Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__pycache__
63 changes: 19 additions & 44 deletions src/PySpectrometer2-Picam2-v1.0.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
https://www.youtube.com/leslaboratory
https://github.com/leswright1977

This project is a follow on from: https://github.com/leswright1977/PySpectrometer
This project is a follow on from: https://github.com/leswright1977/PySpectrometer

This is a more advanced, but more flexible version of the original program. Tk Has been dropped as the GUI to allow fullscreen mode on Raspberry Pi systems and the iterface is designed to fit 800*480 screens, which seem to be a common resolutin for RPi LCD's, paving the way for the creation of a stand alone benchtop instrument.

Expand All @@ -24,7 +24,6 @@
For instructions please consult the readme!
'''


import cv2
import time
import numpy as np
Expand All @@ -46,8 +45,6 @@
if args.waterfall:
print("Waterfall display enabled")
dispWaterfall = True



frameWidth = 800
frameHeight = 600
Expand All @@ -70,8 +67,6 @@
#picam2.set_controls({"Brightness": 0.2}) #Default 0 range -1.0 to +1.0
#picam2.set_controls({"Contrast": 1.8}) #Default 1 range 0.0-32.0



title1 = 'PySpectrometer 2 - Spectrograph'
title2 = 'PySpectrometer 2 - Waterfall'
stackHeight = 320+80+80 #height of the displayed CV window (graph+preview+messages)
Expand All @@ -97,7 +92,7 @@

calibrate = False

clickArray = []
clickArray = []
cursorX = 0
cursorY = 0
def handle_mouse(event,x,y,flags,param):
Expand All @@ -107,15 +102,14 @@ def handle_mouse(event,x,y,flags,param):
mouseYOffset = 160
if event == cv2.EVENT_MOUSEMOVE:
cursorX = x
cursorY = y
cursorY = y
if event == cv2.EVENT_LBUTTONDOWN:
mouseX = x
mouseY = y-mouseYOffset
clickArray.append([mouseX,mouseY])
#listen for click on plot window
cv2.setMouseCallback(title1,handle_mouse)


font=cv2.FONT_HERSHEY_SIMPLEX

intensity = [0] * frameWidth #array for intensity data...full of zeroes
Expand All @@ -124,7 +118,6 @@ def handle_mouse(event,x,y,flags,param):
measure = False #are we measuring?
recPixels = False #are we measuring pixels and recording clicks?


#messages
msg1 = ""
saveMsg = "No data saved"
Expand Down Expand Up @@ -164,7 +157,6 @@ def snapshot(savedata):
message = "Last Save: "+timenow
return(message)


while True:
# Capture frame-by-frame
frame = picam2.capture_array()
Expand Down Expand Up @@ -204,24 +196,21 @@ def snapshot(savedata):
cv2.putText(graph,str(positiondata[1])+'nm',(positiondata[0]-textoffset,12),font,0.4,(0,0,0),1, cv2.LINE_AA)

#horizontal lines
for i in range (320):
if i>=64:
if i%64==0: #suppress the first line then draw the rest...
cv2.line(graph,(0,i),(frameWidth,i),(100,100,100),1)

for i in range(64, 320, 64): # start at 64, increments of 64
cv2.line(graph,(0,i),(frameWidth,i),(100,100,100),1)

#Now process the intensity data and display it
#intensity = []
for i in range(cols):
#data = bwimage[halfway,i] #pull the pixel data from the halfway mark
#data = bwimage[halfway,i] #pull the pixel data from the halfway mark
#print(type(data)) #numpy.uint8
#average the data of 3 rows of pixels:
dataminus1 = bwimage[halfway-1,i]
datazero = bwimage[halfway,i] #pull the pixel data from the halfway mark
dataplus1 = bwimage[halfway+1,i]
data = (int(dataminus1)+int(datazero)+int(dataplus1))/3
data = (int(dataminus1)+int(datazero)+int(dataplus1))/3
data = np.uint8(data)



if holdpeaks == True:
if data > intensity[i]:
intensity[i] = data
Expand Down Expand Up @@ -253,19 +242,17 @@ def snapshot(savedata):

hsv = cv2.cvtColor(waterfall, cv2.COLOR_BGR2HSV)


#Draw the intensity data :-)
#first filter if not holding peaks!

if holdpeaks == False:
intensity = savitzky_golay(intensity,17,savpoly)
intensity = np.array(intensity)
intensity = intensity.astype(int)
holdmsg = "Holdpeaks OFF"
holdmsg = "Holdpeaks OFF"
else:
holdmsg = "Holdpeaks ON"



#now draw the intensity data....
index=0
for i in intensity:
Expand All @@ -278,7 +265,6 @@ def snapshot(savedata):
cv2.line(graph, (index,319-i), (index,320-i), (0,0,0), 1,cv2.LINE_AA)
index+=1


#find peaks and label them
textoffset = 12
thresh = int(thresh) #make sure the data is int.
Expand All @@ -294,7 +280,6 @@ def snapshot(savedata):
#flagpoles
cv2.line(graph,(i,height),(i,height+10),(0,0,0),1)


if measure == True:
#show the cursor!
cv2.line(graph,(cursorX,cursorY-140),(cursorX,cursorY-180),(0,0,0),1)
Expand All @@ -317,11 +302,8 @@ def snapshot(savedata):
cv2.circle(graph,(mouseX,mouseY),5,(0,0,0),-1)
#we can display text :-) so we can work out wavelength from x-pos and display it ultimately
cv2.putText(graph,str(mouseX),(mouseX+5,mouseY),cv2.FONT_HERSHEY_SIMPLEX,0.4,(0,0,0))




#stack the images and display the spectrum
#stack the images and display the spectrum
spectrum_vertical = np.vstack((messages,cropped, graph))
#dividing lines...
cv2.line(spectrum_vertical,(0,80),(frameWidth,80),(255,255,255),1)
Expand All @@ -339,7 +321,7 @@ def snapshot(savedata):
cv2.imshow(title1,spectrum_vertical)

if dispWaterfall == True:
#stack the images and display the waterfall
#stack the images and display the waterfall
waterfall_vertical = np.vstack((messages,cropped, waterfall))
#dividing lines...
cv2.line(waterfall_vertical,(0,80),(frameWidth,80),(255,255,255),1)
Expand All @@ -350,23 +332,21 @@ def snapshot(savedata):

#vertical lines every whole 50nm
for positiondata in fifties:
for i in range(162,480):
if i%20 == 0:
cv2.line(waterfall_vertical,(positiondata[0],i),(positiondata[0],i+1),(0,0,0),2)
cv2.line(waterfall_vertical,(positiondata[0],i),(positiondata[0],i+1),(255,255,255),1)
for i in range(162, 480, 20):
cv2.line(waterfall_vertical,(positiondata[0],i),(positiondata[0],i+1),(0,0,0),2)
cv2.line(waterfall_vertical,(positiondata[0],i),(positiondata[0],i+1),(255,255,255),1)
cv2.putText(waterfall_vertical,str(positiondata[1])+'nm',(positiondata[0]-textoffset,475),font,0.4,(0,0,0),2, cv2.LINE_AA)
cv2.putText(waterfall_vertical,str(positiondata[1])+'nm',(positiondata[0]-textoffset,475),font,0.4,(255,255,255),1, cv2.LINE_AA)

cv2.putText(waterfall_vertical,calmsg1,(490,15),font,0.4,(0,255,255),1, cv2.LINE_AA)
cv2.putText(waterfall_vertical,calmsg3,(490,33),font,0.4,(0,255,255),1, cv2.LINE_AA)
cv2.putText(waterfall_vertical,saveMsg,(490,51),font,0.4,(0,255,255),1, cv2.LINE_AA)
cv2.putText(waterfall_vertical,"Gain: "+str(picamGain),(490,69),font,0.4,(0,255,255),1, cv2.LINE_AA)

cv2.putText(waterfall_vertical,holdmsg,(640,15),font,0.4,(0,255,255),1, cv2.LINE_AA)

cv2.imshow(title2,waterfall_vertical)


keyPress = cv2.waitKey(1)
if keyPress == ord('q'):
break
Expand Down Expand Up @@ -454,12 +434,7 @@ def snapshot(savedata):
if picamGain <=0:
picamGain = 0.0
picam2.set_controls({"AnalogueGain": picamGain})
print("Camera Gain: "+str(picamGain))


print("Camera Gain: "+str(picamGain))


#Everything done
cv2.destroyAllWindows()


Loading