-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsandbox8ColorIterate.py
390 lines (384 loc) · 22.9 KB
/
sandbox8ColorIterate.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
#!~/.anaconda3/bin/python
import math
from PIL.Image import Image, new
import numpy as np
import time as t1
import matplotlib.pyplot as plt
import os
import cv2
import glob
from os import read, startfile, write
from os.path import exists
from numpy.core.fromnumeric import std
from numpy.core.numeric import allclose, zeros_like
from numpy.lib.function_base import rot90
def makeBarHistGraphsSolo(labels,width,barData,title,makeBar: bool,makeHist:bool,folderH):
if makeBar:
x = np.arange(len(labels))
fig, ax = plt.subplots(figsize=(10,5.63))
rects = ax.bar(x,barData,width,label = 'Code Output ( (Mean = '+str(round(np.mean(barData),2))+', Std = '+str(round(np.std(barData),2))+')')
ax.set_ylabel('Detection Frame',fontsize = 10)
ax.set_xlabel('Event Number',fontsize = 10)
ax.set_title(title,fontsize = 12)
ax.set_xticks(x)
ax.set_xticklabels(labels,fontsize = 6)
ax.legend(fontsize = 8)
ax.bar_label(rects, padding=2, fontsize = 6)
fig.tight_layout()
# suffix = 1
# while exists(str(title)+' '+str(suffix)+'.png'):
# suffix += 1
plt.savefig(folderH+str(title)+'.png')
if makeHist:
fig = plt.figure(figsize=(10,5.63))
plt.title(title)
plt.hist(barData,bins=8,alpha=0.5,rwidth=0.9)
plt.xlabel('Detection Frame'+' (Mean = '+str(round(np.mean(barData),2))+', Std = '+str(round(np.std(barData),2))+')')
plt.ylabel('Frequency')
# suffix = 1
# while exists(str(title)+' hist '+str(suffix)+'.png'):
# suffix += 1
plt.savefig(folderH+str(title)+' hist.png')
def makeBarGraph(labels,width,barLabels,barData,title,yLabel,xLabel, makeBar: bool, makeHist: bool):
if makeBar:
x = np.arange(len(labels)) # the label locations
fig, ax = plt.subplots(figsize=(10,5.63))
rects1 = ax.bar(x - width/2, barData[0], width, label = barLabels[0]+' (Mean = '+str(round(np.mean(barData[0]),2))+', Std = '+str(round(np.std(barData[0]),2))+')')
rects2 = ax.bar(x + width/2, barData[1], width, label = barLabels[1]+' (Mean = '+str(round(np.mean(barData[1]),2))+', Std = '+str(round(np.std(barData[1]),2))+')')
# Add some text for labels, title and custom x-axis tick labels, etc.
ax.set_ylabel(yLabel,fontsize = 10)
ax.set_xlabel(xLabel,fontsize = 10)
ax.set_title(title,fontsize = 12)
ax.set_xticks(x)
ax.set_xticklabels(labels,fontsize = 6)
ax.legend(fontsize = 8)
ax.bar_label(rects1, padding=2, fontsize = 6)
ax.bar_label(rects2, padding=2,fontsize = 6)
fig.tight_layout()
suffix = 0
# while exists(str(title)+' '+str(suffix)+'.png'):
# suffix += 1
plt.savefig(str(title)+' '+str(suffix)+'.png')
if makeHist:
suffix = 0
fig = plt.figure(figsize=(10,5.63))
plt.subplot(1,2,1,title='Code Output' + ' ('+str(title)+')')
plt.hist(barData[0],bins=8,alpha=0.5,rwidth=0.9)
plt.xlabel('Detection Frame'+' (Mean = '+str(round(np.mean(barData[0]),2))+', Std = '+str(round(np.std(barData[0]),2))+')')
plt.ylabel('Frequency')
plt.subplot(1,2,2,title='Answer Key' + ' ('+str(title)+')')
plt.xlabel('Detection Frame'+' (Mean = '+str(round(np.mean(barData[1]),2))+', Std = '+str(round(np.std(barData[1]),2))+')')
plt.ylabel('Frequency')
plt.hist(barData[1],bins=8,alpha=0.5,rwidth=0.9)
# while exists(str(title)+' hist '+str(suffix)+'.png'):
# suffix += 1
plt.savefig(str(title)+' hist '+str(suffix)+'.png')
def padEvent(eventImages):
try:return np.pad(eventImages,[(0,0),(1,1),(1,1)],'constant',constant_values = 255)
except:return np.pad(eventImages,[(0,0),(1,1),(1,1),(0,0)],'constant',constant_values = 255)
def initializeImages(eventImages):#this simply returns a duplicate array without modifying the original
newImages = []
for eventImage in eventImages:
newImages.append(eventImage)
return newImages
def eventFrameStamp(eventNumber,eventImages,eventPrefix,eventTimestamps,labels: bool):#this is an aesthethic function
images = initializeImages(eventImages)
if labels:
for frameNumber in range(len(images)):
images[frameNumber] = imgNumStamps(addLeadingZeros(2,eventNumber+1)+'-'+addLeadingZeros(3,(frameNumber)%len(images)),0,0,images[frameNumber])
images[frameNumber] = imgNumStamps(eventPrefix,len(images[frameNumber])-13,0,images[frameNumber])
images[frameNumber] = imgNumStamps(addLeadingZeros(10,eventTimestamps[frameNumber]),len(images[0])-7,0,images[frameNumber])
else:
for frameNumber in range(len(images)):
images[frameNumber] = imgNumStamps(addLeadingZeros(2,eventNumber+1)+'-'+addLeadingZeros(3,(frameNumber)%len(images)),0,0,images[frameNumber])
return images
def normalizePixelValues(eventImages,lowerLimit,upperLimit):#this function is unused
images = np.array(initializeImages(eventImages))
holder = np.zeros_like(images)
mid = int(np.mean(images))
if mid > 255/2:
bottom = np.min([lowerLimit,2*mid-255])
images = cv2.normalize(images,holder,bottom*255/(bottom-255),255,cv2.NORM_MINMAX)
else:
top = np.max([2*mid,upperLimit])
images = cv2.normalize(images,holder,0,255*255/top,cv2.NORM_MINMAX)
return images
def extractForegroundMask(reverse: bool, mustExistInPreviousFrames: bool,static: bool,eventImages, histLength, threshold,blur,startingFrom): #returns the filtered run images
images = initializeImages(eventImages)
if blur > 0:
for i in range(len(images)):
images[i] = cv2.GaussianBlur(images[i],(blur,blur),cv2.BORDER_DEFAULT)
fgbg = cv2.createBackgroundSubtractorMOG2(histLength,threshold,False)
if reverse:
for frameNumber in range(len(images)-1,-1,-1):
if static and frameNumber < len(images)-histLength:
images[frameNumber] = fgbg.apply(images[frameNumber],learningRate = 0)
else:
images[frameNumber] = fgbg.apply(images[frameNumber])
if mustExistInPreviousFrames:
for frameNumber in range(1,len(images)):
images[frameNumber] = np.multiply(images[frameNumber],np.divide(images[frameNumber-1],255))
else:
for frameNumber in range(len(images)):
if static and frameNumber > histLength:
images[frameNumber] = fgbg.apply(images[frameNumber],learningRate = 0)
else:
images[frameNumber] = fgbg.apply(images[frameNumber])
if mustExistInPreviousFrames:
if startingFrom == 0 or startingFrom > len(images)-2:
startingFrom = len(images)-2
for frameNumber in range(startingFrom,-1,-1):
images[frameNumber] = np.multiply(images[frameNumber],np.divide(images[frameNumber+1],255))
return images
def overlayFrames(frame1,frame2): # returns the composite frame of two frames
return np.multiply(frame1,np.divide(frame2,255))
def getEventsFromRun(runFolder): # str - name of grou p, str array - names of runs, str 2d array - timestamps in runs, str 2d array - filenames in runs
filename_RFG = [os.path.join(runFolder,i) for i in os.listdir(runFolder)if i[-4:]=='.bmp' or i[-5:]=='.tiff'] # make sure is tiff and not .tif possible source of error
# filename_RFG = [os.path.join(runFolder,i) for i in os.listdir(runFolder)] # make sure is tiff and not .tif possible source of error
groupName_RFG = os.path.basename(runFolder)
runNames_RFG = []
runImages_RFG = []
runTimestamps_RFG = []
currRunName_RFG = ''
valid_RFG = []
for i in filename_RFG:
tif_RFG = os.path.basename(i)
try:
runName_RFG, timestamp_RFG = tif_RFG.replace('.tiff','').replace('.tif','').split('_')
if runName_RFG != currRunName_RFG:
currRunName_RFG = runName_RFG
runNames_RFG.append(runName_RFG)
runTimestamps_RFG.append([])
valid_RFG.append(True)
runImages_RFG.append([])
runImages_RFG[-1].append(cv2.imread(i))
# if len(runImages_RFG)==35:
# runImages_RFG[-1].append(cv2.imread(i))
if timestamp_RFG[-1] == 'X':
valid_RFG[-1] = False
runTimestamps_RFG[-1].append(timestamp_RFG.replace('X',''))
except:
pass
return groupName_RFG, runNames_RFG, runTimestamps_RFG, runImages_RFG, valid_RFG
def concatFrames(image1,image2,axis):#calls np.concatenate
return np.concatenate((image1,image2),axis)
def imgNumStamps(frameNum, loc1, loc2, origGrid): # this def includes a frame stamp at [loc1][loc2] on origGrid with frameNum works with '-' character as well
frameNums = []
frameNumb = str(frameNum)
for i in range(len(frameNumb)):
if frameNumb[i] == '-':
frameNums.append(-1)
else:
frameNums.append(frameNumb[i])
numForms = ['111101101101111','010010010010010','111001111100111','111001111001111','101101111001001','111100111001111','111100111101111','111001001001001','111101111101111','111101111001111','000000111000000']
grid = np.zeros((7,1+4*len(frameNums)),dtype=int)
for i in range(len(frameNums)):
for j in range(5):
for k in range(3):
grid[1+j][1+4*i+k] = numForms[int(frameNums[i])][3*j+k]
for i in range(7):
for j in range(1+4*len(frameNums)):
origGrid[loc1+i][loc2+j]=255*grid[i][j]
return origGrid
def writeAviVideo(videoName, frameRate, allImages, openVideo: bool,color: bool): # creates a video with videoname, frame_rate, using "images", and opens the video based on a boolean
images = allImages
images = np.array(images).astype(np.uint8)
if not color:
height, width = images[0].shape
size = (width,height)
out = cv2.VideoWriter(videoName+'.avi',cv2.VideoWriter_fourcc(*'DIVX'), frameRate, size, isColor=0) # isColor = 0 can be replaced by changing line (this line + 2 (or 3) to out.write(cv2.merge([imgs[i],imgs[i],imgs[i]]))
else:
height, width,layers = images[0].shape
size = (width,height)
out = cv2.VideoWriter(videoName+'.avi',cv2.VideoWriter_fourcc(*'DIVX'), frameRate, size) # isColor = 0 can be replaced by changing line (this line + 2 (or 3) to out.write(cv2.merge([imgs[i],imgs[i],imgs[i]]))
for i in range(len(images)):
out.write(images[i])
out.release()
if openVideo:
startfile(this_repo_path+os.path.sep+videoName+".avi")
def addLeadingZeros(finalLength, currText): # adds leading zeros to match the expected length of a number/string format
currentText = str(currText)
while len(currentText) < finalLength:
currentText = '0' + currentText
return currentText
Images = [] # initializes the array used to store images to make a movie
Images1 = [] # initializes the array used to store images to make a movie
Images2 = [] # initializes the array used to store images to make a movie
this_file_path = os.path.realpath(__file__) # gets the path to this file including the file
this_repo_path, this_file_name = os.path.split(this_file_path) # gets the path to the repository containing this file and the file name
github_path, this_repo_name = os.path.split(this_repo_path) # gets the users github folder location and the repo name
data_repo_name = "Snowball8"
data_repo_path = github_path + os.path.sep + data_repo_name
data_folder_name = 'ColorCroppedTiffs'
folders = glob.glob(data_repo_path + os.path.sep +data_folder_name + os.path.sep + '*')
for i in range(len(folders)):
folders[i] = os.path.basename(folders[i])
for folder in folders:
print(folder)
data_folder_name = 'ColorCroppedTiffs'
runNames = glob.glob(data_repo_path + os.path.sep +data_folder_name + os.path.sep + folder + os.path.sep + '*')
for i in range(len(runNames)):
runNames[i] = os.path.basename(runNames[i])
# print(runNames)
# runNames = ['Cs-137'] # the short name of the folder containing images (tif files)
notesContent = []
try:
os.mkdir(this_repo_path+os.path.sep+folder)
except:
pass
# continue
for runName in runNames:
circleComposite = []
Images3 = []
Images4 = []
runEventsNoteContent = runName+', Invalid Events: '
invalidEventsInRun = ''
detectedFrames = []
data_folder_name = 'ColorCroppedTiffs'
data_folder_name += os.path.sep + folder
data_folder_name += os.path.sep + runName
data_folder_path = data_repo_path + os.path.sep + data_folder_name # THIS LINE MUST BE CORRECT EVERYTHING ELSE IS NOT ESSENTIAL
print(data_folder_path)
runName, eventPrefixes, eventFrameTimestamps, runEventImages, validRunEvents = getEventsFromRun(data_folder_path) # calls getRunsFromGroup data_folder_path MUST BE A COMPLETE PATH, ALL
print(str(runName)+'/'+str(len(eventPrefixes)))
allEventsInFolder = True
if allEventsInFolder:
eventsOfInterest = np.arange(len(eventPrefixes))
else:
eventsOfInterest = np.array([8]) # 1-indexing
eventsOfInterest = np.array([1,2,3,4,5,6,8,15,35]) # 1-indexing
eventsOfInterest = eventsOfInterest[eventsOfInterest <= len(eventPrefixes)]
for i in range(len(eventsOfInterest)):
eventsOfInterest[i] -= 1
numEvents = len(eventsOfInterest)
# to-do: remove following lines
# answerKeyPath = glob.glob(data_folder_path+os.path.sep+'known*.txt')[0]
# answerKeyFile = open(answerKeyPath,'r')
# answerKeyLines = answerKeyFile.readlines()
labels = []
codeFrame = []
keyFrame = []
scatterCount = []
for eventNumber in eventsOfInterest: # iterates over all runNumber in runsOfInterest (note: runNumber is 0-indexed)
eventLabel = str(eventNumber+1)
# print(eventNumber)
if not validRunEvents[eventNumber]:
runEventsNoteContent+= eventLabel+','
eventLabel = '('+eventLabel+')'
thisEventImages = runEventImages[eventNumber]
thisEventFrameTimestamps = eventFrameTimestamps[eventNumber]
eventLength = len(thisEventImages)
# minArea = (thisEventImages[0].shape[0]+thisEventImages[0].shape[1])/2
# maxArea = thisEventImages[0].shape[0]*thisEventImages[0].shape[1]/2
# cv2.text
if thisEventFrameTimestamps[0][0] == '0':
thisEventImages.append(thisEventImages.pop(0)) # the 0-th frame is removed and added to the end of the event images
thisEventFrameTimestamps.append(thisEventFrameTimestamps.pop(0)) # the 0-th frame is removed and added to the end of the event images
thisEventImagesO = np.array(thisEventImages).astype(np.uint8)
thisEventImages = cv2.normalize(np.array(thisEventImages),np.zeros_like(thisEventImages),0,255,cv2.NORM_MINMAX) # first number: [0,255/2], second number [255/2,255] 0 and 255 mean no normalization
thisEventImages = [np.subtract(255,thisEventImagesGs) for thisEventImagesGs in thisEventImages]
thisEventImagesGGGG = np.min(thisEventImages[0],-1)
thisEventImagesGGGG = np.where(thisEventImagesGGGG>=200,0,1)
thisEventImagesGGGG = np.array(thisEventImagesGGGG).astype(np.uint8)
# cv2.imshow('test',cv2.merge([thisEventImagesGGGG,thisEventImagesGGGG,thisEventImagesGGGG]))
# cv2.waitKey(0)
# cv2.destroyAllWindows()
for frameNumber in range(len(thisEventImages)):
for i in range(3):
thisEventImages[frameNumber][:,:,i] = np.multiply(thisEventImages[frameNumber][:,:,i],thisEventImagesGGGG)
thisEventImages = [cv2.GaussianBlur(thisEventImagesGs,(25,25),cv2.BORDER_DEFAULT) for thisEventImagesGs in thisEventImages]
thisEventImages = np.array(thisEventImages).astype(np.uint8)
thisEventImagesG = extractForegroundMask(False,True,True,thisEventImages,50,200,0,0)
# cv2.imshow('test',thisEventImagesGGGG)
# # cv2.imshow('test',cv2.merge([thisEventImagesGGGG,thisEventImagesGGGG,thisEventImagesGGGG]))
# cv2.waitKey(0)
# cv2.destroyAllWindows()
# thisEventImagesGGG = extractForegroundMask(False,False,True,thisEventImages,10,5,1,0)
# for frameNumber in range(len(thisEventImages)):
# # thisEventImagesG[frameNumber] = overlayFrames(thisEventImagesGGG[frameNumber],thisEventImagesG[min([len(thisEventImages)-1,frameNumber+2])])
# thisEventImagesG[frameNumber] = overlayFrames(thisEventImagesGGG[frameNumber],thisEventImagesG[-1])
# thisEventImagesG = [overlayFrames(thisEventImagesGs,thisEventImagesG[-1])for thisEventImagesGs in thisEventImagesG]
blur = 1
allCircles = np.zeros_like(thisEventImages)
thisEventImagesG = [np.subtract(255,thisEventImagesGs) for thisEventImagesGs in thisEventImagesG]
thisEventImagesG = [cv2.GaussianBlur(thisEventImagesGs,(blur,blur),cv2.BORDER_DEFAULT)for thisEventImagesGs in thisEventImagesG]
thisEventImagesG = np.array(thisEventImagesG).astype(np.uint8)
# thisEventImagesG = [np.subtract(255,cv2.cvtColor(thisEventImage,cv2.COLOR_RGB2GRAY))for thisEventImage in thisEventImages]
# thisEventImages = np.array(thisEventImages)
# thisEvent3 = np.array(extractForegroundMask(False,True,True,thisEventImages,50,100,35,0)).astype(np.uint8)
# thisEvent3 = np.array(np.subtract(255,thisEvent3)).astype(np.uint8)
# thisEvent1 = np.array(extractForegroundMask(False,False,True,thisEventImages,50,9,3,0)).astype(np.uint8)
# thisEvent1 = extractForegroundMask(False,False,True,thisEventImages,50,9,0,0)
# thisEvent1 = np.array(np.subtract(255,thisEvent1)).astype(np.uint8)
# newImage = [cv2.cvtColor(thisEvent,cv2.COLOR_GRAY2RGB) for thisEvent in thisEvent3]
# newImage1 = [cv2.cvtColor(thisEvent,cv2.COLOR_GRAY2RGB) for thisEvent in thisEvent1]
# newImage = np.array(newImage).astype(np.uint)
foundIt = False
thisEventImagesGg = []
circles = []
for frameNumber in range(len(thisEventImages)):
# thisEvent1[frameNumber] = np.subtract(255,overlayFrames(thisEvent1[frameNumber],thisEvent3[min([frameNumber+12,len(thisEventImages)-1])]))
params = cv2.SimpleBlobDetector_Params()
params.minThreshold = 226
params.maxThreshold = 256
# params.thresholdStep = 51
params.filterByArea = True
# params.minArea = minArea
# params.maxArea = maxArea
params.minArea = 80
# params.maxArea = (len(thisEventImages[0]))**2/4
params.filterByCircularity = False
params.minCircularity = 0.1
params.filterByConvexity = False
params.minConvexity = 0.1
params.filterByInertia = False
params.minInertiaRatio = 0.5
# detector = cv2.SimpleBlobDetector_create()
detector = cv2.SimpleBlobDetector_create(params)
keypoints = detector.detect(thisEventImagesG[frameNumber])
thisEventImages[frameNumber] = cv2.drawKeypoints(thisEventImages[frameNumber],keypoints,np.array([]),(0,0,255),cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
if frameNumber > 0:
allCircles[frameNumber] = cv2.drawKeypoints(allCircles[frameNumber-1],keypoints,np.array([]),(0,0,255),cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
thisEventImagesGg.append(cv2.merge([thisEventImagesG[frameNumber],thisEventImagesG[frameNumber],thisEventImagesG[frameNumber]]))
thisEventImagesGg[frameNumber] = cv2.drawKeypoints(thisEventImagesGg[frameNumber],keypoints,np.array([]),(0,0,255),cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
# print(eventNumber,frameNumber)
circleTracker = []
[circleTracker.append([keypoint.pt,keypoint.size]) for keypoint in keypoints]
for [(x1,y1),d1]in circleTracker:
newCircle = True
for i in range(len(circles)):
x0,y0,d0=circles[i]
if (x0-x1)**2+(y0-y1)**2<=(d0+d1)**2/4:
if d1 > d0:
circles[i]=[x1,y1,d1]
newCircle = False
# ***** VERY IMPORTANT ***** THIS(below) COULD BE USED TO ROUGHLY APPROXIMATE THE FRAME WHERE A SNOWBALL FORMS (blur causes shifting but this might be a really good spot to look at using similar to sandboxColor and sandbox8Color ballParkFrame approximations ****** VERY IMPORTANT)
if newCircle:
circles.append([x1,y1,d1])
thisCircles = np.array(allCircles[frameNumber]).astype(np.uint8)
thisCircles = cv2.putText(thisCircles,str(eventNumber),(0,15),cv2.FONT_HERSHEY_COMPLEX_SMALL,1,(255,0,0),1)
thisCircles = cv2.putText(thisCircles,str(len(circles)),(0,34),cv2.FONT_HERSHEY_COMPLEX_SMALL,1,(255,0,0),1)
thisCircles = cv2.putText(thisCircles,str(frameNumber),(0,53),cv2.FONT_HERSHEY_COMPLEX_SMALL,1,(255,0,0),1)
Images.append(concatFrames(thisEventImagesO[frameNumber],concatFrames(concatFrames(thisEventImages[frameNumber],thisEventImagesGg[frameNumber],1),thisCircles,1),1))
# Images.append(concatFrames(thisEventImages[frameNumber],newImage[frameNumber],1))
# Images.append(concatFrames(thisEventImages[frameNumber],concatFrames(newImage[frameNumber],newImage1[frameNumber],1),1))
thisCircle = allCircles[-1]
# print(theEventKeys)
thisCircle = cv2.putText(thisCircle,str(eventNumber),(0,15),cv2.FONT_HERSHEY_SIMPLEX,1,(255,0,0),1)
thisCircle = cv2.putText(thisCircle,str(len(circles)),(0,34),cv2.FONT_HERSHEY_SIMPLEX,1,(255,0,0),1)
circleComposite.append(thisCircle)
scatterCount.append(len(circles))
while len(circleComposite)%10 != 0:
circleComposite.append(np.zeros_like(circleComposite[-1]))
circleRows = []
while len(circleComposite) > 0:
circleRows.append(np.concatenate(circleComposite[:10],1))
circleComposite = circleComposite[10:]
circleGrid = np.concatenate(circleRows,0)
circleGrid = np.array(circleGrid).astype(np.uint8)
cv2.imwrite(this_repo_path+os.path.sep+folder+os.path.sep+'blob detection grid - '+folder+' - '+runName+'2.jpg',circleGrid)
# cv2.waitKey(0)
# cv2.destroyAllWindows()
writeAviVideo(videoName = folder+os.path.sep+'Blob Detection - '+folder+' - '+runName+'2',frameRate = 1,allImages = Images,openVideo = False,color = True)
Images = []
print(np.mean(scatterCount),np.std(scatterCount))