This commit is contained in:
2024-10-30 22:37:32 +01:00
commit 7cade5aed9
6 changed files with 622 additions and 0 deletions

12
.gitignore vendored Normal file
View File

@@ -0,0 +1,12 @@
*.pyc
*.spec
*.toc
*.pkg
*.zip
*.html
*.txt
*.pyz
*.pyo
*.log
*.lock
.venv/*

3
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,3 @@
{
"CodeGPT.apiKey": "Ollama"
}

61
extract_ts.py Normal file
View File

@@ -0,0 +1,61 @@
import cv2
import pytesseract
import re
# Set Tesseract executable path
pytesseract.pytesseract.tesseract_cmd = r'/usr/bin/tesseract'
def extract_frame_and_timestamp(video_path):
"""
Extract a frame from the given video and identify its timestamp.
Args:
video_path (str): Path to the video file.
Returns:
None if the video cannot be opened or no timestamp is found.
Otherwise, prints the extracted timestamp.
"""
# Open the video capture
cap = cv2.VideoCapture(video_path)
# Check if the video was opened correctly
if not cap.isOpened():
print("Error opening the video")
return
# Iterate over frames until one with a timestamp is found
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
text = pytesseract.image_to_string(frame)
timestamp = _extract_timestamp(text)
if timestamp:
print(timestamp.group())
break
# Release the video capture
cap.release()
def _extract_timestamp(text):
"""
Extract a timestamp from the given text.
Args:
text (str): Text to search for timestamps.
Returns:
The extracted timestamp as a string, or None if no timestamp is found.
"""
pattern = r'\d{2}-\d{2}-\d{4}\s\d{2}:\d{2}:\d{2}'
return re.search(pattern, text)
# Execute the program
video_path = "/home/alex/Scaricati/2024_08_11_14_55_26.MP4"
extract_frame_and_timestamp(video_path)

211
timestamp_extraction.py Normal file
View File

@@ -0,0 +1,211 @@
# program to extract a timestamp from a video
# written by Akshay Krishnan, Yashika (Interns, Amagi Media Labs)
#usage:
#timestamp_extract.py -b <Name_of_s3_bucket> -p <path_to_folder_containing_videos_in_bucket> -f(optional)
#specifying f is optional. if specified, it downloads entire video from the bucket.
#before running, ensure that a file 'videos.txt' contains the list of videos in s3 from which timestamp is to be extracted
#after execution, extracted timestamps are stored in stamp_file.txt
import cv2 #computer vision library to process images
from PIL import Image #Python imaging library to handle images
import pytesseract #Google's tesseract-OCR wrapper for python
import argparse #library to handle command line arguments
import os #perform file operations, create and remove files
import re #perform regular expression search
import unicodedata #convert string format between unicode and ascii
import boto3 #downloading files
import botocore #from AWS s3
#function to convert the numbers in the stamp as detected by tesseract
#into the standard hh:mm:ss:nn stamp format
def stampFromText(text):
stamp = text.encode('ascii','ignore')
s = list(stamp)
st = []
for item in s:
if item.isdigit() == True:
st.append(item)
if len(st) == 8:
return (True, st[0]+st[1]+':'+st[2]+st[3]+':'+st[4]+st[5]+':'+st[6]+st[7])
else:
return (False, 'garbage')
#function to calculate the mismatch between stamp of first frame
#as obtained by frame number and the stamp as obtained by tesseract
def calculateMismatch(stamp, firstFrameStamp, frame_no):
h, m, s, f = firstFrameStamp
h1, m1, s1, f1 = stamp
init_f = (h*3600 + m*60 + s)*25 + f+1
now_f = (h1*3600 +m1*60+s1)*25 +f1 +1
return frame_no - (now_f - init_f)
#function that obtains the timestamp in a given frame of the video
def GetTimestamp(video):
cap = cv2.VideoCapture(video)
filename = "timestamp_test_file.bmp"
stamp_found = False
frame_count = 0
stamp_confirmed = False
stamp = None
firstFrameStamp1 = None
reset_count = 0
mismatch = 0
while(cap.isOpened() and stamp_confirmed is False):
ret, frame = cap.read()
if ret == True:
cv2.imwrite(filename, frame)
text = pytesseract.image_to_string(Image.open(filename))
if len(text) > 0:
m = re.findall("[0-2][0-9].[0-5][0-9].[0-5][0-9].[0-9][0-9]", text)
if len(m) > 0:
temp_flag, stamp = stampFromText(m[0])
if temp_flag is True:
firstFrameStamp = getTimeFirstFrame(stamp, frame_count, 25)
if stamp_found is False:
stamp_found = True
firstFrameStamp1 = firstFrameStamp
else:
x,y,w,z = firstFrameStamp1
x1,y1,w1,z1 = firstFrameStamp
if (x1==x and y1==y and z1==z and w1==w):
stamp_confirmed = True
mismatch = calculateMismatch(intStamp(stamp), firstFrameStamp, frame_count)
else:
firstFrameStamp1 = firstFrameStamp
reset_count+=1
else:
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
rows, cols = gray.shape
gray = gray[20:40, int(float(cols/3))+18:int(float(cols)*2/3)-16]
gray = cv2.threshold(gray, 240,255,cv2.THRESH_BINARY)[1]
gray = cv2.resize(gray, None, fx=2, fy=2, interpolation=cv2.INTER_CUBIC)
gray = cv2.dilate(gray, cv2.getStructuringElement(cv2.MORPH_CROSS, (3,3)), iterations=1)
cv2.imwrite(filename, gray)
text = pytesseract.image_to_string(Image.open(filename))
os.remove(filename)
if len(text) > 0:
m = re.findall("[0-2][0-9].[0-5][0-9].[0-5][0-9].[0-9][0-9]", text)
if len(m) > 0:
temp_flag, stamp = stampFromText(m[0])
if temp_flag is True:
firstFrameStamp = getTimeFirstFrame(stamp, frame_count, 25)
if stamp_found is False:
stamp_found = True
firstFrameStamp1 = firstFrameStamp
else:
x,y,w,z = firstFrameStamp1
x1,y1,w1,z1 = firstFrameStamp
if (x1==x and y1==y and z1==z and w1==w):
stamp_confirmed = True
mismatch = calculateMismatch(intStamp(stamp), firstFrameStamp, frame_count)
else:
firstFrameStamp1 = firstFrameStamp
reset_count+=1
frame_count += 1
else:
break
if(os.path.isfile('timestamp_test_file.bmp')):
os.remove('timestamp_test_file.bmp')
cap.release()
return stamp_confirmed, firstFrameStamp1, mismatch
#if frame number is given as input, the function returns the run time to reach that particular frame
def getTimeFromFrameNumber(frame_no, fps):
f = frame_no % fps
s = int(frame_no/fps)
m = int(s/60)
s = s%60
h = int(m/60)
m = m%60
return (h, m, s, f)
#helper function to convert stamps from string to integer tuples
def intStamp(stamp):
l = stamp.split(':')
t = []
for i in l:
t.append(int(i))
return t
#funtion to calculate the timestamp on the first frame if the stamp at
#any other frame and the corresponding frame numbers are input
def getTimeFirstFrame(stamp, frameno, fps):
t = intStamp(stamp)
h,m,s,f = t
secs = h*3600 + m*60 + s
isecs = secs - (frameno/fps)
h = isecs/3600
m = (isecs%3600)/60
s = (isecs%60)
return (h,m,s,0)
if __name__ == '__main__':
ap = argparse.ArgumentParser()
ap.add_argument("-b", "--bucket", required=True, help="S3 bucket name")
ap.add_argument("-p", "--path", required=True, help="path to folder containing videos in bucket")
ap.add_argument("-f", "--full", default=False, help="boolean flag, if set downloads entire media file", action='store_true')
args = vars(ap.parse_args())
s3 = boto3.resource('s3')
client = boto3.client('s3')
offset = 0
end = 5000000
if(os.path.isfile('stamp_file.txt')):
db_file = open("stamp_file.txt", 'r')
text_from_file = str(db_file.read())
db_file.close()
else:
text_from_file = ''
videos_file = open("videos.txt")
videoname = ''
stamp_file = open("stamp_file.txt", 'a+')
lines = videos_file.read().split('\n')
try:
for line in lines:
if len(line) > 0:
words = line.split(' ')
videoname = words[len(words)-1]
if videoname in text_from_file:
print videoname, ": entry already exists for this video"
else:
if args["full"] is True:
s3.Bucket(args["bucket"]).download_file(args["path"]+videoname, videoname)
else:
obj = client.get_object(Bucket=args["bucket"], Key=args["path"]+videoname,Range='bytes={}-{}'.format(offset, end))
newdata = obj['Body'].read()
f = open(videoname,'w')
f.write(newdata)
f.close()
flagt, stamp, err = GetTimestamp(videoname)
os.remove(videoname)
if flagt == True:
stamp_file.write(videoname+', '+str(stamp[0])+":"+str(stamp[1])+":"+str(stamp[2])+":"+str(stamp[3])+', '+str(err)+'\n')
print "video ", videoname, stamp, err
else:
print videoname, ": error in finding stamp"
stamp_file.close()
videos_file.close()
except KeyboardInterrupt:
if(os.path.isfile('timestamp_test_file.bmp')):
os.remove('timestamp_test_file.bmp')
if(os.path.isfile(videoname)):
os.remove(videoname)
stamp_file.close()
videos_file.close()
print "quitting"

34
timestamp_frame.py Normal file
View File

@@ -0,0 +1,34 @@
import cv2
import pytesseract
import re
pytesseract.pytesseract.tesseract_cmd = r'/usr/bin/tesseract'
def salva_frame(video_path):
# Apri il video
cap = cv2.VideoCapture(video_path)
# Controlla se il video è stato aperto correttamente
if not cap.isOpened():
print("Errore nell'apertura del video")
return
while(cap.isOpened()):
# Leggi un frame
ret, frame = cap.read()
if not ret:
break
text = pytesseract.image_to_string(frame)
timestamp = re.search(r'\d{2}-\d{2}-\d{4}\s\d{2}:\d{2}:\d{2}', text)
if timestamp:
print(timestamp.group())
break
# Rilascia il video capture
cap.release()
# Esegui il programma
video_path = "/home/alex/Scaricati/2024_08_11_14_55_26.MP4" # Sostituisci con il percorso del tuo video
salva_frame(video_path)

301
timestamps.csv Normal file
View File

@@ -0,0 +1,301 @@
Frame,Timestamp
0,0.0
1,0.03333333333333333
2,0.06666666666666667
3,0.1
4,0.13333333333333333
5,0.16666666666666666
6,0.2
7,0.23333333333333334
8,0.26666666666666666
9,0.3
10,0.3333333333333333
11,0.36666666666666664
12,0.4
13,0.43333333333333335
14,0.4666666666666667
15,0.5
16,0.5333333333333333
17,0.5666666666666667
18,0.6
19,0.6333333333333333
20,0.6666666666666666
21,0.7
22,0.7333333333333333
23,0.7666666666666666
24,0.8
25,0.8333333333333334
26,0.8666666666666667
27,0.9
28,0.9333333333333333
29,0.9666666666666667
30,1.0
31,1.0333333333333332
32,1.0666666666666667
33,1.1
34,1.1333333333333333
35,1.1666666666666667
36,1.2
37,1.2333333333333334
38,1.2666666666666666
39,1.3
40,1.3333333333333333
41,1.3666666666666667
42,1.4
43,1.4333333333333333
44,1.4666666666666666
45,1.5
46,1.5333333333333332
47,1.5666666666666667
48,1.6
49,1.6333333333333333
50,1.6666666666666667
51,1.7
52,1.7333333333333334
53,1.7666666666666666
54,1.8
55,1.8333333333333333
56,1.8666666666666667
57,1.9
58,1.9333333333333333
59,1.9666666666666666
60,2.0
61,2.033333333333333
62,2.0666666666666664
63,2.1
64,2.1333333333333333
65,2.1666666666666665
66,2.2
67,2.2333333333333334
68,2.2666666666666666
69,2.3
70,2.3333333333333335
71,2.3666666666666667
72,2.4
73,2.433333333333333
74,2.466666666666667
75,2.5
76,2.533333333333333
77,2.5666666666666664
78,2.6
79,2.6333333333333333
80,2.6666666666666665
81,2.7
82,2.7333333333333334
83,2.7666666666666666
84,2.8
85,2.8333333333333335
86,2.8666666666666667
87,2.9
88,2.933333333333333
89,2.966666666666667
90,3.0
91,3.033333333333333
92,3.0666666666666664
93,3.1
94,3.1333333333333333
95,3.1666666666666665
96,3.2
97,3.2333333333333334
98,3.2666666666666666
99,3.3
100,3.3333333333333335
101,3.3666666666666667
102,3.4
103,3.433333333333333
104,3.466666666666667
105,3.5
106,3.533333333333333
107,3.5666666666666664
108,3.6
109,3.6333333333333333
110,3.6666666666666665
111,3.6999999999999997
112,3.7333333333333334
113,3.7666666666666666
114,3.8
115,3.8333333333333335
116,3.8666666666666667
117,3.9
118,3.933333333333333
119,3.966666666666667
120,4.0
121,4.033333333333333
122,4.066666666666666
123,4.1
124,4.133333333333333
125,4.166666666666667
126,4.2
127,4.233333333333333
128,4.266666666666667
129,4.3
130,4.333333333333333
131,4.366666666666666
132,4.4
133,4.433333333333334
134,4.466666666666667
135,4.5
136,4.533333333333333
137,4.566666666666666
138,4.6
139,4.633333333333333
140,4.666666666666667
141,4.7
142,4.733333333333333
143,4.766666666666667
144,4.8
145,4.833333333333333
146,4.866666666666666
147,4.9
148,4.933333333333334
149,4.966666666666667
150,5.0
151,5.033333333333333
152,5.066666666666666
153,5.1
154,5.133333333333333
155,5.166666666666667
156,5.2
157,5.233333333333333
158,5.266666666666667
159,5.3
160,5.333333333333333
161,5.366666666666666
162,5.4
163,5.433333333333334
164,5.466666666666667
165,5.5
166,5.533333333333333
167,5.566666666666666
168,5.6
169,5.633333333333333
170,5.666666666666667
171,5.7
172,5.733333333333333
173,5.766666666666667
174,5.8
175,5.833333333333333
176,5.866666666666666
177,5.9
178,5.933333333333334
179,5.966666666666667
180,6.0
181,6.033333333333333
182,6.066666666666666
183,6.1
184,6.133333333333333
185,6.166666666666667
186,6.2
187,6.233333333333333
188,6.266666666666667
189,6.3
190,6.333333333333333
191,6.366666666666666
192,6.4
193,6.433333333333334
194,6.466666666666667
195,6.5
196,6.533333333333333
197,6.566666666666666
198,6.6
199,6.633333333333333
200,6.666666666666667
201,6.7
202,6.733333333333333
203,6.766666666666667
204,6.8
205,6.833333333333333
206,6.866666666666666
207,6.8999999999999995
208,6.933333333333334
209,6.966666666666667
210,7.0
211,7.033333333333333
212,7.066666666666666
213,7.1
214,7.133333333333333
215,7.166666666666667
216,7.2
217,7.233333333333333
218,7.266666666666667
219,7.3
220,7.333333333333333
221,7.366666666666666
222,7.3999999999999995
223,7.433333333333334
224,7.466666666666667
225,7.5
226,7.533333333333333
227,7.566666666666666
228,7.6
229,7.633333333333333
230,7.666666666666667
231,7.7
232,7.733333333333333
233,7.766666666666667
234,7.8
235,7.833333333333333
236,7.866666666666666
237,7.8999999999999995
238,7.933333333333334
239,7.966666666666667
240,8.0
241,8.033333333333333
242,8.066666666666666
243,8.1
244,8.133333333333333
245,8.166666666666666
246,8.2
247,8.233333333333333
248,8.266666666666666
249,8.3
250,8.333333333333334
251,8.366666666666667
252,8.4
253,8.433333333333334
254,8.466666666666667
255,8.5
256,8.533333333333333
257,8.566666666666666
258,8.6
259,8.633333333333333
260,8.666666666666666
261,8.7
262,8.733333333333333
263,8.766666666666666
264,8.8
265,8.833333333333334
266,8.866666666666667
267,8.9
268,8.933333333333334
269,8.966666666666667
270,9.0
271,9.033333333333333
272,9.066666666666666
273,9.1
274,9.133333333333333
275,9.166666666666666
276,9.2
277,9.233333333333333
278,9.266666666666666
279,9.3
280,9.333333333333334
281,9.366666666666667
282,9.4
283,9.433333333333334
284,9.466666666666667
285,9.5
286,9.533333333333333
287,9.566666666666666
288,9.6
289,9.633333333333333
290,9.666666666666666
291,9.7
292,9.733333333333333
293,9.766666666666666
294,9.8
295,9.833333333333334
296,9.866666666666667
297,9.9
298,9.933333333333334
299,9.966666666666667
1 Frame Timestamp
2 0 0.0
3 1 0.03333333333333333
4 2 0.06666666666666667
5 3 0.1
6 4 0.13333333333333333
7 5 0.16666666666666666
8 6 0.2
9 7 0.23333333333333334
10 8 0.26666666666666666
11 9 0.3
12 10 0.3333333333333333
13 11 0.36666666666666664
14 12 0.4
15 13 0.43333333333333335
16 14 0.4666666666666667
17 15 0.5
18 16 0.5333333333333333
19 17 0.5666666666666667
20 18 0.6
21 19 0.6333333333333333
22 20 0.6666666666666666
23 21 0.7
24 22 0.7333333333333333
25 23 0.7666666666666666
26 24 0.8
27 25 0.8333333333333334
28 26 0.8666666666666667
29 27 0.9
30 28 0.9333333333333333
31 29 0.9666666666666667
32 30 1.0
33 31 1.0333333333333332
34 32 1.0666666666666667
35 33 1.1
36 34 1.1333333333333333
37 35 1.1666666666666667
38 36 1.2
39 37 1.2333333333333334
40 38 1.2666666666666666
41 39 1.3
42 40 1.3333333333333333
43 41 1.3666666666666667
44 42 1.4
45 43 1.4333333333333333
46 44 1.4666666666666666
47 45 1.5
48 46 1.5333333333333332
49 47 1.5666666666666667
50 48 1.6
51 49 1.6333333333333333
52 50 1.6666666666666667
53 51 1.7
54 52 1.7333333333333334
55 53 1.7666666666666666
56 54 1.8
57 55 1.8333333333333333
58 56 1.8666666666666667
59 57 1.9
60 58 1.9333333333333333
61 59 1.9666666666666666
62 60 2.0
63 61 2.033333333333333
64 62 2.0666666666666664
65 63 2.1
66 64 2.1333333333333333
67 65 2.1666666666666665
68 66 2.2
69 67 2.2333333333333334
70 68 2.2666666666666666
71 69 2.3
72 70 2.3333333333333335
73 71 2.3666666666666667
74 72 2.4
75 73 2.433333333333333
76 74 2.466666666666667
77 75 2.5
78 76 2.533333333333333
79 77 2.5666666666666664
80 78 2.6
81 79 2.6333333333333333
82 80 2.6666666666666665
83 81 2.7
84 82 2.7333333333333334
85 83 2.7666666666666666
86 84 2.8
87 85 2.8333333333333335
88 86 2.8666666666666667
89 87 2.9
90 88 2.933333333333333
91 89 2.966666666666667
92 90 3.0
93 91 3.033333333333333
94 92 3.0666666666666664
95 93 3.1
96 94 3.1333333333333333
97 95 3.1666666666666665
98 96 3.2
99 97 3.2333333333333334
100 98 3.2666666666666666
101 99 3.3
102 100 3.3333333333333335
103 101 3.3666666666666667
104 102 3.4
105 103 3.433333333333333
106 104 3.466666666666667
107 105 3.5
108 106 3.533333333333333
109 107 3.5666666666666664
110 108 3.6
111 109 3.6333333333333333
112 110 3.6666666666666665
113 111 3.6999999999999997
114 112 3.7333333333333334
115 113 3.7666666666666666
116 114 3.8
117 115 3.8333333333333335
118 116 3.8666666666666667
119 117 3.9
120 118 3.933333333333333
121 119 3.966666666666667
122 120 4.0
123 121 4.033333333333333
124 122 4.066666666666666
125 123 4.1
126 124 4.133333333333333
127 125 4.166666666666667
128 126 4.2
129 127 4.233333333333333
130 128 4.266666666666667
131 129 4.3
132 130 4.333333333333333
133 131 4.366666666666666
134 132 4.4
135 133 4.433333333333334
136 134 4.466666666666667
137 135 4.5
138 136 4.533333333333333
139 137 4.566666666666666
140 138 4.6
141 139 4.633333333333333
142 140 4.666666666666667
143 141 4.7
144 142 4.733333333333333
145 143 4.766666666666667
146 144 4.8
147 145 4.833333333333333
148 146 4.866666666666666
149 147 4.9
150 148 4.933333333333334
151 149 4.966666666666667
152 150 5.0
153 151 5.033333333333333
154 152 5.066666666666666
155 153 5.1
156 154 5.133333333333333
157 155 5.166666666666667
158 156 5.2
159 157 5.233333333333333
160 158 5.266666666666667
161 159 5.3
162 160 5.333333333333333
163 161 5.366666666666666
164 162 5.4
165 163 5.433333333333334
166 164 5.466666666666667
167 165 5.5
168 166 5.533333333333333
169 167 5.566666666666666
170 168 5.6
171 169 5.633333333333333
172 170 5.666666666666667
173 171 5.7
174 172 5.733333333333333
175 173 5.766666666666667
176 174 5.8
177 175 5.833333333333333
178 176 5.866666666666666
179 177 5.9
180 178 5.933333333333334
181 179 5.966666666666667
182 180 6.0
183 181 6.033333333333333
184 182 6.066666666666666
185 183 6.1
186 184 6.133333333333333
187 185 6.166666666666667
188 186 6.2
189 187 6.233333333333333
190 188 6.266666666666667
191 189 6.3
192 190 6.333333333333333
193 191 6.366666666666666
194 192 6.4
195 193 6.433333333333334
196 194 6.466666666666667
197 195 6.5
198 196 6.533333333333333
199 197 6.566666666666666
200 198 6.6
201 199 6.633333333333333
202 200 6.666666666666667
203 201 6.7
204 202 6.733333333333333
205 203 6.766666666666667
206 204 6.8
207 205 6.833333333333333
208 206 6.866666666666666
209 207 6.8999999999999995
210 208 6.933333333333334
211 209 6.966666666666667
212 210 7.0
213 211 7.033333333333333
214 212 7.066666666666666
215 213 7.1
216 214 7.133333333333333
217 215 7.166666666666667
218 216 7.2
219 217 7.233333333333333
220 218 7.266666666666667
221 219 7.3
222 220 7.333333333333333
223 221 7.366666666666666
224 222 7.3999999999999995
225 223 7.433333333333334
226 224 7.466666666666667
227 225 7.5
228 226 7.533333333333333
229 227 7.566666666666666
230 228 7.6
231 229 7.633333333333333
232 230 7.666666666666667
233 231 7.7
234 232 7.733333333333333
235 233 7.766666666666667
236 234 7.8
237 235 7.833333333333333
238 236 7.866666666666666
239 237 7.8999999999999995
240 238 7.933333333333334
241 239 7.966666666666667
242 240 8.0
243 241 8.033333333333333
244 242 8.066666666666666
245 243 8.1
246 244 8.133333333333333
247 245 8.166666666666666
248 246 8.2
249 247 8.233333333333333
250 248 8.266666666666666
251 249 8.3
252 250 8.333333333333334
253 251 8.366666666666667
254 252 8.4
255 253 8.433333333333334
256 254 8.466666666666667
257 255 8.5
258 256 8.533333333333333
259 257 8.566666666666666
260 258 8.6
261 259 8.633333333333333
262 260 8.666666666666666
263 261 8.7
264 262 8.733333333333333
265 263 8.766666666666666
266 264 8.8
267 265 8.833333333333334
268 266 8.866666666666667
269 267 8.9
270 268 8.933333333333334
271 269 8.966666666666667
272 270 9.0
273 271 9.033333333333333
274 272 9.066666666666666
275 273 9.1
276 274 9.133333333333333
277 275 9.166666666666666
278 276 9.2
279 277 9.233333333333333
280 278 9.266666666666666
281 279 9.3
282 280 9.333333333333334
283 281 9.366666666666667
284 282 9.4
285 283 9.433333333333334
286 284 9.466666666666667
287 285 9.5
288 286 9.533333333333333
289 287 9.566666666666666
290 288 9.6
291 289 9.633333333333333
292 290 9.666666666666666
293 291 9.7
294 292 9.733333333333333
295 293 9.766666666666666
296 294 9.8
297 295 9.833333333333334
298 296 9.866666666666667
299 297 9.9
300 298 9.933333333333334
301 299 9.966666666666667