add us process and web

This commit is contained in:
flandre 2025-05-08 00:25:52 +08:00
parent 35472c5112
commit ec93302ea9
11 changed files with 272 additions and 24 deletions

View File

@ -1 +1,18 @@
{"t_end": 2026, "t_start": 1714, "v2": 1524, "dct_center": 1086, "dct_bandwidth": 915, "f_rows": 6002, "beta": 40, "tgc": 0, "g1": 23, "g2": 27, "g3": 34, "g4": 24, "g5": 23, "g6": 30, "g7": 27, "g8": 51} {
"t_end": 2026,
"t_start": 1714,
"v2": 1524,
"dct_center": 1086,
"dct_bandwidth": 915,
"f_rows": 6002,
"beta": 40,
"tgc": 0,
"g1": 23,
"g2": 27,
"g3": 34,
"g4": 24,
"g5": 23,
"g6": 30,
"g7": 27,
"g8": 51
}

View File

@ -2,6 +2,8 @@ import cupy as cp
from flandre.beamformer.das import TFM from flandre.beamformer.das import TFM
from flandre.utils.Config import ImagingConfig from flandre.utils.Config import ImagingConfig
from flandre.utils.Msg import ImageArgMsg
from flandre.utils.RfMat import RfMat
from flandre.utils.ScanData import ScanData from flandre.utils.ScanData import ScanData
tfm_cache = [None] tfm_cache = [None]
@ -42,3 +44,16 @@ def tfm_process(s: ScanData, icfg: ImagingConfig, disable_cache: bool, tfm: TFM)
.cpu() .cpu()
.get() .get()
) )
def process_pwi_v2(data: RfMat, arg: ImageArgMsg, pwi):
return (data
.dct_center(arg.dct_center, arg.dct_bandwidth)
.call(lambda m: m.astype(cp.int16))
.call(pwi)
.call(cp.asarray, order='C')
.argrelextrema()
.conv_guass(b=arg.beta * 0.01)
.crop_center(arg.t_start, arg.t_end)
.time_gain_compensation_global((1 - arg.g8 * (1.0 / 128)) ** 2)
)

View File

@ -12,6 +12,7 @@ from flandre.config import C
from flandre.nodes.Node import Node from flandre.nodes.Node import Node
from flandre.utils.Config import DeviceConfig from flandre.utils.Config import DeviceConfig
from flandre.utils.Msg import ImageArgMsg, Msg, BeamformerMsg, RfMatMsg, RfFrameMsg, MaxMsg from flandre.utils.Msg import ImageArgMsg, Msg, BeamformerMsg, RfMatMsg, RfFrameMsg, MaxMsg
from flandre.utils.RfFrame import RfFrameFile
from flandre.utils.RfMat import RfMat from flandre.utils.RfMat import RfMat
from flandre.utils.RfMeta import RfSequenceMeta from flandre.utils.RfMeta import RfSequenceMeta
@ -87,6 +88,7 @@ class Beamformer(Node):
self.send(MaxMsg(mm.item())) self.send(MaxMsg(mm.item()))
last_v2 = 5900 last_v2 = 5900
last_f_rows = 0 last_f_rows = 0
last_blake2b = None
while True: while True:
self.muxer_req_socket.send(b'') self.muxer_req_socket.send(b'')
r = dict(self.c.poller.poll()) r = dict(self.c.poller.poll())
@ -103,8 +105,16 @@ class Beamformer(Node):
id2 = r.index(Msg.magic(), 1) id2 = r.index(Msg.magic(), 1)
arg_msg: ImageArgMsg = Msg.decode_msg(r[:id2]) arg_msg: ImageArgMsg = Msg.decode_msg(r[:id2])
rf_frame_msg: RfFrameMsg = Msg.decode_msg(r[id2:]) rf_frame_msg: RfFrameMsg = Msg.decode_msg(r[id2:])
current_frame = rf_frame_msg.rf_frame
if isinstance(current_frame, RfFrameFile):
if current_frame.meta.blake2b is not None and current_frame.meta.blake2b == last_blake2b:
continue
mat = RfMat.from_rf_frame(rf_frame_msg.rf_frame, 'gpu') mat = RfMat.from_rf_frame(rf_frame_msg.rf_frame, 'gpu')
# logger.info(mat.frame_meta.blake2b) # logger.info(mat.frame_meta.blake2b)
last_blake2b = mat.frame_meta.blake2b
if mat is None: if mat is None:
continue continue
if arg_msg.v2 != last_v2 or arg_msg.f_rows != last_f_rows: if arg_msg.v2 != last_v2 or arg_msg.f_rows != last_f_rows:

View File

@ -6,7 +6,7 @@ import zmq
from flandre.config import C, ISDEV from flandre.config import C, ISDEV
from flandre.nodes.Node import Node from flandre.nodes.Node import Node
from flandre.utils.Msg import MoveAxisMsg, KillMsg, SetSeqMetaMsg, SeqIdMinMax, SetBaseMsg, PlaybackSeqListMsg, \ from flandre.utils.Msg import MoveAxisMsg, KillMsg, SetSeqMetaMsg, SeqIdMinMax, SetBaseMsg, PlaybackSeqListMsg, \
SeqIdList, SetSidMsg, RfFrameMsg SeqIdList, SetSidMsg, RfFrameMsg, RobotRtsiMsg
from flandre.utils.RfSequence import RfSequence from flandre.utils.RfSequence import RfSequence
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -29,7 +29,9 @@ class Loader(Node):
if msg.axis == 'S': if msg.axis == 'S':
pass pass
elif isinstance(msg, SetSidMsg): elif isinstance(msg, SetSidMsg):
self.send(RfFrameMsg(1, rff.frames[msg.value])) selected_frame = rff.frames[msg.value]
self.send(RfFrameMsg(1, selected_frame))
self.send(RobotRtsiMsg.from_meta(selected_frame.meta))
elif isinstance(msg, SetSeqMetaMsg): elif isinstance(msg, SetSeqMetaMsg):
if base is None: if base is None:

View File

@ -1,10 +1,13 @@
import asyncio import asyncio
import dataclasses import dataclasses
import logging import logging
from pathlib import Path
from threading import Thread from threading import Thread
from fastapi import FastAPI, Response
from flandre.nodes.Node import Node from flandre.nodes.Node import Node
from flandre.utils.Msg import ImageArgMsg, RobotRtsiMsg from flandre.utils.Msg import ImageArgMsg, RobotRtsiMsg, SetSidMsg
from flandre.utils.RfSequence import RfSequence
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -70,7 +73,7 @@ app = FastAPI()
class Web(Node): class Web(Node):
topics = [ImageArgMsg, RobotRtsiMsg] topics = [ImageArgMsg, RobotRtsiMsg, SetSidMsg]
def __init__(self, level=logging.INFO): def __init__(self, level=logging.INFO):
super(Web, self).__init__(level=level) super(Web, self).__init__(level=level)
@ -81,10 +84,22 @@ class Web(Node):
self.router = APIRouter() self.router = APIRouter()
self.router.add_api_route("/hello", self.hello, methods=["GET"]) self.router.add_api_route("/hello", self.hello, methods=["GET"])
self.router.add_websocket_route("/ws", self.websocket_endpoint) self.router.add_websocket_route("/ws", self.websocket_endpoint)
self.router.add_api_route("/p", self.get_image, response_class=Response, responses={
200: {
"content": {"image/png": {}}
}
})
def hello(self): def hello(self):
return {"Hello": 'asd'} return {"Hello": 'asd'}
def get_image(self, i: int):
rfs = RfSequence()
f = rfs.frames[i]
image_bytes: bytes = b''
return Response(content=image_bytes, media_type="image/png")
async def websocket_endpoint(self, websocket: WebSocket): async def websocket_endpoint(self, websocket: WebSocket):
await websocket.accept() await websocket.accept()
self.wss.append(websocket) self.wss.append(websocket)
@ -101,8 +116,11 @@ class Web(Node):
self.wss.remove(websocket) self.wss.remove(websocket)
def boardcast(self, data: dict): def boardcast(self, data: dict):
for ws in self.wss: try:
asyncio.run(ws.send_json(data)) for ws in self.wss:
asyncio.run(ws.send_json(data))
except Exception as e:
logger.warning(e)
def wst(self): def wst(self):
app = FastAPI() app = FastAPI()
@ -118,10 +136,9 @@ class Web(Node):
self.arg = msg self.arg = msg
self.boardcast(msg.dict) self.boardcast(msg.dict)
elif isinstance(msg, RobotRtsiMsg): elif isinstance(msg, RobotRtsiMsg):
try: self.boardcast(msg.dict)
self.boardcast(msg.dict) elif isinstance(msg, SetSidMsg):
except Exception as e: self.boardcast(msg.dict)
logger.warning(e)
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -378,6 +378,7 @@ class RfFrameMsg(HeaderByteMsg):
@classmethod @classmethod
def decode(cls, data: bytes) -> 'RfFrameMsg': def decode(cls, data: bytes) -> 'RfFrameMsg':
# return RfFrameMemory(RfFrameMeta(),RfSequenceMeta(),b'')
msg = super(RfFrameMsg, cls).decode(data) msg = super(RfFrameMsg, cls).decode(data)
if msg.header['type'] == 'RfFrameFile': if msg.header['type'] == 'RfFrameFile':
return RfFrameMsg( return RfFrameMsg(
@ -523,6 +524,19 @@ class RobotRtsiMsg(Msg):
pos: tuple[int, int, int, int, int, int] pos: tuple[int, int, int, int, int, int]
force: tuple[int, int, int, int, int, int] force: tuple[int, int, int, int, int, int]
@staticmethod
def from_meta(meta: RfFrameMeta):
return RobotRtsiMsg(
pos=(
meta.robot_x, meta.robot_y, meta.robot_z,
meta.robot_roll, meta.robot_pitch, meta.robot_yal,
),
force=(
meta.robot_force_x, meta.robot_force_y, meta.robot_force_z,
meta.robot_force_roll, meta.robot_force_pitch, meta.robot_force_yal
)
)
class RequestRfFrameMsg(Msg): class RequestRfFrameMsg(Msg):
pass pass

View File

@ -1,4 +1,5 @@
import inspect import inspect
from pathlib import Path
import cupyx import cupyx
import cv2 import cv2
@ -415,10 +416,17 @@ class RfMat:
self.m = self.m.astype(np.int64) self.m = self.m.astype(np.int64)
return self return self
def jupyter(self): def jupyter(self, figsize=(40, 20), aspect=None):
from matplotlib import pyplot as plt from matplotlib import pyplot as plt
plt.figure(figsize=(40, 20)) plt.figure(figsize=figsize)
plt.imshow(self.m, cmap='grey') plt.imshow(self.m, cmap='grey', aspect=aspect)
def png(self, path: Path, color=(255, 0, 0), pre=0):
canvas = np.zeros((self.h, self.w, 4), dtype=np.uint8)
canvas[:, :, 0:3] = color
canvas[:, :, 3] = self.grey().cpu().m[:, :]
canvas[:pre, :, 3] = 0
cv2.imwrite(str(path), canvas)
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -1,12 +1,8 @@
import dataclasses
import json
from dataclasses import dataclass from dataclasses import dataclass
from enum import Enum, auto from enum import Enum, auto
from pathlib import Path from pathlib import Path
from typing import Annotated, get_type_hints from typing import Annotated, get_type_hints
# from attr import dataclass
COMMIT_KEY = 'COMMIT' COMMIT_KEY = 'COMMIT'

108
imaging_example.ipynb Normal file

File diff suppressed because one or more lines are too long

38
test/process_b.py Normal file
View File

@ -0,0 +1,38 @@
import cupy as cp
from flandre.beamformer.das import gen_pwi
from flandre.beamformer.dist import direct_dist
from flandre.utils.Config import DeviceConfig
from flandre.utils.Msg import ImageArgMsg
from flandre.utils.RfMat import RfMat
from flandre.utils.RfSequence import RfSequence
if __name__ == '__main__':
arg = ImageArgMsg(
sender='',
t_end=2900,
t_start=0,
v2=1524,
dct_center=1086,
dct_bandwidth=915,
f_rows=6002,
beta=40,
tgc=0,
g8=80
)
dc = DeviceConfig(v2=1540, rows=5999)
pwi, _, la = gen_pwi(direct_dist(dc, p=cp), dc)
seq = RfSequence('/run/media/lambda/b86dccdc-f134-464b-a310-6575ee9ae85c/us/baby789,S=(256 6002),M=PWI,U=120/')
for i, frame in enumerate(seq.frames):
data = RfMat.from_rf_frame(frame, device='gpu')
data = data.dct_center(arg.dct_center, arg.dct_bandwidth)
data = data.call(lambda m: m.astype(cp.int16))
data = data.call(pwi)
data = data.call(cp.asarray, order='C')
data = data.argrelextrema()
data = data.conv_guass(b=arg.beta * 0.01)
data = data.crop(arg.t_start, arg.t_end)
data = data.time_gain_compensation_global((1 - arg.g8 * (1.0 / 128)) ** 2)
data = data.rotate90()
data.png(f'/home/lambda/source/scarlet/flandre/@DS/test/{i}.png', pre=300)

View File

@ -173,23 +173,46 @@
{ {
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2025-04-16T10:03:23.103198Z", "end_time": "2025-05-07T13:04:34.708223Z",
"start_time": "2025-04-16T10:03:23.018519Z" "start_time": "2025-05-07T13:04:34.699244Z"
} }
}, },
"cell_type": "code", "cell_type": "code",
"source": "", "source": [
"from flandre.utils.Msg import ImageArgMsg\n",
"\n",
"arg = ImageArgMsg(\n",
" sender='',\n",
" t_start=0,\n",
" t_end=1,\n",
")\n",
"rff = RfSequence('/run/media/lambda/b86dccdc-f134-464b-a310-6575ee9ae85c/us/baby789,S=(256 6002),M=PWI,U=120')\n",
"\n",
"dc = DeviceConfig(v2=1540, rows=1490)\n",
"pwi, _ = gen_pwi(direct_dist(dc, p=cp), dc)\n",
"\n",
"data = RfMat.from_rf_frame(rff.frames[0])\n",
"data = data.dct_center(arg.dct_center, arg.dct_bandwidth)\n",
"data = data.call(lambda m: m.astype(cp.int16))\n",
"data = data.call(pwi)\n",
"data = data.call(cp.asarray, order='C')\n",
"data = data.argrelextrema()\n",
"data = data.conv_guass(b=arg.beta * 0.01)\n",
"data = data.crop_center(arg.t_start, arg.t_end)\n",
"data = data.time_gain_compensation_global((1 - arg.g8 * (1.0 / 128)) ** 2)\n",
"data.jupyter()\n"
],
"id": "75e9c5f82736241", "id": "75e9c5f82736241",
"outputs": [ "outputs": [
{ {
"ename": "NameError", "ename": "NameError",
"evalue": "name 'rff' is not defined", "evalue": "name 'RfSequence' is not defined",
"output_type": "error", "output_type": "error",
"traceback": [ "traceback": [
"\u001B[0;31m---------------------------------------------------------------------------\u001B[0m", "\u001B[0;31m---------------------------------------------------------------------------\u001B[0m",
"\u001B[0;31mNameError\u001B[0m Traceback (most recent call last)", "\u001B[0;31mNameError\u001B[0m Traceback (most recent call last)",
"Cell \u001B[0;32mIn[2], line 1\u001B[0m\n\u001B[0;32m----> 1\u001B[0m RfMat\u001B[38;5;241m.\u001B[39mfrom_rf_frame(\u001B[43mrff\u001B[49m\u001B[38;5;241m.\u001B[39mframes[\u001B[38;5;241m0\u001B[39m])\u001B[38;5;241m.\u001B[39mjupyter()\n", "Cell \u001B[0;32mIn[2], line 8\u001B[0m\n\u001B[1;32m 1\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m\u001B[38;5;250m \u001B[39m\u001B[38;5;21;01mflandre\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mutils\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mMsg\u001B[39;00m\u001B[38;5;250m \u001B[39m\u001B[38;5;28;01mimport\u001B[39;00m ImageArgMsg\n\u001B[1;32m 3\u001B[0m arg \u001B[38;5;241m=\u001B[39m ImageArgMsg(\n\u001B[1;32m 4\u001B[0m sender\u001B[38;5;241m=\u001B[39m\u001B[38;5;124m'\u001B[39m\u001B[38;5;124m'\u001B[39m,\n\u001B[1;32m 5\u001B[0m t_start\u001B[38;5;241m=\u001B[39m\u001B[38;5;241m0\u001B[39m,\n\u001B[1;32m 6\u001B[0m t_end\u001B[38;5;241m=\u001B[39m\u001B[38;5;241m1\u001B[39m,\n\u001B[1;32m 7\u001B[0m )\n\u001B[0;32m----> 8\u001B[0m rff \u001B[38;5;241m=\u001B[39m \u001B[43mRfSequence\u001B[49m(\u001B[38;5;124m'\u001B[39m\u001B[38;5;124m/run/media/lambda/b86dccdc-f134-464b-a310-6575ee9ae85c/us/baby789,S=(256 6002),M=PWI,U=120\u001B[39m\u001B[38;5;124m'\u001B[39m)\n\u001B[1;32m 10\u001B[0m dc \u001B[38;5;241m=\u001B[39m DeviceConfig(v2\u001B[38;5;241m=\u001B[39m\u001B[38;5;241m1540\u001B[39m, rows\u001B[38;5;241m=\u001B[39m\u001B[38;5;241m1490\u001B[39m)\n\u001B[1;32m 11\u001B[0m pwi, _ \u001B[38;5;241m=\u001B[39m gen_pwi(direct_dist(dc, p\u001B[38;5;241m=\u001B[39mcp), dc)\n",
"\u001B[0;31mNameError\u001B[0m: name 'rff' is not defined" "\u001B[0;31mNameError\u001B[0m: name 'RfSequence' is not defined"
] ]
} }
], ],