pogucam 0.1.12__py3-none-any.whl → 0.1.14__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pogucam/explore_u24_uni.py +450 -153
- pogucam/mqimr.py +61 -0
- pogucam/mqims.py +100 -0
- {pogucam-0.1.12.dist-info → pogucam-0.1.14.dist-info}/METADATA +2 -1
- pogucam-0.1.14.dist-info/RECORD +11 -0
- pogucam-0.1.12.dist-info/RECORD +0 -9
- {pogucam-0.1.12.dist-info → pogucam-0.1.14.dist-info}/WHEEL +0 -0
- {pogucam-0.1.12.dist-info → pogucam-0.1.14.dist-info}/entry_points.txt +0 -0
pogucam/explore_u24_uni.py
CHANGED
@@ -83,6 +83,17 @@ import math
|
|
83
83
|
|
84
84
|
from astropy import wcs
|
85
85
|
|
86
|
+
#------------------------------------ subscibe
|
87
|
+
import struct
|
88
|
+
import paho.mqtt.client as mqtt
|
89
|
+
import numpy as np
|
90
|
+
import datetime as dt
|
91
|
+
import cv2
|
92
|
+
import threading
|
93
|
+
|
94
|
+
|
95
|
+
|
96
|
+
|
86
97
|
istrip = 0
|
87
98
|
UPDATE_INTERVAL = 1
|
88
99
|
#FITS_CUBE_N = 400
|
@@ -157,7 +168,10 @@ def is_int(n):
|
|
157
168
|
|
158
169
|
def guess_url( inp ):
|
159
170
|
"""
|
160
|
-
interpret url
|
171
|
+
interpret url: http: or /dev/
|
172
|
+
- low integer== dev
|
173
|
+
- int 80+ is local port; http+ is clear;
|
174
|
+
- :1883/topic/var or :1883
|
161
175
|
"""
|
162
176
|
final = inp
|
163
177
|
ip = ""
|
@@ -166,7 +180,29 @@ def guess_url( inp ):
|
|
166
180
|
if inp is None:
|
167
181
|
print("X... no url")
|
168
182
|
return None
|
169
|
-
if
|
183
|
+
if inp[0] == ":":
|
184
|
+
port = "".join(inp[1:])
|
185
|
+
path = port.split("/")[1:]
|
186
|
+
path = "/".join(path)
|
187
|
+
port = port.split("/")[0]
|
188
|
+
print("D... port is evidently given in ", inp[1:], "; port:", port, "path:" , path)
|
189
|
+
if not is_int(port):
|
190
|
+
print("X... port not integer")
|
191
|
+
return None
|
192
|
+
port = int(port)
|
193
|
+
if port == 1883:
|
194
|
+
final = f"mqtt://127.0.0.1/{path}"
|
195
|
+
print("i... local mqtt ... ", final)
|
196
|
+
return final
|
197
|
+
else:
|
198
|
+
final = f"http://127.0.0.1:{port}/{path}"
|
199
|
+
print("i... local http ... ", final)
|
200
|
+
return final
|
201
|
+
#return inp
|
202
|
+
if inp.find("/dev/video") == 0:
|
203
|
+
print("D... no discussion, videodev:", inp)
|
204
|
+
return inp
|
205
|
+
if type(inp) is int:# dev # or port #
|
170
206
|
if int(inp) < 80:
|
171
207
|
print("D... maybe video device")
|
172
208
|
videostr = f"/dev/video{inp}"
|
@@ -183,65 +219,96 @@ def guess_url( inp ):
|
|
183
219
|
return final
|
184
220
|
print("X... IDK:")
|
185
221
|
return None
|
186
|
-
|
222
|
+
# clearly mqtt
|
223
|
+
if (inp.find("mqtt://") == 0):
|
224
|
+
print("i... clearly mqtt:", inp)
|
225
|
+
return final
|
226
|
+
# clearly http
|
187
227
|
if (inp.find("http://") == 0) or (inp.find("https://") == 0):
|
188
228
|
if (inp.find(":") > 0):
|
189
229
|
return final
|
190
230
|
else:
|
191
231
|
print("X... a problem, no port demanded")
|
192
232
|
return None
|
233
|
+
# something strange, less than any IP ... IDK
|
193
234
|
elif len(inp) < 7:
|
194
|
-
print("X... TOO short ip (can be 0 for
|
235
|
+
print("X... /ShoudntBeHere/ TOO short ip (can be 0 for video0):", inp)
|
195
236
|
if is_int(inp):
|
196
|
-
print("i... but
|
197
|
-
if int(inp) > 79 and int(inp) < 64000:
|
198
|
-
print("i... I put 127.0.0.1 address ")
|
237
|
+
print("i... /ShoudntBeHere/ but this is one number, possibly port number", inp)
|
238
|
+
if int(inp) > 79 and int(inp) < 64000 and int(inp) != 1883:
|
239
|
+
print("i... /ShoudntBeHere/I put 127.0.0.1 address ")
|
199
240
|
final = f"http://127.0.0.1:{inp}/video"
|
200
241
|
return final
|
242
|
+
elif int(inp) == 1883:
|
243
|
+
print("i... mqtt is evidently required. Topic (too short inp) is: ", path)
|
244
|
+
# if inp.find("/") > 0:
|
245
|
+
# port = inp.split("/")[]
|
246
|
+
# path = join("/").portplus.split("/")[1:]
|
247
|
+
if path == "":
|
248
|
+
print("i... topic will be by default image/raw8000")
|
249
|
+
path = "image/raw8000"
|
250
|
+
ip = "127.0.0.1"
|
251
|
+
final = f"mqtt://{ip}/{path}"
|
252
|
+
print(final)
|
253
|
+
return final
|
201
254
|
elif is_int(inp):
|
202
|
-
print("D... maybe video device")
|
255
|
+
print("D... /ShoudntBeHere/maybe video device")
|
203
256
|
videostr = f"/dev/video{inp}"
|
204
257
|
if os.path.exists( videostr):
|
205
|
-
print(f"i... {videostr} exists ")
|
258
|
+
print(f"i... /ShoudntBeHere/ {videostr} exists ")
|
206
259
|
return videostr
|
207
260
|
else:
|
208
|
-
print(f"i... {videostr} DOES NOT exist !!!!! ")
|
261
|
+
print(f"i... /ShoudntBeHere/ {videostr} DOES NOT exist !!!!! ")
|
209
262
|
return videostr
|
210
263
|
else:
|
211
|
-
print("X... BAD input", inp)
|
264
|
+
print("X... /ShoudntBeHere-maybe/ BAD input", inp)
|
265
|
+
return None
|
266
|
+
# address
|
212
267
|
elif inp.find(".") < 0:
|
213
|
-
print("X... no dots in address ", inp)
|
268
|
+
print("X... no dots in the address ", inp)
|
214
269
|
return None
|
215
270
|
elif len(inp.split(".")) < 3:
|
216
|
-
print("X... not IP4 address ", inp)
|
271
|
+
print("X... too few dots, not IP4 address ", inp)
|
217
272
|
return None
|
218
273
|
# ----------------------------------------------
|
219
274
|
digit = inp.split(".")
|
220
|
-
if is_int( digit[0]) and is_int(digit[1]) and is_int(digit[2]):
|
275
|
+
if is_int( digit[0]) and is_int(digit[1]) and is_int(digit[2]): # 3 digits and d:port
|
221
276
|
# DIGITS
|
222
277
|
if is_int(digit[3]):
|
223
|
-
print("
|
278
|
+
print("i... a bit of problem, no port demanded at 3rd digit", digit, " giving 8000")
|
224
279
|
ip = inp # back to 4 digits
|
225
280
|
port = "8000"
|
226
281
|
#return None
|
227
|
-
elif digit[3].find(":") <= 0:
|
228
|
-
print("X... a bit problem, no port demanded, giving 8000")
|
282
|
+
elif digit[3].find(":") <= 0: # if not a digit, maybe path??
|
283
|
+
print("X... /ShoudntBeHere-maybe/ a bit of problem, no port demanded, giving 8000")
|
229
284
|
port = "8000"
|
230
285
|
#return None
|
231
|
-
else:# port ok
|
286
|
+
else:# port ok-extract
|
232
287
|
ip = inp.split(":")[0]
|
233
288
|
portplus = inp.split(":")[1]
|
289
|
+
# extract path
|
234
290
|
if portplus.find("/") > 0:
|
235
291
|
port = portplus.split("/")[0]
|
236
|
-
|
292
|
+
pathlist = portplus.split("/")[1:]
|
293
|
+
path = "/".join(pathlist)
|
237
294
|
else:
|
238
295
|
port = portplus
|
239
|
-
|
296
|
+
# ---
|
240
297
|
if not is_int(port):
|
241
|
-
print("X... port is not a number", port)
|
298
|
+
print("X... port is not a number:", port)
|
242
299
|
return None
|
300
|
+
# port is OK now----------------------------
|
301
|
+
port = int(port)
|
302
|
+
if port == 1883:
|
303
|
+
print("i... mqtt is evidently required. Topic is: ", path)
|
304
|
+
if path == "":
|
305
|
+
print("i... topic will be by default image/raw8000")
|
306
|
+
path = "image/raw8000"
|
307
|
+
final = f"mqtt://{ip}:{port}/{path}"
|
308
|
+
print(final)
|
309
|
+
return final
|
243
310
|
if path == "":
|
244
|
-
print("
|
311
|
+
print("i... a bit problem, no path obtained. Giving /video , but this should probably change in future")
|
245
312
|
path = "video"
|
246
313
|
|
247
314
|
final = f"http://{ip}:{port}/{path}"
|
@@ -379,32 +446,42 @@ class StreamWidget(QLabel):
|
|
379
446
|
self.device = None
|
380
447
|
self.url = None
|
381
448
|
self.post_addr = None
|
382
|
-
|
383
|
-
|
449
|
+
self.internet_mqtt = False
|
450
|
+
self.mqtt_topic = "image/raw8000" # default topic
|
451
|
+
self.mqtt_subscribed = False
|
452
|
+
self.mqtt_client = None
|
453
|
+
self.mqtt_new_image = False # trafic light
|
454
|
+
# url is mqtt:// of http:// or /dev/
|
384
455
|
if url is None :
|
385
456
|
print("X... I cannot find a relevant source kind, but program should not be here...")
|
386
457
|
sys.exit(1)
|
387
458
|
if (url is not None) and is_int(url) and int(url) < 10:
|
388
|
-
|
389
|
-
#self.url = f"/dev/video{url}"
|
390
|
-
##self.device = f"/dev/video{url}"
|
391
|
-
##self.internet_not_device = False
|
392
|
-
##self.post_addr = None #self.url.replace("/video", "/cross")
|
393
|
-
print("X... should enver get here")
|
459
|
+
print("X... should never get here")
|
394
460
|
sys.exit(1)
|
461
|
+
#--------------------- decide if device or internet http:// ----
|
395
462
|
if (url is not None) and url.find("/dev/video") >= 0:
|
396
463
|
self.device = url
|
397
464
|
self.url = url#"local"
|
398
|
-
self.internet_not_device = False #
|
465
|
+
self.internet_not_device = False #
|
399
466
|
self.post_addr = None# self.url.replace("/video", "/cross")
|
400
467
|
if not os.path.exists( self.device):
|
401
468
|
print(f"i... {self.device} DOES NOT exists ")
|
402
|
-
elif (url is not None) and url.find("http://") >= 0:
|
469
|
+
elif (url is not None) and (url.find("http://") or url.find("http://")) >= 0:
|
403
470
|
self.url = url
|
404
|
-
self.internet_not_device = True
|
471
|
+
self.internet_not_device = True #
|
405
472
|
self.post_addr = self.url.replace("/video", "/cross")
|
473
|
+
|
474
|
+
elif (url is not None) and url.find("mqtt://") >= 0:
|
475
|
+
ipdeco = url.split("mqtt://")[-1] # remove protocol
|
476
|
+
self.url = ipdeco.split("/")[0] # jsut IP address for mqtt
|
477
|
+
self.mqtt_topic = ipdeco.split("/")[1:] # IP address
|
478
|
+
self.mqtt_topic = "/".join(self.mqtt_topic)
|
479
|
+
self.internet_not_device = True #
|
480
|
+
self.internet_mqtt = True #
|
481
|
+
self.post_addr = None#self.url.replace("/video", "/cross")
|
406
482
|
else:
|
407
483
|
print(f"X... {self.url} x {self.device} ")
|
484
|
+
#---------------------------------------------------------------
|
408
485
|
self.resolution = resolution
|
409
486
|
self.fourcc = fourcc
|
410
487
|
#self.internet_not_device = internet_not_device
|
@@ -431,7 +508,7 @@ class StreamWidget(QLabel):
|
|
431
508
|
self.bytex = b"" # stream
|
432
509
|
# ----------------------------------- initial frame -------------- was always STRIPS, now NONE: helsp w VCR ----
|
433
510
|
# with big colored strips
|
434
|
-
self.frame = None#np.zeros((self.height, self.width, 3), dtype=np.uint8)
|
511
|
+
self.frame = None # do COPY() to img # np.zeros((self.height, self.width, 3), dtype=np.uint8)
|
435
512
|
self.which_error = "" # no error, can be url http...
|
436
513
|
self.frames_to_fail_max = 5 # countdown to 0 and reset CAP
|
437
514
|
self.frames_to_fail = self.frames_to_fail_max # countdown to 0 and reset CAP
|
@@ -879,6 +956,8 @@ class StreamWidget(QLabel):
|
|
879
956
|
# ---------------------------
|
880
957
|
if selfimg is None:
|
881
958
|
return
|
959
|
+
|
960
|
+
#print(f"D... overtext {self.img.shape} ")
|
882
961
|
RXT = f"XT:{self.r_xtend}" # CC LU ... for remote ok
|
883
962
|
ZOO = f"ZOO:{self.zoomme:3.1f}"
|
884
963
|
ROO = f"ROT:{self.l_rotate:3.1f}"
|
@@ -896,15 +975,29 @@ class StreamWidget(QLabel):
|
|
896
975
|
total_size = sys.getsizeof(self.FABuffer)
|
897
976
|
cur_size = len(self.FABuffer)
|
898
977
|
max_size = self.FABuffer.get_max_frames()
|
978
|
+
total_size = sys.getsizeof(selfimg) * cur_size
|
899
979
|
|
900
980
|
#if self.accum_buffer is not None:
|
901
981
|
# total_size = sys.getsizeof(self.accum_buffer) + sum(sys.getsizeof(arr) for arr in self.accum_buffer)
|
902
982
|
#BUF = f"BUF={self.accum_count:3d}/{self.accum_n:3d} {total_size/1024/1024:5.0f} MB"
|
903
|
-
|
904
|
-
|
983
|
+
bufshow = "( )"
|
984
|
+
if self.l_show_accum:
|
985
|
+
if self.l_show_accum_avg:
|
986
|
+
bufshow = "(AVG)"
|
987
|
+
else:
|
988
|
+
bufshow = "(SUM)"
|
989
|
+
else:
|
990
|
+
bufshow = "( )"
|
991
|
+
|
992
|
+
BUF = f"BUF{bufshow}={cur_size:3d}/{max_size:3d} {total_size/1024/1024:5.0f} MB"
|
905
993
|
#
|
994
|
+
#*********************************** HERE I CONTRUCT THE BOTTOM LINE ***********************
|
906
995
|
#
|
907
|
-
overtext = f"{self.frame_time} # {self.frame_num} # {self.l_frame_num:6d} # {RXT} . {ZOO} . {ROO} . {LGA} . {SAV} {FIT} . {BUF}. {LAPS}"
|
996
|
+
#overtext = f"{self.frame_time} # {self.frame_num} # {self.l_frame_num:6d} # {RXT} . {ZOO} . {ROO} . {LGA} . {SAV} {FIT} . {BUF}. {LAPS}"
|
997
|
+
# SAVING is already red
|
998
|
+
overtext = f"{self.frame_time} # {self.frame_num} # {self.l_frame_num:6d} # {RXT} . {ZOO} . {ROO} . {LGA} . {FIT} . {BUF}. {LAPS}"
|
999
|
+
# ROTATE IS LOCAL
|
1000
|
+
overtext = f"{self.frame_time} # {self.frame_num} # {self.l_frame_num:6d} # {RXT} . {ZOO} . {LGA} . {FIT} . {BUF}. {LAPS}"
|
908
1001
|
#
|
909
1002
|
position = ( 0, selfimg.shape[0]-1 ) # 480 on x-axis
|
910
1003
|
#
|
@@ -930,7 +1023,7 @@ class StreamWidget(QLabel):
|
|
930
1023
|
position = ( selfimg.shape[1] - 20, selfimg.shape[0]-1 ) # 480 on x-axis
|
931
1024
|
selfimg = iprint(selfimg, f"SAVE", font=font, position=position,color_rgb=(0,0,255) ) # bgr
|
932
1025
|
self.img = selfimg
|
933
|
-
|
1026
|
+
|
934
1027
|
|
935
1028
|
|
936
1029
|
|
@@ -1117,8 +1210,11 @@ class StreamWidget(QLabel):
|
|
1117
1210
|
mycnt += 1
|
1118
1211
|
fff = fname1.replace(".jpg", f"_{mycnt:03d}.jpg")
|
1119
1212
|
print(fff)
|
1213
|
+
# ----------------------- Overtext shoud be IMPROVED FOR DUMPED BUFFER
|
1120
1214
|
if self.flag_print_over:
|
1121
|
-
self.overtext(blackbar=True) # ---- after ACCUM ------------------ img should be tagged
|
1215
|
+
self.overtext(blackbar=True, image=i) # ---- after ACCUM ------------------ img should be tagged
|
1216
|
+
i = self.img
|
1217
|
+
print(fg.magenta, "D... simple save - overtext solved ", fg.default, end="\n")
|
1122
1218
|
if self.saving_jpg:
|
1123
1219
|
cv2.imwrite(fff, i, [int(cv2.IMWRITE_JPEG_QUALITY), 90])
|
1124
1220
|
else:
|
@@ -1126,15 +1222,43 @@ class StreamWidget(QLabel):
|
|
1126
1222
|
pass
|
1127
1223
|
# -----------------------------------------------
|
1128
1224
|
elif (not dumpbuffer) and (not self.l_show_accum):
|
1225
|
+
print(fg.magenta, "D... simple save overtext is there", fg.default)
|
1129
1226
|
# This is a simple save
|
1130
1227
|
if self.saving_jpg:
|
1131
1228
|
cv2.imwrite(fname1, self.img, [int(cv2.IMWRITE_JPEG_QUALITY), 90])
|
1132
1229
|
else:
|
1133
1230
|
cv2.imwrite(fname1.replace("jpg", "png"), self.img )
|
1134
1231
|
elif (dumpbuffer) and (self.l_show_accum):
|
1135
|
-
|
1136
|
-
|
1137
|
-
|
1232
|
+
# -....
|
1233
|
+
print(fg.magenta, "D... the trickies - save every Nth-every new buffer - IDK ", fg.default)
|
1234
|
+
elif (len(self.FABuffer) < 2) and (not dumpbuffer):# and (self.l_show_accum):
|
1235
|
+
# ....
|
1236
|
+
print(fg.magenta, f"D... buffer <1; cannot dump; save SUM {not self.l_show_accum_avg} or AVG {self.l_show_accum_avg}", fg.default)
|
1237
|
+
mymean = None
|
1238
|
+
if self.l_show_accum_avg: # not sum
|
1239
|
+
mymean = self.FABuffer.get_avg_frames()
|
1240
|
+
else:# # yes sum
|
1241
|
+
mymean = self.FABuffer.get_sum_frames()
|
1242
|
+
# NO OVERTEXT ! ! ! ! ! ! SOLVED
|
1243
|
+
if self.flag_print_over:
|
1244
|
+
self.overtext(blackbar=True, image=mymean)
|
1245
|
+
mymean = self.img
|
1246
|
+
if self.saving_jpg:
|
1247
|
+
cv2.imwrite(fname1, mymean, [int(cv2.IMWRITE_JPEG_QUALITY), 90])
|
1248
|
+
else:
|
1249
|
+
cv2.imwrite(fname1.replace("jpg", "png"), mymean )
|
1250
|
+
elif (len(self.FABuffer) > 1) and (not dumpbuffer):# and (self.l_show_accum):
|
1251
|
+
# ....
|
1252
|
+
print(fg.magenta, "D... buffer >1; do not dump; save SUM or AVG", fg.default)
|
1253
|
+
mymean = None
|
1254
|
+
if self.l_show_accum_avg: # not sum
|
1255
|
+
mymean = self.FABuffer.get_avg_frames()
|
1256
|
+
else:# # yes sum
|
1257
|
+
mymean = self.FABuffer.get_sum_frames()
|
1258
|
+
# NO OVERTEXT ! ! ! ! ! ! SOLVED
|
1259
|
+
if self.flag_print_over:
|
1260
|
+
self.overtext(blackbar=True, image=mymean)
|
1261
|
+
mymean = self.img
|
1138
1262
|
if self.saving_jpg:
|
1139
1263
|
cv2.imwrite(fname1, mymean, [int(cv2.IMWRITE_JPEG_QUALITY), 90])
|
1140
1264
|
else:
|
@@ -1172,28 +1296,6 @@ class StreamWidget(QLabel):
|
|
1172
1296
|
#
|
1173
1297
|
# --------------------------------------------------
|
1174
1298
|
|
1175
|
-
# def make_strips(self):
|
1176
|
-
# """
|
1177
|
-
# creates self.img and strips, increments istrip and resets it
|
1178
|
-
# """
|
1179
|
-
# global istrip
|
1180
|
-
# width, height = 640, 480
|
1181
|
-
# self.img = np.zeros((height, width, 3), dtype=np.uint8)
|
1182
|
-
# strip_height = 64
|
1183
|
-
# istrip += 1
|
1184
|
-
# if istrip > strip_height * 2:
|
1185
|
-
# istrip = 0
|
1186
|
-
|
1187
|
-
# if int(istrip / strip_height) % 2== 0:
|
1188
|
-
# self.img[0 :0+min(istrip, strip_height), :] = (55, 55, 0) # Red strip (BGR)
|
1189
|
-
# else:
|
1190
|
-
# self.img[0 :0+min(istrip, strip_height), :] = (55, 150, 0) # Red strip (BGR)
|
1191
|
-
# self.img[min(istrip, strip_height):2 * strip_height, :] = (55, 55, 0) # Red strip (BGR)
|
1192
|
-
|
1193
|
-
# # Draw red and green horizontal strips
|
1194
|
-
# for i in range(0, height, strip_height * 2):
|
1195
|
-
# self.img[i + istrip:i+strip_height+ istrip, :] = (55, 150, 0) # Red strip (BGR)
|
1196
|
-
# self.img[i+strip_height+ istrip:i+ istrip+strip_height*2, :] = (55, 55, 0) # Green strip
|
1197
1299
|
|
1198
1300
|
|
1199
1301
|
# ================================================================================
|
@@ -1251,7 +1353,7 @@ class StreamWidget(QLabel):
|
|
1251
1353
|
|
1252
1354
|
def update_image(self):
|
1253
1355
|
"""
|
1254
|
-
Stream Widget!!!!! self==stream technically takes img and put pixmap
|
1356
|
+
QT6 - Stream Widget!!!!! self==stream technically takes img and put pixmap
|
1255
1357
|
"""
|
1256
1358
|
|
1257
1359
|
if self.rgb_image is None:return # 1st contact may no exist
|
@@ -1388,6 +1490,11 @@ class StreamWidget(QLabel):
|
|
1388
1490
|
#cv2.waitKey(0)
|
1389
1491
|
#cv2.destroyAllWindows()
|
1390
1492
|
|
1493
|
+
|
1494
|
+
# ================================================================================
|
1495
|
+
# COPY FRAME TO IMG .................
|
1496
|
+
# --------------------------------------------------------------------------------
|
1497
|
+
|
1391
1498
|
def use_frame(self, stripes=False):
|
1392
1499
|
"""
|
1393
1500
|
put frame on tom of img .... ONLY THIS .....
|
@@ -1408,7 +1515,7 @@ class StreamWidget(QLabel):
|
|
1408
1515
|
# ___________________ vvv started, make gray strips _____________________________
|
1409
1516
|
ret_val = False
|
1410
1517
|
if True:# self.img.shape == self.frame.shape:
|
1411
|
-
self.img = self.frame
|
1518
|
+
self.img = self.frame.copy()
|
1412
1519
|
if stripes: # These are thin gray
|
1413
1520
|
#self.vcr_pal_style(["NO SIGNAL"])
|
1414
1521
|
for y in range(0, self.img.shape[0], 16):
|
@@ -1417,25 +1524,6 @@ class StreamWidget(QLabel):
|
|
1417
1524
|
#
|
1418
1525
|
return ret_val
|
1419
1526
|
|
1420
|
-
|
1421
|
-
# ==================================================
|
1422
|
-
# FETCHING THE IMAGE FROM VIDEODEV AND ALL LOCAL-ACTIONS ------------ ALSO INITIATING THE STREAM ------------
|
1423
|
-
# --------------------------------------------------
|
1424
|
-
|
1425
|
-
def fetch_and_update(self): # * * * ** * * * * * * * * * * * * * * * * * * * * * * * * * *
|
1426
|
-
"""
|
1427
|
-
main operation with image:: fetch_and_update + update_only
|
1428
|
-
"""
|
1429
|
-
ret = None
|
1430
|
-
#print(f".... fau : {self.internet_not_device} ")
|
1431
|
-
if self.internet_not_device:
|
1432
|
-
ret = self.fetch_only()
|
1433
|
-
else:
|
1434
|
-
#resol = "640x480"
|
1435
|
-
#resol = "1920x1080"
|
1436
|
-
ret = self.capture_only(self.resolution)
|
1437
|
-
self.update_only(ret)
|
1438
|
-
|
1439
1527
|
# ================================================================================
|
1440
1528
|
# CLICK TRICK to recover resolution in CLI
|
1441
1529
|
# --------------------------------------------------------------------------------
|
@@ -1495,16 +1583,18 @@ class StreamWidget(QLabel):
|
|
1495
1583
|
if not ret:
|
1496
1584
|
return False
|
1497
1585
|
print(f" ... {self.frame_time} ; resolution /{self.frame.shape}/ .... ", end="")
|
1498
|
-
|
1499
|
-
|
1500
|
-
|
1586
|
+
# ADD ONE FRAME !!!!!!!!
|
1587
|
+
self.l_frame_num += 1
|
1588
|
+
#avg = self.frame # once per Nx it is AVG
|
1589
|
+
#self.img = avg # normally frame. but sometimes avg == really averaged img!
|
1590
|
+
self.img = self.frame.copy()
|
1501
1591
|
return True
|
1502
1592
|
|
1503
1593
|
|
1504
1594
|
|
1505
1595
|
|
1506
1596
|
# ==================================================
|
1507
|
-
# FETCHING THE IMAGE FROM VIDEODEV ------------ ALSO INITI
|
1597
|
+
# FETCHING THE IMAGE FROM internet VIDEODEV ------------ ALSO INITI
|
1508
1598
|
# --------------------------------------------------
|
1509
1599
|
|
1510
1600
|
def fetch_only(self):
|
@@ -1512,7 +1602,7 @@ class StreamWidget(QLabel):
|
|
1512
1602
|
called from from fetch_and_update() / returns BOOL
|
1513
1603
|
"""
|
1514
1604
|
ret_val = False
|
1515
|
-
if self.stream is None:
|
1605
|
+
if self.stream is None: # INITIALIZE THE STREAM -----------------
|
1516
1606
|
#self.make_strips()
|
1517
1607
|
self.stream = self.get_stream(videodev=self.url)
|
1518
1608
|
if self.stream is not None:
|
@@ -1543,6 +1633,7 @@ class StreamWidget(QLabel):
|
|
1543
1633
|
self.t_lasread = self.l_frame_time
|
1544
1634
|
self.l_frame_time = dt.datetime.now()
|
1545
1635
|
delta_frame = (self.l_frame_time - self.t_lasread).total_seconds() # TOTAL
|
1636
|
+
self.l_frame_num += 1 # INCREMENT LOCAL FRAME NUMBER
|
1546
1637
|
#
|
1547
1638
|
print(f" ; {self.stream_length/delta_frame/1024/1024*8:4.2f} Mbs .. buffer tot= {len(self.bytex)/1024:4.1f} kB; Reading:{delta_read:4.2f} s.; TOT {str(delta_frame)[:4]} s.; Duty {int((delta_frame-delta_read)/delta_frame*100):3.0f} % ", end="")
|
1548
1639
|
#
|
@@ -1603,6 +1694,178 @@ class StreamWidget(QLabel):
|
|
1603
1694
|
return ret_val
|
1604
1695
|
|
1605
1696
|
|
1697
|
+
|
1698
|
+
# ==================================================
|
1699
|
+
# FETCHING THE IMAGE FROM ------------ MQTT
|
1700
|
+
# --------------------------------------------------
|
1701
|
+
|
1702
|
+
|
1703
|
+
|
1704
|
+
def decode_payload(self, data):
|
1705
|
+
"""
|
1706
|
+
MUST BE SAME AS SENDER
|
1707
|
+
"""
|
1708
|
+
header_size = struct.calcsize('!HHQddIfff') # SAME CODE 2x
|
1709
|
+
width, height, framenumber, timestamp_ts, recording_started_ts, _, exposition, gain, gamma = struct.unpack('!HHQddIfff', data[:header_size])
|
1710
|
+
image = np.frombuffer(data[header_size:], dtype=np.uint8).reshape((height, width, 3))
|
1711
|
+
timestamp = dt.datetime.fromtimestamp(timestamp_ts)
|
1712
|
+
recording_started = dt.datetime.fromtimestamp(recording_started_ts)
|
1713
|
+
return {
|
1714
|
+
'width': width,
|
1715
|
+
'height': height,
|
1716
|
+
'framenumber': framenumber,
|
1717
|
+
'timestamp': timestamp,
|
1718
|
+
'recording_started': recording_started,
|
1719
|
+
'exposition': exposition,
|
1720
|
+
'gain': gain,
|
1721
|
+
'gamma': gamma,
|
1722
|
+
'image': image
|
1723
|
+
}
|
1724
|
+
|
1725
|
+
|
1726
|
+
def on_message(self, client, userdata, msg):
|
1727
|
+
"""
|
1728
|
+
just copy content to frame and set flag
|
1729
|
+
"""
|
1730
|
+
data = msg.payload
|
1731
|
+
#width, height = struct.unpack('!HH', data[:4])
|
1732
|
+
#image = np.frombuffer(data[4:], dtype=np.uint8).reshape((height, width, 3))
|
1733
|
+
#####image = np.frombuffer(data, dtype=np.uint8).reshape((480, 640, 3))
|
1734
|
+
data_block = self.decode_payload(data)
|
1735
|
+
self.frame_num = data_block['framenumber']
|
1736
|
+
self.frame_time = str(data_block['timestamp'])[:-4]
|
1737
|
+
#print(f"i... mqtt image: shape={image.shape} time={dt.datetime.now()}", end="\r" )
|
1738
|
+
self.frame = data_block['image'].copy()
|
1739
|
+
self.mqtt_new_image = True
|
1740
|
+
#print( flush=True)
|
1741
|
+
#cv2.imshow("Received Image", image)
|
1742
|
+
#cv2.waitKey(10) # Needed to refresh window
|
1743
|
+
|
1744
|
+
def subscribe_only(self):
|
1745
|
+
"""
|
1746
|
+
called from from fetch_and_update() / returns BOOL / I want to read image via mqtt 1883
|
1747
|
+
"""
|
1748
|
+
if not self.mqtt_subscribed:
|
1749
|
+
#self.mqtt_broker = "10.10.104.17"
|
1750
|
+
#self.mqtt_topic = "image/raw"
|
1751
|
+
|
1752
|
+
self.mqtt_client = mqtt.Client()
|
1753
|
+
self.mqtt_client.on_message = self.on_message
|
1754
|
+
|
1755
|
+
self.mqtt_client.connect(self.url, 1883, 60) # 60 seconds?
|
1756
|
+
self.mqtt_client.subscribe(self.mqtt_topic)
|
1757
|
+
print("i... ... looping inside thread... on_message active")
|
1758
|
+
self.mqtt_subscribed = True
|
1759
|
+
# Start loop in a separate thread to handle network traffic
|
1760
|
+
thread = threading.Thread(target=self.mqtt_client.loop_start)
|
1761
|
+
thread.daemon = True
|
1762
|
+
thread.start()
|
1763
|
+
#self.mqtt_client.loop_forever()
|
1764
|
+
|
1765
|
+
else:# ==================== it is subscribed =========================
|
1766
|
+
# just loop-wait for a new image
|
1767
|
+
#while True:
|
1768
|
+
#print(self.mqtt_new_image)
|
1769
|
+
if self.mqtt_new_image: # ALL ACTION HERE - use_frame; franum++ ....
|
1770
|
+
self.mqtt_new_image = False
|
1771
|
+
self.use_frame() # i copy grame
|
1772
|
+
self.l_frame_num += 1
|
1773
|
+
self.error = False
|
1774
|
+
else:
|
1775
|
+
time.sleep(0.02)
|
1776
|
+
# return False
|
1777
|
+
#break
|
1778
|
+
#time.sleep(0.1)
|
1779
|
+
return True
|
1780
|
+
|
1781
|
+
|
1782
|
+
|
1783
|
+
# ==================================================
|
1784
|
+
# FETCHING THE IMAGE FROM VIDEODEV AND ALL LOCAL-ACTIONS ------------ ALSO INITIATING THE STREAM ------------
|
1785
|
+
#
|
1786
|
+
# I think the main function here is fetch_and_update #
|
1787
|
+
# - when IP, it does fetch, when not, it grabs image.
|
1788
|
+
# -
|
1789
|
+
#
|
1790
|
+
# --------------------------------------------------
|
1791
|
+
|
1792
|
+
def fetch_and_update(self): # * * * ** * * * * * * * * * * * * * * * * * * * * * * * * * *
|
1793
|
+
"""
|
1794
|
+
main operation with image:: fetch_and_update + update_only
|
1795
|
+
"""
|
1796
|
+
ret = None
|
1797
|
+
#print(f".... fau : {self.internet_not_device} ")
|
1798
|
+
if self.internet_not_device:
|
1799
|
+
if self.internet_mqtt:
|
1800
|
+
ret = self.subscribe_only() # MQTT
|
1801
|
+
else:
|
1802
|
+
ret = self.fetch_only() # just normaly fetch
|
1803
|
+
else:
|
1804
|
+
#resol = "640x480"
|
1805
|
+
#resol = "1920x1080"
|
1806
|
+
ret = self.capture_only(self.resolution)
|
1807
|
+
self.update_only(ret)
|
1808
|
+
|
1809
|
+
|
1810
|
+
# #!/usr/bin/env python3
|
1811
|
+
# import struct
|
1812
|
+
# import paho.mqtt.client as mqtt
|
1813
|
+
# import numpy as np
|
1814
|
+
# import datetime as dt
|
1815
|
+
# import time
|
1816
|
+
|
1817
|
+
# def provide(width, height):
|
1818
|
+
# # Create colorful structured image with gradients and sinusoidal patterns
|
1819
|
+
|
1820
|
+
# x = np.linspace(0, 4 * np.pi, width)
|
1821
|
+
# y = np.linspace(0, 4 * np.pi, height)
|
1822
|
+
# X, Y = np.meshgrid(x, y)
|
1823
|
+
# r = ((np.sin(X) + 1) * 127).astype(np.uint8)
|
1824
|
+
# g = ((np.cos(Y) + 1) * 127).astype(np.uint8)
|
1825
|
+
# b = ((np.sin(X + Y) + 1) * 127).astype(np.uint8)
|
1826
|
+
|
1827
|
+
# # Randomize grid frequency and color amplitude
|
1828
|
+
# freq_x = np.random.uniform(2, 6)
|
1829
|
+
# freq_y = np.random.uniform(2, 6)
|
1830
|
+
# amp = np.random.uniform(80, 150)
|
1831
|
+
# x = np.linspace(0, freq_x * np.pi, width)
|
1832
|
+
# y = np.linspace(0, freq_y * np.pi, height)
|
1833
|
+
# X, Y = np.meshgrid(x, y)
|
1834
|
+
# r = ((np.sin(X) + 1) * amp / 2).clip(0, 255).astype(np.uint8 )
|
1835
|
+
# g = ((np.cos(Y) + 1) * amp / 2).clip(0, 255).astype(np.uint8)
|
1836
|
+
# b = ((np.sin(X + Y) + 1) * amp / 2).clip(0, 255).astype(np.uint8)
|
1837
|
+
# image = np.stack((r, g, b), axis=2)
|
1838
|
+
# # Add random noise element
|
1839
|
+
# #noise = np.random.randint(0, 50, (height, width, 3), dtype=np.uint8)
|
1840
|
+
# #image = np.clip(image + noise, 0, 255).astype(np.uint8)
|
1841
|
+
# return image
|
1842
|
+
|
1843
|
+
# broker = "127.0.0.1"
|
1844
|
+
# topic = "image/raw"
|
1845
|
+
|
1846
|
+
# client = mqtt.Client()
|
1847
|
+
# client.connect(broker, 1883, 10)
|
1848
|
+
|
1849
|
+
# for i in range(100):
|
1850
|
+
|
1851
|
+
# # Create dummy image
|
1852
|
+
# #image = np.random.randint(0, 256, (480, 640, 3), dtype=np.uint8)
|
1853
|
+
# height,width=1080,1920
|
1854
|
+
# height,width=480,640
|
1855
|
+
# header = struct.pack('!HH', width, height) # Network byte order
|
1856
|
+
# #image = np.random.randint(0, 256, (height, width, 3), dtype=np.uint8)
|
1857
|
+
# image=provide(width, height)
|
1858
|
+
# payload = header + image.tobytes()
|
1859
|
+
# # Send raw bytes
|
1860
|
+
# print(dt.datetime.now())
|
1861
|
+
# result=client.publish(topic, payload )
|
1862
|
+
# print(dt.datetime.now())
|
1863
|
+
# #result.wait_for_publish() # Ensure message is sent before continuing
|
1864
|
+
# #print(dt.datetime.now())
|
1865
|
+
# time.sleep(0.96)
|
1866
|
+
|
1867
|
+
# client.disconnect()
|
1868
|
+
|
1606
1869
|
##################################################################
|
1607
1870
|
# # m mmmm mm m m #
|
1608
1871
|
# m m mmmm mmm# mmm mm#mm mmm m" "m #"m # # #
|
@@ -1615,8 +1878,6 @@ class StreamWidget(QLabel):
|
|
1615
1878
|
|
1616
1879
|
|
1617
1880
|
|
1618
|
-
|
1619
|
-
|
1620
1881
|
# ================================================================================
|
1621
1882
|
# All the traNSFORMS and saves are here
|
1622
1883
|
# --------------------------------------------------------------------------------
|
@@ -1630,9 +1891,10 @@ class StreamWidget(QLabel):
|
|
1630
1891
|
# ___________________________ after this point - NO REFERENCE TO FRAME ***** only img *********************
|
1631
1892
|
# ___________________________________ whatever, RET VAL ------------RET VAL ------------RET VAL ------------
|
1632
1893
|
if ret_val and not self.error: # OK
|
1894
|
+
# IMG SHOULD BE HERE READY!!!!!!!!!!!!
|
1633
1895
|
|
1634
|
-
self.l_frame_num += 1
|
1635
|
-
#print(self.l_frame_num)
|
1896
|
+
#self.l_frame_num += 1 # NOT GOOD!!!!!!!!!!!!!!!
|
1897
|
+
#print("D... ... franum", self.l_frame_num)
|
1636
1898
|
|
1637
1899
|
# ------------------------- calculate bias to see lost frames count ----------------------
|
1638
1900
|
# no change to frame
|
@@ -1686,8 +1948,8 @@ class StreamWidget(QLabel):
|
|
1686
1948
|
rimg = self.FABuffer.get_avg_frames()#_mean_accum_buffer()
|
1687
1949
|
else:
|
1688
1950
|
rimg = self.FABuffer.get_sum_frames()#_mean_accum_buffer()
|
1689
|
-
|
1690
|
-
|
1951
|
+
#print("\n new", type(rimg))
|
1952
|
+
print(f"SATURATED: {self.FABuffer.get_saturated_pixel_count()}", end="") # only for SUM
|
1691
1953
|
else:
|
1692
1954
|
rimg = self.FABuffer.get_previous_sum_frames()#_mean_accum_buffer()
|
1693
1955
|
#print("\n----pre", type(rimg))
|
@@ -1730,92 +1992,129 @@ class StreamWidget(QLabel):
|
|
1730
1992
|
|
1731
1993
|
# ---- just save once -------------------- ************ "s" ***********
|
1732
1994
|
if self.saving_once:
|
1733
|
-
# jpg and NO AVG
|
1995
|
+
# jpg and NO AVG --------- No difference show_accum_not_showaccum if frabuffer ==1
|
1734
1996
|
if (len(self.FABuffer) < 2) and (not self.l_show_accum) and (not self.saving_fits_only):
|
1735
1997
|
# no bufffer no loopshow no fits
|
1998
|
+
print(f"\ni... {fg.red}SAVING ONE 1 B1 NOshac{fg.default}")
|
1999
|
+
self.save_img( time_tag=self.frame_time , dumpbuffer=False, use_fits=False ) # one simple image
|
2000
|
+
#print(fg.magenta, "\ns1 b1 shac", fg.default, end="\n")
|
2001
|
+
self.saving_once = False
|
2002
|
+
elif (len(self.FABuffer) < 2) and (self.l_show_accum) and (not self.saving_fits_only):
|
2003
|
+
# no bufffer no loopshow no fits
|
2004
|
+
print()
|
2005
|
+
print(f"i... {fg.red}SAVING ONE 2 B1 shac{fg.default}")
|
1736
2006
|
self.save_img( time_tag=self.frame_time , dumpbuffer=False, use_fits=False ) # one simple image
|
1737
|
-
print(fg.red, "
|
2007
|
+
#print(fg.red, "\ns1", fg.default, end="\n")
|
1738
2008
|
self.saving_once = False
|
1739
2009
|
# jpg and NO AVG
|
1740
2010
|
elif (len(self.FABuffer) >= 2) and (not self.l_show_accum) and (not self.saving_fits_only):
|
2011
|
+
print()
|
2012
|
+
print(fg.red, "SAVING ONE 3 B2+ NOshac ", fg.default, end="\n")
|
1741
2013
|
self.save_img( time_tag=self.frame_time, dumpbuffer=False, use_fits=False ) # save one simple image only
|
1742
|
-
print(fg.red, "s1", fg.default, end="")
|
1743
2014
|
self.saving_once = False
|
1744
2015
|
# jpg and AVG
|
1745
2016
|
elif (len(self.FABuffer) < 2) and (self.l_show_accum) and (not self.saving_fits_only):
|
1746
2017
|
# no bufffer no loopshow no fits
|
2018
|
+
print()
|
2019
|
+
print(fg.red, "SAVING ONE 4 B1 shac ", fg.default, end="\n")
|
1747
2020
|
self.save_img( time_tag=self.frame_time, dumpbuffer=False, use_fits=False ) # just one simple image /lshow inside
|
1748
|
-
print(fg.red, "F1", fg.default, end="")
|
2021
|
+
#print(fg.red, "F1", fg.default, end="")
|
1749
2022
|
self.saving_once = False
|
1750
2023
|
pass
|
1751
2024
|
# jpg and AVG
|
1752
2025
|
elif (len(self.FABuffer) >= 2) and (self.l_show_accum) and (not self.saving_fits_only):
|
1753
2026
|
# no bufffer no loopshow no fits
|
1754
2027
|
#if self.accum_index >= len(self.FABuffer) - 1:
|
2028
|
+
print()
|
2029
|
+
print(fg.red, "SAVING ONE 5 B2+ shac ", fg.default, end="\n")
|
1755
2030
|
self.save_img( time_tag=self.frame_time, dumpbuffer=False, use_fits=False ) # should be 1 AVG IMG
|
1756
|
-
print(fg.red, "F1", fg.default, end="")
|
2031
|
+
#print(fg.red, "F1", fg.default, end="")
|
1757
2032
|
self.saving_once = False
|
1758
2033
|
# FITS and NO AVG ---------------------------------------------------------------------------- FITS
|
1759
2034
|
elif (len(self.FABuffer) < 2) and (not self.l_show_accum) and (self.saving_fits_only):
|
1760
2035
|
# no bufffer no loopshow YES fits
|
2036
|
+
print()
|
2037
|
+
print(fg.red, "SAVING ONE 6 B1 NOshac ", fg.default, end="\n")
|
1761
2038
|
self.save_img( time_tag=self.frame_time , dumpbuffer=False, use_fits=True ) # 1 img
|
1762
|
-
print(fg.red, "F1", fg.default, end="")
|
2039
|
+
#print(fg.red, "F1", fg.default, end="")
|
1763
2040
|
self.saving_once = False
|
1764
2041
|
pass
|
1765
2042
|
# FITS and NO AVG
|
1766
2043
|
elif (len(self.FABuffer) >= 2) and (not self.l_show_accum) and (self.saving_fits_only):
|
1767
2044
|
# no bufffer no loopshow no fits
|
2045
|
+
print(fg.red, "SAVING ONE 7 B2 NOshac ", fg.default, end="\n")
|
1768
2046
|
self.save_img( time_tag=self.frame_time , dumpbuffer=True, use_fits=True ) # dump buffer once
|
1769
|
-
print(fg.red, "F1", fg.default, end="")
|
2047
|
+
#print(fg.red, "F1", fg.default, end="")
|
1770
2048
|
self.saving_once = False
|
1771
2049
|
pass
|
1772
2050
|
# FITS and avg
|
1773
2051
|
elif (len(self.FABuffer) < 2) and (self.l_show_accum) and (self.saving_fits_only):
|
1774
2052
|
# no bufffer no loopshow no fits
|
2053
|
+
print()
|
2054
|
+
print(fg.red, "SAVING ONE 8 B1 shac ", fg.default, end="\n")
|
1775
2055
|
self.save_img( time_tag=self.frame_time , dumpbuffer=False, use_fits=True ) # one AVG
|
1776
|
-
print(fg.red, "F1", fg.default, end="")
|
2056
|
+
#print(fg.red, "F1", fg.default, end="")
|
1777
2057
|
self.saving_once = False
|
1778
2058
|
pass
|
1779
2059
|
# FITS and avg there are more
|
1780
2060
|
elif (len(self.FABuffer) >= 2) and (self.l_show_accum) and (self.saving_fits_only):
|
1781
2061
|
# no bufffer no loopshow no fits
|
1782
2062
|
#if self.accum_index >= len(self.FABuffer) - 1:
|
2063
|
+
print()
|
2064
|
+
print(fg.red, "SAVING ONE 9 B2+ shac ", fg.default, end="\n")
|
1783
2065
|
self.save_img( time_tag=self.frame_time , dumpbuffer=False, use_fits=True ) # many AVG IDK
|
1784
|
-
print(fg.red, "F1", fg.default, end="")
|
2066
|
+
#print(fg.red, "F1", fg.default, end="")
|
1785
2067
|
self.saving_once = False
|
1786
2068
|
|
1787
2069
|
|
1788
2070
|
# ---- save ALL ----------------- -------------------------------------------- ************ "shift-s" ***********
|
1789
2071
|
# ---- save ALL ----------------- -------------------------------------------- ************ "shift-s" ***********
|
1790
|
-
if self.saving_all: # --------------- Shift-S-------
|
2072
|
+
if self.saving_all: # --------------- Shift-S------- ALWAYS PUT RED
|
1791
2073
|
|
1792
|
-
# jpg and NO AVG
|
1793
|
-
if (len(self.FABuffer) < 2)
|
2074
|
+
# jpg and NO AVG when no frbuffer, showaccum makes no sense
|
2075
|
+
if (len(self.FABuffer) < 2) and (not self.l_show_accum) and (not self.saving_fits_only):
|
2076
|
+
print()
|
2077
|
+
print(fg.red, "D... SALL 1 B1 NOshaccum NOdump", fg.default, f"{bg.red}{fg.white}!!ALL-1!!{bg.default}{fg.default}", end="\n")
|
2078
|
+
self.save_img( time_tag=self.frame_time, dumpbuffer=False, use_fits=False) # every frame, BURSTING JPGS!
|
2079
|
+
elif (len(self.FABuffer) < 2) and (self.l_show_accum) and (not self.saving_fits_only):
|
2080
|
+
print()
|
2081
|
+
print(fg.red, "D... SALL 2 B1 shaccum NOdump", fg.default, f"{bg.red}{fg.white}!!ALL-2!!{bg.default}{fg.default}", end="\n")
|
1794
2082
|
self.save_img( time_tag=self.frame_time, dumpbuffer=False, use_fits=False) # every frame, BURSTING JPGS!
|
1795
|
-
print(fg.red, "s!", fg.default, f"{bg.red}{fg.white}!!!!!!!!!!!!{bg.default}{fg.default}", end="\n")
|
1796
2083
|
# jpg and NO AVG
|
1797
2084
|
elif (len(self.FABuffer) >= 2) and (not self.l_show_accum) and (not self.saving_fits_only):
|
2085
|
+
print()
|
2086
|
+
print(fg.red, "D... SALL 3 B2+ NOshac DUMP", fg.default, end="\n") # ONE DUMP
|
1798
2087
|
self.save_img( time_tag=self.frame_time, dumpbuffer=True, use_fits=False ) # Dump Full Buffer and stop
|
1799
|
-
print(fg.red, "s-FuB DUMPED", fg.default, end="\n") # ONE DUMP
|
1800
2088
|
self.saving_all = False
|
1801
2089
|
# jpg and AVG
|
1802
2090
|
elif (len(self.FABuffer) < 2) and (self.l_show_accum) and (not self.saving_fits_only):
|
1803
2091
|
# no bufffer no loopshow no fits
|
1804
2092
|
#self.save_img( time_tag=self.frame_time, dumpbuffer=False, use_fits=False ) # just one simple image /lshow inside
|
2093
|
+
print()
|
2094
|
+
print(fg.red, "D... SALL 4 B1 shaccum / switching OFF saving all but not saving", fg.default, end="\n") # ???
|
1805
2095
|
self.saving_all = False
|
1806
2096
|
pass
|
1807
2097
|
# jpg and AVG
|
1808
|
-
elif (len(self.FABuffer) >= 2) and (self.l_show_accum) and (not self.saving_fits_only):
|
2098
|
+
elif (len(self.FABuffer) >= 2) and (self.l_show_accum) and (not self.saving_fits_only): # ??? newSUM x newAVG
|
2099
|
+
#
|
2100
|
+
#if self.l_show_accum_avg:
|
2101
|
+
# rimg = self.FABuffer.get_avg_frames()#_mean_accum_buffer()
|
2102
|
+
#
|
1809
2103
|
# no bufffer no loopshow no fits
|
1810
2104
|
#self.save_img( time_tag=self.frame_time, dumpbuffer=False, use_fits=False ) # should be AVG
|
1811
2105
|
#if self.accum_index >= len(self.FABuffer) - 1:
|
1812
2106
|
if self.FABuffer.new_sum_available():
|
2107
|
+
print()
|
2108
|
+
if self.l_show_accum_avg:
|
2109
|
+
print(fg.red, "D... SALL 5a shac Save AVG evry Nth ", fg.default, end="\n")
|
2110
|
+
else:
|
2111
|
+
print(fg.red, "D... SALL 5b Save SUM evry Nth ", fg.default, end="\n")
|
1813
2112
|
self.save_img( time_tag=self.frame_time, dumpbuffer=False, use_fits=False ) # Dump Full Buffer and stop
|
1814
|
-
print(fg.red, "Save SUM evry Nth ", fg.default, end="\n")
|
1815
2113
|
# FITS and NO AVG ---------------------------------------------------------------------------- FITS
|
1816
2114
|
# FITS and NO AVG ---------------------------------------------------------------------------- FITS
|
1817
2115
|
elif (len(self.FABuffer) < 2) and (not self.l_show_accum) and (self.saving_fits_only):
|
1818
|
-
print("
|
2116
|
+
print(fg.red, "D... SALL 6 fits for every image ... ", fg.default, end="\n")
|
2117
|
+
#print(" here fits for every image .... too low buffer --- so MAYBE ")
|
1819
2118
|
# no bufffer no loopshow YES fits
|
1820
2119
|
self.save_img( time_tag=self.frame_time, dumpbuffer=False, use_fits=True) # every frame, BURSTING FITS !?!?!
|
1821
2120
|
#print(fg.red, "every N frames to FITS-IDK", fg.default, f"{bg.red}{fg.white}???{bg.default}{fg.default}", end="\n")
|
@@ -1843,8 +2142,8 @@ class StreamWidget(QLabel):
|
|
1843
2142
|
#self.save_img( time_tag=self.frame_time , dumpbuffer=False, use_fits=True ) # many AVG IDK
|
1844
2143
|
if self.FABuffer.new_sum_available():
|
1845
2144
|
#if self.accum_index >= len(self.FABuffer) - 1: # ONLY THE ACCUM FRAME!
|
1846
|
-
self.save_img( time_tag=self.frame_time , dumpbuffer=False, use_fits=True ) # SIMPLIFIED
|
1847
2145
|
print(fg.red, "F-Every Nth-AVG to FITS -IDK", fg.default, end="")
|
2146
|
+
self.save_img( time_tag=self.frame_time , dumpbuffer=False, use_fits=True ) # SIMPLIFIED
|
1848
2147
|
###########################################################################################################################################
|
1849
2148
|
# if self.level2_buffer.get_frame_shape() != self.img.shape: #
|
1850
2149
|
# print(self.level2_buffer.get_frame_shape, self.img.shape) # CLEAR WHEN RES_CHANGE #
|
@@ -1878,6 +2177,7 @@ class StreamWidget(QLabel):
|
|
1878
2177
|
|
1879
2178
|
#
|
1880
2179
|
else:# --- NO IMAGE CREATED ------------------------------- ... make the image gray ...
|
2180
|
+
print(f" ret_val {ret_val} ... self.error {self.error} ")
|
1881
2181
|
#print("D... 3")
|
1882
2182
|
# Extra override with some frame
|
1883
2183
|
self.img = cv2.cvtColor(self.img, cv2.COLOR_BGR2GRAY)
|
@@ -1937,7 +2237,9 @@ class StreamWidget(QLabel):
|
|
1937
2237
|
#post_addr = self.url.replace("/video", "/cross") # FOR REMOTE COMMANDS
|
1938
2238
|
|
1939
2239
|
#print(" + ".join(parts), f" /{chr(key)}/ .... {parts_set}")
|
1940
|
-
|
2240
|
+
|
2241
|
+
|
2242
|
+
# ----------------------------------------------------------------- s savings - LOCAL ONLY !
|
1941
2243
|
if (key == Qt.Key.Key_S):
|
1942
2244
|
self.SAVED_NOW = True # red blink
|
1943
2245
|
if ( len(parts_set) == 0) :
|
@@ -1945,12 +2247,12 @@ class StreamWidget(QLabel):
|
|
1945
2247
|
self.saving_all = False
|
1946
2248
|
#self.saving_fits_only = False
|
1947
2249
|
#self.saving_jpg = True
|
1948
|
-
print("i... SAVING_ONCE IMAGE ")
|
2250
|
+
#print(f"i... {fg.red}SAVING_ONCE IMAGE {fg.default}")
|
1949
2251
|
#---------------- SHIFT-S: 1) IbufferON=> save every nth image; 2) ---
|
1950
2252
|
elif (parts_set == {'Shift'}):
|
1951
2253
|
self.saving_all = not self.saving_all
|
1952
2254
|
#self.saving_fits_only = False
|
1953
|
-
print(f"i... 'SAVING_all' SET TO {self.saving_all} !!!!!FITS=={self.saving_fits_only}!!!!!
|
2255
|
+
print(f"i... {fg.orange}'SAVING_all' SET TO {self.saving_all} !!!!!FITS=={self.saving_fits_only}!!!!! {fg.default}")
|
1954
2256
|
if self.saving_all:
|
1955
2257
|
print('ffmpeg -framerate 5 -pattern_type glob -i "*.jpg" -c:v libx264 -pix_fmt yuv420p output.mkv')
|
1956
2258
|
print('ffmpeg -hide_banner -y -framerate 5 -pattern_type glob -i "*.jpg" -c:v libx264 -pix_fmt yuv420p output.mkv')
|
@@ -1973,7 +2275,7 @@ class StreamWidget(QLabel):
|
|
1973
2275
|
else:
|
1974
2276
|
print(f"i... {fg.orange}PNG!{fg.default} SAVING_JPG set to {fg.cyan}{self.saving_jpg}{fg.default} (interval is {self.FITS_INTERVAL_SECONDS}) ; but 'SAVING_all' SET TO ", self.saving_all)
|
1975
2277
|
|
1976
|
-
#
|
2278
|
+
# ------------------------------ xtend x2 ot switchres resolution--- x XRES SWITCH - REMOTE - **SEND_COMMAND**
|
1977
2279
|
if (key == Qt.Key.Key_X):
|
1978
2280
|
if ( len(parts_set) == 0):
|
1979
2281
|
self.xtended = not self.xtended
|
@@ -1991,7 +2293,7 @@ class StreamWidget(QLabel):
|
|
1991
2293
|
self.send_command( data={"switch_res_off": "SWITCH_RES_OFF"})
|
1992
2294
|
print("D.... r_xtend == ' ' <<======== ", self.r_xtend)
|
1993
2295
|
|
1994
|
-
# ----------------------------------------------------------------- p printout
|
2296
|
+
# ----------------------------------------------------------------- p printout - LOCAL ONLY
|
1995
2297
|
if (key == Qt.Key.Key_P):
|
1996
2298
|
if ( len(parts_set) == 0):
|
1997
2299
|
self.flag_print = not self.flag_print
|
@@ -2002,7 +2304,7 @@ class StreamWidget(QLabel):
|
|
2002
2304
|
print(f"i... overtext: {self.flag_print_over}")
|
2003
2305
|
elif (parts_set == {'Ctrl'}) :
|
2004
2306
|
pass
|
2005
|
-
# ----------------------------------------------------------------- e expo
|
2307
|
+
# ----------------------------------------------------------------- e expo - REMOTE ONLY ! **SEND_COMMAND**
|
2006
2308
|
if (key == Qt.Key.Key_E):
|
2007
2309
|
if ( len(parts_set) == 0):
|
2008
2310
|
if self.r_expo < 1.0: self.r_expo += 0.02
|
@@ -2018,7 +2320,7 @@ class StreamWidget(QLabel):
|
|
2018
2320
|
self.send_command( data= {"expot": "EXPOT", "expotxt": -1.0} )
|
2019
2321
|
self.r_expodef = True
|
2020
2322
|
|
2021
|
-
# ----------------------------------------------------------------- g gain
|
2323
|
+
# ----------------------------------------------------------------- g gain - REMOTE ONLY ! **SEND_COMMAND**
|
2022
2324
|
if (key == Qt.Key.Key_G):
|
2023
2325
|
if ( len(parts_set) == 0):
|
2024
2326
|
if self.r_gain < 1.0: self.r_gain += 0.1
|
@@ -2038,7 +2340,7 @@ class StreamWidget(QLabel):
|
|
2038
2340
|
# self.send_command( data= {"gain05": "GAIN05"})
|
2039
2341
|
#elif (parts_set == {'Ctrl'}) :
|
2040
2342
|
# self.send_command( data= {"gain": "GAIN"} )
|
2041
|
-
# ----------------------------------------------------------------- y gamma
|
2343
|
+
# ----------------------------------------------------------------- y gamma - REMOTE ONLY ! **SEND_COMMAND**
|
2042
2344
|
if (key == Qt.Key.Key_Y):
|
2043
2345
|
if ( len(parts_set) == 0):
|
2044
2346
|
if self.r_gamma < 1.0: self.r_gamma += 0.1
|
@@ -2059,7 +2361,7 @@ class StreamWidget(QLabel):
|
|
2059
2361
|
# self.send_command( data= {"gamma05": "GAMMA05"})
|
2060
2362
|
#elif (parts_set == {'Ctrl'}) :
|
2061
2363
|
# self.send_command( data= {"gamma": "GAMMA"} )
|
2062
|
-
# ----------------------------------------------------------------- d local gamma
|
2364
|
+
# ----------------------------------------------------------------- d local gamma - LOCAL ONLY
|
2063
2365
|
if (key == Qt.Key.Key_D):
|
2064
2366
|
if ( len(parts_set) == 0):
|
2065
2367
|
self.l_gamma = self.l_gamma * 1.4
|
@@ -2068,7 +2370,7 @@ class StreamWidget(QLabel):
|
|
2068
2370
|
elif (parts_set == {'Ctrl'}) :
|
2069
2371
|
self.l_gamma = 1
|
2070
2372
|
|
2071
|
-
# ----------------------------------------------------------------- w
|
2373
|
+
# ----------------------------------------------------------------- w - Web Browser - LOCAL ONLY
|
2072
2374
|
if (key == Qt.Key.Key_W):
|
2073
2375
|
if ( len(parts_set) == 0):
|
2074
2376
|
webbrowser.open(self.url.replace("/video", "")) # BRUTAL
|
@@ -2076,7 +2378,7 @@ class StreamWidget(QLabel):
|
|
2076
2378
|
pass
|
2077
2379
|
elif (parts_set == {'Ctrl'}) :
|
2078
2380
|
pass
|
2079
|
-
# ----------------------------------------------------------------- z
|
2381
|
+
# ----------------------------------------------------------------- z - ZOOM - LOCAL ONLY !
|
2080
2382
|
if (key == Qt.Key.Key_Z):
|
2081
2383
|
if ( len(parts_set) == 0):
|
2082
2384
|
self.zoomme *= 1.5
|
@@ -2088,7 +2390,7 @@ class StreamWidget(QLabel):
|
|
2088
2390
|
if self.zoomme < 1: self.zoome= 1
|
2089
2391
|
elif (parts_set == {'Ctrl'}) :
|
2090
2392
|
self.zoomme = 1
|
2091
|
-
# ----------------------------------------------------------------- hjkl
|
2393
|
+
# ----------------------------------------------------------------- hjkl - H - **SEND_COMMAND** c-s-*
|
2092
2394
|
# self.send_command( data={"right": "RIGHT"})
|
2093
2395
|
if (key == Qt.Key.Key_H):
|
2094
2396
|
if ( len(parts_set) == 0):
|
@@ -2102,7 +2404,7 @@ class StreamWidget(QLabel):
|
|
2102
2404
|
if self.r_xtend[0] == "R": self.r_xtend = "C" + self.r_xtend[1:]
|
2103
2405
|
elif self.r_xtend[0] == "C": self.r_xtend = "L" + self.r_xtend[1:]
|
2104
2406
|
elif self.r_xtend[0] == " ": self.r_xtend = "L" + self.r_xtend[1:]
|
2105
|
-
# ----------------------------------------------------------------- hjkl
|
2407
|
+
# ----------------------------------------------------------------- hjkl - J **SEND_COMMAND** c-s-*
|
2106
2408
|
if (key == Qt.Key.Key_J):
|
2107
2409
|
if ( len(parts_set) == 0):
|
2108
2410
|
self.redcross[1] += 4 # DOWN
|
@@ -2115,7 +2417,7 @@ class StreamWidget(QLabel):
|
|
2115
2417
|
if self.r_xtend[1] == "U": self.r_xtend = self.r_xtend[:1] + "C"
|
2116
2418
|
elif self.r_xtend[1] == "C": self.r_xtend = self.r_xtend[:1] + "D"
|
2117
2419
|
elif self.r_xtend[1] == " ": self.r_xtend = self.r_xtend[:1] + "D"
|
2118
|
-
# ----------------------------------------------------------------- hjkl
|
2420
|
+
# ----------------------------------------------------------------- hjkl - K **SEND_COMMAND** c-s-*
|
2119
2421
|
if (key == Qt.Key.Key_K):
|
2120
2422
|
if ( len(parts_set) == 0):
|
2121
2423
|
self.redcross[1] -= 4 # UP
|
@@ -2128,7 +2430,7 @@ class StreamWidget(QLabel):
|
|
2128
2430
|
if self.r_xtend[1] == "D": self.r_xtend = self.r_xtend[:1] + "C"
|
2129
2431
|
elif self.r_xtend[1] == "C": self.r_xtend = self.r_xtend[:1] + "U"
|
2130
2432
|
elif self.r_xtend[1] == " ": self.r_xtend = self.r_xtend[:1] + "U"
|
2131
|
-
# ----------------------------------------------------------------- hjkl
|
2433
|
+
# ----------------------------------------------------------------- hjkl - L **SEND_COMMAND** c-s-*
|
2132
2434
|
if (key == Qt.Key.Key_L):
|
2133
2435
|
if ( len(parts_set) == 0):
|
2134
2436
|
self.redcross[0] += 4
|
@@ -2141,7 +2443,7 @@ class StreamWidget(QLabel):
|
|
2141
2443
|
if self.r_xtend[0] == "L": self.r_xtend = "C" + self.r_xtend[1:]
|
2142
2444
|
elif self.r_xtend[0] == "C": self.r_xtend = "R" + self.r_xtend[1:]
|
2143
2445
|
elif self.r_xtend[0] == " ": self.r_xtend = "R" + self.r_xtend[1:]
|
2144
|
-
# ----------------------------------------------------------------- v GREEN CROSS
|
2446
|
+
# ----------------------------------------------------------------- v GREEN CROSS - REMOTE **SEND_COMMAND**
|
2145
2447
|
if (key == Qt.Key.Key_V):
|
2146
2448
|
if ( len(parts_set) == 0):
|
2147
2449
|
self.send_command( data= {"crosson": "CROSSON"} )
|
@@ -2150,7 +2452,7 @@ class StreamWidget(QLabel):
|
|
2150
2452
|
pass
|
2151
2453
|
elif (parts_set == {'Ctrl'}) :
|
2152
2454
|
self.send_command( data= {"crossoff": "CROSSOFF"} )
|
2153
|
-
# ----------------------------------------------------------------- c RED CROSS
|
2455
|
+
# ----------------------------------------------------------------- c RED CROSS - LOCAL ONLY
|
2154
2456
|
if (key == Qt.Key.Key_C):
|
2155
2457
|
if ( len(parts_set) == 0):
|
2156
2458
|
self.flag_redcross = True# not self.flag_redcross
|
@@ -2161,8 +2463,8 @@ class StreamWidget(QLabel):
|
|
2161
2463
|
elif (parts_set == {'Ctrl'}) :
|
2162
2464
|
print( "i... reset position red cross")
|
2163
2465
|
self.redcross = [0, 0]
|
2164
|
-
# ----------------------------------------------------------------- i integrate accumulate
|
2165
|
-
if (key == Qt.Key.Key_I): # i shift-i
|
2466
|
+
# ----------------------------------------------------------------- i integrate accumulate - LOCAL ONLY ! **SEND_COMMAND**
|
2467
|
+
if (key == Qt.Key.Key_I): # i:inc shift-i:dec Ctrl-i:reset Ctrl-Shift-i:watch Alt-i: SUM vs. AVG
|
2166
2468
|
# 4.6GB / 1000 640x480
|
2167
2469
|
if ( len(parts_set) == 0):
|
2168
2470
|
if self.r_integrate < 8:
|
@@ -2190,15 +2492,17 @@ class StreamWidget(QLabel):
|
|
2190
2492
|
elif (parts_set == {'Ctrl'}) :
|
2191
2493
|
self.r_integrate = 1
|
2192
2494
|
self.send_command( data= {"accum": "ACCUM", "accumtxt": 0})
|
2495
|
+
self.l_show_accum = False
|
2193
2496
|
# 0 would be a problem (locally???); but 1 is not sent!!! ; SENDING 0, checking@send_command
|
2194
2497
|
elif (parts_set == {'Ctrl', 'Shift'}) :
|
2498
|
+
# REMOVE SHOW ACCUM .... ok but I remove it also when reseting buffer
|
2195
2499
|
self.l_show_accum = not self.l_show_accum
|
2196
|
-
print(f"i...
|
2500
|
+
print(f"i... BUFFER ACCUMULATED SHOW IS {self.l_show_accum} ; MODE AVG={self.l_show_accum_avg} MODE SUM = {not self.l_show_accum_avg}")
|
2197
2501
|
elif (parts_set == {'Alt'}) :
|
2198
2502
|
self.l_show_accum_avg = not self.l_show_accum_avg
|
2199
|
-
print(f"i... ACCUMULATION AVG
|
2503
|
+
print(f"i... ACCUMULATION DISPLAY MODE SWITCHED: AVG (nonSUM) IS {self.l_show_accum_avg}")
|
2200
2504
|
|
2201
|
-
# ----------------------------------------------------------------- b
|
2505
|
+
# ----------------------------------------------------------------- b BACKGROUND - REMOTE **SEND_COMMAND**
|
2202
2506
|
if (key == Qt.Key.Key_B):
|
2203
2507
|
if ( len(parts_set) == 0):
|
2204
2508
|
self.send_command( data= {"subbg": "SUBBG"})
|
@@ -2206,7 +2510,7 @@ class StreamWidget(QLabel):
|
|
2206
2510
|
self.send_command( data= {"savebg": "SAVEBG"})
|
2207
2511
|
elif (parts_set == {'Ctrl'}) :
|
2208
2512
|
pass
|
2209
|
-
# -----------------------------------------------------------------
|
2513
|
+
# ----------------------------------------------------------------- f FOREGROUND - REMOTE **SEND_COMMAND**
|
2210
2514
|
if (key == Qt.Key.Key_F):
|
2211
2515
|
if ( len(parts_set) == 0):
|
2212
2516
|
self.send_command( data= {"mixfg": "MIXFG"})
|
@@ -2215,7 +2519,7 @@ class StreamWidget(QLabel):
|
|
2215
2519
|
elif (parts_set == {'Ctrl'}) :
|
2216
2520
|
pass
|
2217
2521
|
|
2218
|
-
# ----------------------------------------------------------------- r
|
2522
|
+
# ----------------------------------------------------------------- r ROTATE - LOCAL ONLY !
|
2219
2523
|
if (key == Qt.Key.Key_R):
|
2220
2524
|
if ( len(parts_set) == 0):
|
2221
2525
|
self.l_rotate += 1
|
@@ -2223,7 +2527,7 @@ class StreamWidget(QLabel):
|
|
2223
2527
|
self.l_rotate -= 1
|
2224
2528
|
elif (parts_set == {'Ctrl'}) :
|
2225
2529
|
self.l_rotate = 0
|
2226
|
-
# ----------------------------------------------------------------- 1
|
2530
|
+
# ----------------------------------------------------------------- 1 config
|
2227
2531
|
if (key == Qt.Key.Key_1) or (key == ord("!") ):
|
2228
2532
|
if ( len(parts_set) == 0):
|
2229
2533
|
print("i... config 1 - recall")
|
@@ -2239,7 +2543,7 @@ class StreamWidget(QLabel):
|
|
2239
2543
|
print("D... r_xtend == ", self.r_xtend)
|
2240
2544
|
elif (parts_set == {'Ctrl'}) :
|
2241
2545
|
self.setup("q")
|
2242
|
-
# ----------------------------------------------------------------- 2
|
2546
|
+
# ----------------------------------------------------------------- 2 config
|
2243
2547
|
if (key == Qt.Key.Key_2) or (key == ord("@") ):
|
2244
2548
|
if ( len(parts_set) == 0):
|
2245
2549
|
print("i... config 2 - recall")
|
@@ -2251,7 +2555,7 @@ class StreamWidget(QLabel):
|
|
2251
2555
|
self.setup("w", 2)
|
2252
2556
|
elif (parts_set == {'Ctrl'}) :
|
2253
2557
|
self.setup("q")
|
2254
|
-
# ----------------------------------------------------------------- 3
|
2558
|
+
# ----------------------------------------------------------------- 3 config
|
2255
2559
|
if (key == Qt.Key.Key_3) or (key == ord("#") ):
|
2256
2560
|
if ( len(parts_set) == 0):
|
2257
2561
|
print("i... config 3 - recall")
|
@@ -2263,7 +2567,7 @@ class StreamWidget(QLabel):
|
|
2263
2567
|
self.setup("w", 3)
|
2264
2568
|
elif (parts_set == {'Ctrl'}) :
|
2265
2569
|
self.setup("q")
|
2266
|
-
# ----------------------------------------------------------------- 4
|
2570
|
+
# ----------------------------------------------------------------- 4 config
|
2267
2571
|
if (key == Qt.Key.Key_4) or (key == ord("$") ):
|
2268
2572
|
if ( len(parts_set) == 0):
|
2269
2573
|
print("i... config 4 - recall")
|
@@ -2290,7 +2594,7 @@ class StreamWidget(QLabel):
|
|
2290
2594
|
elif (parts_set == {'Ctrl'}) :
|
2291
2595
|
#self.send_command( data= {"expot": "EXPOT", "expotxt": float(-1.0)})
|
2292
2596
|
pass
|
2293
|
-
# -----------------------------------------------------------------
|
2597
|
+
# ----------------------------------------------------------------- t tests whatever REMOTE ! **SEND_COMMAND**
|
2294
2598
|
if (key == Qt.Key.Key_T):
|
2295
2599
|
if ( len(parts_set) == 0):
|
2296
2600
|
# THIS IS in reallity SKIPPED IN send_command ....
|
@@ -2333,22 +2637,15 @@ class StreamWidget(QLabel):
|
|
2333
2637
|
@click.option('-r', '--resolution', default="640x480", required=False, help='Resolution value')
|
2334
2638
|
@click.option('-f', '--fourcc', default="YUYV", required=False, help='YUYV or MJPG')
|
2335
2639
|
def handle_cli(url, resolution, fourcc):
|
2640
|
+
"""
|
2641
|
+
commandline is solved here; guess url
|
2642
|
+
"""
|
2336
2643
|
#app = QApplication() #
|
2337
2644
|
app = QApplication(sys.argv) # NOT clear why argv here
|
2338
|
-
#url = None
|
2339
|
-
#if len(sys.argv)> 1:
|
2340
|
-
# url = sys.argv[1]
|
2341
|
-
#else:
|
2342
|
-
# url = "http://127.0.0.1:8000/video"
|
2343
2645
|
url = guess_url(url)
|
2344
|
-
#if url is None:
|
2345
|
-
# sys.exit(1)
|
2346
2646
|
widget = None
|
2347
2647
|
|
2348
|
-
#if url is None:
|
2349
2648
|
widget = StreamWidget(url, resolution=resolution, fourcc=fourcc)
|
2350
|
-
#else:
|
2351
|
-
# widget = StreamWidget(url, internet_not_device=True)
|
2352
2649
|
widget.show()
|
2353
2650
|
sys.exit(app.exec())
|
2354
2651
|
|
pogucam/mqimr.py
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
|
3
|
+
print("""
|
4
|
+
RECEIVE IMAGE
|
5
|
+
|
6
|
+
uv run --with paho-mqtt --with=numpy --with=opencv-python --script ./mqimr.py
|
7
|
+
|
8
|
+
show an image received from mqtt
|
9
|
+
""")
|
10
|
+
|
11
|
+
|
12
|
+
import struct
|
13
|
+
import paho.mqtt.client as mqtt
|
14
|
+
import numpy as np
|
15
|
+
import datetime as dt
|
16
|
+
import cv2
|
17
|
+
|
18
|
+
broker = "10.10.104.17"
|
19
|
+
broker = "127.0.0.1"
|
20
|
+
topic = "image/raw8000"
|
21
|
+
|
22
|
+
def decode_payload(data):
|
23
|
+
header_size = struct.calcsize('!HHQddIfff')
|
24
|
+
width, height, framenumber, timestamp_ts, recording_started_ts, _, exposition, gain, gamma = struct.unpack('!HHQddIfff', data[:header_size])
|
25
|
+
image = np.frombuffer(data[header_size:], dtype=np.uint8).reshape((height, width, 3))
|
26
|
+
timestamp = dt.datetime.fromtimestamp(timestamp_ts)
|
27
|
+
recording_started = dt.datetime.fromtimestamp(recording_started_ts)
|
28
|
+
return {
|
29
|
+
'width': width,
|
30
|
+
'height': height,
|
31
|
+
'framenumber': framenumber,
|
32
|
+
'timestamp': timestamp,
|
33
|
+
'recording_started': recording_started,
|
34
|
+
'exposition': exposition,
|
35
|
+
'gain': gain,
|
36
|
+
'gamma': gamma,
|
37
|
+
'image': image
|
38
|
+
}
|
39
|
+
|
40
|
+
|
41
|
+
def on_message(client, userdata, msg):
|
42
|
+
data = msg.payload
|
43
|
+
|
44
|
+
data_block = decode_payload(data)
|
45
|
+
image = data_block['image']
|
46
|
+
#
|
47
|
+
#width, height = struct.unpack('!HH', data[:4])
|
48
|
+
#image = np.frombuffer(data[4:], dtype=np.uint8).reshape((height, width, 3))
|
49
|
+
#####image = np.frombuffer(data, dtype=np.uint8).reshape((480, 640, 3))
|
50
|
+
print("Received image shape:", image.shape, dt.datetime.now() )
|
51
|
+
print( flush=True)
|
52
|
+
|
53
|
+
cv2.imshow("Received Image", image)
|
54
|
+
cv2.waitKey(10) # Needed to refresh window
|
55
|
+
|
56
|
+
client = mqtt.Client()
|
57
|
+
client.on_message = on_message
|
58
|
+
|
59
|
+
client.connect(broker, 1883, 60)
|
60
|
+
client.subscribe(topic)
|
61
|
+
client.loop_forever()
|
pogucam/mqims.py
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
|
3
|
+
print(""" SEND IMAGE via MQTT
|
4
|
+
|
5
|
+
uv run --with paho-mqtt --with=numpy --with=opencv-python --script ./mqims.py
|
6
|
+
|
7
|
+
""")
|
8
|
+
# connect to local MQTT
|
9
|
+
broker = "127.0.0.1"
|
10
|
+
topic = "image/raw8000"
|
11
|
+
|
12
|
+
import struct
|
13
|
+
import paho.mqtt.client as mqtt
|
14
|
+
import numpy as np
|
15
|
+
import datetime as dt
|
16
|
+
import time
|
17
|
+
|
18
|
+
def create_payload(image, framenumber, timestamp, recording_started, exposition, gain, gamma):
|
19
|
+
height, width = image.shape[:2]
|
20
|
+
header = struct.pack(
|
21
|
+
'!HHQddIfff',
|
22
|
+
width,
|
23
|
+
height,
|
24
|
+
int(framenumber),
|
25
|
+
timestamp.timestamp(),
|
26
|
+
recording_started.timestamp(),
|
27
|
+
0, # padding for alignment if needed
|
28
|
+
float(exposition),
|
29
|
+
float(gain),
|
30
|
+
float(gamma)
|
31
|
+
)
|
32
|
+
payload = header + image.tobytes()
|
33
|
+
return payload
|
34
|
+
|
35
|
+
|
36
|
+
|
37
|
+
def provide_image(width, height):
|
38
|
+
# Add random noise element
|
39
|
+
image = np.zeros((480, 640, 3), dtype=np.uint8)
|
40
|
+
#return image # 1ms for just black
|
41
|
+
noise = np.random.randint(0, 50, (height, width, 3), dtype=np.uint8)
|
42
|
+
#image = np.clip(image + noise, 0, 255).astype(np.uint8)
|
43
|
+
#return image # 6.6ms image+noise
|
44
|
+
#---------------------------------------
|
45
|
+
# Create colorful structured image with gradients and sinusoidal patterns
|
46
|
+
x = np.linspace(0, 4 * np.pi, width)
|
47
|
+
y = np.linspace(0, 4 * np.pi, height)
|
48
|
+
X, Y = np.meshgrid(x, y)
|
49
|
+
r = ((np.sin(X) + 1) * 127).astype(np.uint8)
|
50
|
+
g = ((np.cos(Y) + 1) * 127).astype(np.uint8)
|
51
|
+
b = ((np.sin(X + Y) + 1) * 127).astype(np.uint8)
|
52
|
+
|
53
|
+
# Randomize grid frequency and color amplitude
|
54
|
+
freq_x = np.random.uniform(2, 6)
|
55
|
+
freq_y = np.random.uniform(2, 6)
|
56
|
+
amp = np.random.uniform(80, 150)
|
57
|
+
x = np.linspace(0, freq_x * np.pi, width)
|
58
|
+
y = np.linspace(0, freq_y * np.pi, height)
|
59
|
+
X, Y = np.meshgrid(x, y)
|
60
|
+
r = ((np.sin(X) + 1) * amp / 2).clip(0, 255).astype(np.uint8 )
|
61
|
+
g = ((np.cos(Y) + 1) * amp / 2).clip(0, 255).astype(np.uint8)
|
62
|
+
b = ((np.sin(X + Y) + 1) * amp / 2).clip(0, 255).astype(np.uint8)
|
63
|
+
image = np.stack((r, g, b), axis=2)
|
64
|
+
image = np.clip(image + noise, 0, 255).astype(np.uint8)
|
65
|
+
return image # alltogether 35 ms
|
66
|
+
|
67
|
+
|
68
|
+
# *********************************************************************
|
69
|
+
|
70
|
+
client = mqtt.Client()
|
71
|
+
client.connect(broker, 1883, 10)
|
72
|
+
|
73
|
+
recording_started = dt.datetime.now()
|
74
|
+
framenumber = 0
|
75
|
+
for i in range(1000):
|
76
|
+
# Create dummy image
|
77
|
+
#image = np.random.randint(0, 256, (480, 640, 3), dtype=np.uint8)
|
78
|
+
height,width=1080,1920
|
79
|
+
#
|
80
|
+
height,width=480,640
|
81
|
+
#header = struct.pack('!HH', width, height) # Network byte order
|
82
|
+
timestamp = dt.datetime.now()
|
83
|
+
framenumber += 1
|
84
|
+
#recording_started ... also timestamp
|
85
|
+
image=provide_image(width, height) # create image elsewhere
|
86
|
+
exposition, gain, gamma = 0.5, 0.5, 0.5
|
87
|
+
payload = create_payload(image, framenumber, timestamp, recording_started, exposition, gain, gamma)
|
88
|
+
#payload = header + image.tobytes()
|
89
|
+
# Send raw bytes
|
90
|
+
result=client.publish(topic, payload )
|
91
|
+
print(timestamp, end="\r")
|
92
|
+
#result.wait_for_publish() # Ensure message is sent before continuing
|
93
|
+
#print(dt.datetime.now())
|
94
|
+
|
95
|
+
#
|
96
|
+
time.sleep(0.095)
|
97
|
+
|
98
|
+
delta = dt.datetime.now() - recording_started
|
99
|
+
print(f"{delta}, {delta.total_seconds() / 1000} per frame ")
|
100
|
+
client.disconnect()
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: pogucam
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.14
|
4
4
|
Summary: Add your description here
|
5
5
|
Author-email: jaromrax <jaromrax@gmail.com>
|
6
6
|
Requires-Python: >=3.12
|
@@ -9,6 +9,7 @@ Requires-Dist: click>=8.2.1
|
|
9
9
|
Requires-Dist: console>=0.9911
|
10
10
|
Requires-Dist: numpy>=2.3.0
|
11
11
|
Requires-Dist: opencv-python>=4.11.0.86
|
12
|
+
Requires-Dist: paho-mqtt>=2.1.0
|
12
13
|
Requires-Dist: pillow>=11.2.1
|
13
14
|
Requires-Dist: pyqt6>=6.9.1
|
14
15
|
Requires-Dist: requests>=2.32.4
|
@@ -0,0 +1,11 @@
|
|
1
|
+
pogucam/__init__.py,sha256=Iij7VvXCrFPMtTia41mQ7LxFLaulf_fD5cb-AyjpUo0,53
|
2
|
+
pogucam/buffers.py,sha256=1JLkuenkHoA-K-uZAlNV7chHQDZLrspgT5_XOY-E-34,6692
|
3
|
+
pogucam/explore_u24_uni.py,sha256=MtAQ0httaCtSBtYquD1ElXak9k7TC12v-R07kzjQroU,126592
|
4
|
+
pogucam/installation.md,sha256=8qspiLlYjEBx5CedRfBU7Mm0A2pz0lfAnaupZyBm5Eo,128
|
5
|
+
pogucam/mqimr.py,sha256=f48gTXng5vM-1RiNPXSA-IvAc3y6WMStbvfQ8rUV7l0,1727
|
6
|
+
pogucam/mqims.py,sha256=_G8AdfrbTrkIm2MOsq3tFOBYpiD4o58JUIvnZt0Sm7A,3293
|
7
|
+
pogucam/text_write.py,sha256=hyRyA1M5z-pda963T-k0i8fvvAlv1p3YBTZtYNdOeoE,19304
|
8
|
+
pogucam-0.1.14.dist-info/METADATA,sha256=-0fHR7SySxz9vmujJaNMLUUtDxILCPC_6eAoWUYzruQ,499
|
9
|
+
pogucam-0.1.14.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
10
|
+
pogucam-0.1.14.dist-info/entry_points.txt,sha256=-97N0LsXIR8h0rJMzIMuNeNwuY8LvPYPTqnXsuAnVsM,63
|
11
|
+
pogucam-0.1.14.dist-info/RECORD,,
|
pogucam-0.1.12.dist-info/RECORD
DELETED
@@ -1,9 +0,0 @@
|
|
1
|
-
pogucam/__init__.py,sha256=Iij7VvXCrFPMtTia41mQ7LxFLaulf_fD5cb-AyjpUo0,53
|
2
|
-
pogucam/buffers.py,sha256=1JLkuenkHoA-K-uZAlNV7chHQDZLrspgT5_XOY-E-34,6692
|
3
|
-
pogucam/explore_u24_uni.py,sha256=JY_fid_w-Trycs0plLUjv_UNLTjQW66wk4OP-nNiaTs,112075
|
4
|
-
pogucam/installation.md,sha256=8qspiLlYjEBx5CedRfBU7Mm0A2pz0lfAnaupZyBm5Eo,128
|
5
|
-
pogucam/text_write.py,sha256=hyRyA1M5z-pda963T-k0i8fvvAlv1p3YBTZtYNdOeoE,19304
|
6
|
-
pogucam-0.1.12.dist-info/METADATA,sha256=K9zizgKKO_Ur-I4-whqe6rFG8gaBI3xVCQuYYRgl6WA,467
|
7
|
-
pogucam-0.1.12.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
8
|
-
pogucam-0.1.12.dist-info/entry_points.txt,sha256=-97N0LsXIR8h0rJMzIMuNeNwuY8LvPYPTqnXsuAnVsM,63
|
9
|
-
pogucam-0.1.12.dist-info/RECORD,,
|
File without changes
|
File without changes
|