Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

waterfall responsiveness improvements #1079

Merged
merged 5 commits into from
Jan 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 21 additions & 21 deletions auto_label/auto_label.py
Original file line number Diff line number Diff line change
@@ -1,39 +1,38 @@
import os
import os
from argparse import ArgumentParser
import numpy as np
import numpy as np
import cv2 as cv



def label(filename):

img = cv.imread(filename)
imgray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

# opening and closing
# https://docs.opencv.org/3.4/d9/d61/tutorial_py_morphological_ops.html
# https://docs.opencv.org/3.4/d3/dbe/tutorial_opening_closing_hats.html
kernel = np.ones((5,5),np.uint8)
kernel = np.ones((5, 5), np.uint8)
imgray = cv.morphologyEx(imgray, cv.MORPH_OPEN, kernel)
imgray = cv.morphologyEx(imgray, cv.MORPH_CLOSE, kernel)


# bilateral smoothing
# https://docs.opencv.org/3.4/dc/dd3/tutorial_gausian_median_blur_bilateral_filter.html
bilateral_kernel = 8
imgray = cv.bilateralFilter(imgray, bilateral_kernel, bilateral_kernel * 2, bilateral_kernel / 2)
imgray = cv.bilateralFilter(
imgray, bilateral_kernel, bilateral_kernel * 2, bilateral_kernel / 2
)
ret, thresh = cv.threshold(imgray, 140, 255, 0)
contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
# remove internal contours

# remove internal contours
# https://docs.opencv.org/4.x/d9/d8b/tutorial_py_contours_hierarchy.html
good_contours = []
for i in range(len(contours)):
if hierarchy[0,i,3] == -1:
if hierarchy[0, i, 3] == -1:
good_contours.append(contours[i])
contours = good_contours

# draw rectangels over all contours
# draw rectangels over all contours
for cnt in contours:
# Contour approximation https://docs.opencv.org/4.x/dd/d49/tutorial_py_contour_features.html
# epsilon = 0.01*cv.arcLength(cnt,True)
Expand All @@ -42,14 +41,14 @@ def label(filename):
# Convex hull
# cnt = cv.convexHull(cnt)

x,y,w,h = cv.boundingRect(cnt)
cv.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)

x, y, w, h = cv.boundingRect(cnt)
cv.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)

cv.imshow('Image',img)
cv.imshow("Image", img)
cv.waitKey(0)
cv.destroyAllWindows()


def main():
parser = ArgumentParser()
parser.add_argument(
Expand All @@ -62,20 +61,21 @@ def main():

filepath = args.filepath

# get files
# get files
files = []
if os.path.isfile(filepath):
files.append(filepath)
elif os.path.isdir(filepath):
files.extend([os.path.join(filepath, filename) for filename in os.listdir(filepath)])
files.extend(
[os.path.join(filepath, filename) for filename in os.listdir(filepath)]
)
else:
raise ValueError('filepath must be existing directory or filename')
raise ValueError("filepath must be existing directory or filename")

# loop through files
for img_filename in files:
label(img_filename)



if __name__ == "__main__":
main()
main()
33 changes: 21 additions & 12 deletions gamutrflib/gamutrflib/zmqbucket.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,14 +177,15 @@
self.fftbuffer = pd.concat([self.fftbuffer, df])
if self.fftbuffer["sweep_start"].nunique() > 1:
min_sweep_start = self.fftbuffer["sweep_start"].min()
max_sweep_start = self.fftbuffer["sweep_start"].max()
frame_df = self.fftbuffer[
self.fftbuffer["sweep_start"] == min_sweep_start
self.fftbuffer["sweep_start"] != max_sweep_start
].copy()
frame_df["tune_count"] = (
frame_df["tune_count"].max() - frame_df["tune_count"].min()
)
self.fftbuffer = self.fftbuffer[
self.fftbuffer["sweep_start"] != min_sweep_start
self.fftbuffer["sweep_start"] == max_sweep_start
]
scan_config = self.scan_configs[min_sweep_start]
del self.scan_configs[min_sweep_start]
Expand Down Expand Up @@ -226,7 +227,8 @@
lines = self.txtbuf_to_lines(log)
if lines:
df = self.lines_to_df(lines)
scan_config, frame_df = self.read_new_frame_df(df, discard_time)
if df is not None:
scan_config, frame_df = self.read_new_frame_df(df, discard_time)
return scan_config, frame_df


Expand Down Expand Up @@ -264,15 +266,22 @@
return False

def read_buff(self, log=None, discard_time=0, scan_fres=0):
results = [scanner.read_buff(log, discard_time) for scanner in self.scanners]
if self.last_results:
for i, result in enumerate(results):
_scan_config, df = result
if df is not None:
self.last_results[i] = result
logging.info("%s got scan result", self.scanners[i])
else:
self.last_results = results
while True:
results = [
scanner.read_buff(log, discard_time) for scanner in self.scanners
]
new_results = 0
if self.last_results:
for i, result in enumerate(results):
_scan_config, df = result
if df is not None:
self.last_results[i] = result
new_results += 1
logging.info("%s got scan result", self.scanners[i])

Check warning on line 280 in gamutrflib/gamutrflib/zmqbucket.py

View check run for this annotation

Codecov / codecov/patch

gamutrflib/gamutrflib/zmqbucket.py#L275-L280

Added lines #L275 - L280 were not covered by tests
else:
self.last_results = results
if new_results == 0:
break

scan_configs = []
dfs = []
Expand Down
18 changes: 16 additions & 2 deletions gamutrfwaterfall/gamutrfwaterfall/waterfall.py
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,12 @@
type=int,
help="Waterfall width (maximum)",
)

parser.add_argument(
"--refresh",
default=5,
type=int,
help="Waterfall refresh time",
)
return parser


Expand Down Expand Up @@ -899,6 +904,7 @@
waterfall_height,
waterfall_width,
batch,
refresh,
zmqr,
):
style.use("fast")
Expand Down Expand Up @@ -980,11 +986,18 @@
if need_reset_fig:
reset_fig(config, state)
need_reset_fig = False
last_gap = time.time()
while True:
gap_time = time.time() - last_gap
if results and gap_time > refresh / 2:
break
scan_configs, scan_df = zmqr.read_buff(
scan_fres=config.freq_resolution * 1e6
)
if scan_df is None:
if batch and gap_time < refresh / 2:
time.sleep(0.1)
continue
break
last_config = make_config(
scan_configs,
Expand Down Expand Up @@ -1085,7 +1098,7 @@
engine = "agg"
batch = True
savefig_path = os.path.join(tempdir, "waterfall.png")
flask = FlaskHandler(savefig_path, args.port)
flask = FlaskHandler(savefig_path, args.port, refresh=args.refresh)

Check warning on line 1101 in gamutrfwaterfall/gamutrfwaterfall/waterfall.py

View check run for this annotation

Codecov / codecov/patch

gamutrfwaterfall/gamutrfwaterfall/waterfall.py#L1101

Added line #L1101 was not covered by tests
flask.start()

zmqr = ZmqReceiver(
Expand All @@ -1108,6 +1121,7 @@
args.waterfall_height,
args.waterfall_width,
batch,
args.refresh,
zmqr,
)

Expand Down
1 change: 1 addition & 0 deletions gamutrfwaterfall/tests/test_waterfall.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ def test_run_waterfall(self):
5, # args.height,
10, # args.waterfall_height,
100, # args.waterfall_width,
5, # args.refresh,
True, # args.batch
zmqr,
)
Expand Down
3 changes: 2 additions & 1 deletion orchestrator.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ services:
- --tune-dwell-ms=0
- --tune-step-fft=512
- --db_clamp_floor=-150
- --fft_batch_size=256
- --fft_batch_size=16
- --mqtt_server=mqtt
- --no-compass
- --use_external_gps
Expand All @@ -78,6 +78,7 @@ services:
- --inference_model_name=mini2_snr
- --n_inference=10
- --n_image=10
- --vkfft
# - --external_gps_server=1.2.3.4
# - --external_gps_server_port=8888
# - --inference_output_dir=/logs/inference
Expand Down
4 changes: 3 additions & 1 deletion tests/test_grscan.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,9 @@ def test_fake_uhd(self):
get_source("ettus", 1e3, 10, 1024, 1024, uhd_lib=FakeUHD())

def test_fake_soapy(self):
sources, _, workaround = get_source("SoapyAIRT", 1e3, 10, 1024, 1024, soapy_lib=FakeSoapy())
sources, _, workaround = get_source(
"SoapyAIRT", 1e3, 10, 1024, 1024, soapy_lib=FakeSoapy()
)
tb = FakeTb(sources, workaround, 100e6)
tb.start()

Expand Down
Loading