update after ojzm
This commit is contained in:
@@ -0,0 +1,192 @@
|
|||||||
|
import os
|
||||||
|
os.environ["OPENCV_VIDEOIO_MSMF_ENABLE_HW_TRANSFORMS"] = "0"
|
||||||
|
import cv2
|
||||||
|
import orisys
|
||||||
|
import numpy as np
|
||||||
|
import time
|
||||||
|
|
||||||
|
import pyqtgraph as pg
|
||||||
|
|
||||||
|
def create_plot():
|
||||||
|
p1 = win.addPlot(title="法相力")
|
||||||
|
p1.setLabel('bottom', '时间', units='s')
|
||||||
|
win.nextRow()
|
||||||
|
p2 = win.addPlot(title="切向力 X")
|
||||||
|
p2.setLabel('bottom', '时间', units='s')
|
||||||
|
win.nextRow()
|
||||||
|
p3 = win.addPlot(title="切向力 Y")
|
||||||
|
p3.setLabel('bottom', '时间', units='s')
|
||||||
|
plot_af = p1.plot(pen='k')
|
||||||
|
plot_tfx = p2.plot(pen='k')
|
||||||
|
plot_tfy = p3.plot(pen='k')
|
||||||
|
return p1, p2, p3, plot_af, plot_tfx, plot_tfy
|
||||||
|
|
||||||
|
def update(plot_af, plot_tfx, plot_tfy, data, p1, p2, p3):
|
||||||
|
# global plot_af, plot_tfx, plot_tfy, data, p1, p2, p3
|
||||||
|
plot_af.setData(data[:,:,0])
|
||||||
|
p1.setYRange(min(data[:,1,0]),max(data[:,1,0]))
|
||||||
|
plot_tfx.setData(data[:,:,1])
|
||||||
|
p2.setYRange(min(data[:,1,1]),max(data[:,1,1]))
|
||||||
|
plot_tfy.setData(data[:,:,2])
|
||||||
|
p3.setYRange(min(data[:,1,2]),max(data[:,1,2]))
|
||||||
|
|
||||||
|
# 深度图
|
||||||
|
def draw_magnitude_map(vfield, threshold=3.0, colormap=cv2.COLORMAP_JET) -> np.ndarray:
|
||||||
|
"""
|
||||||
|
Draw color map of pointwise magnitude of velocity field.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
vfield: Velocity field to visualize (2D vector field)
|
||||||
|
threshold: Minimum magnitude to display (below threshold shows as zero/blue)
|
||||||
|
colormap: OpenCV colormap to use (default: COLORMAP_JET)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
np.ndarray: 400x400 BGR image with colored magnitude map
|
||||||
|
"""
|
||||||
|
flow_field = vfield
|
||||||
|
|
||||||
|
# Compute magnitude at each point
|
||||||
|
magnitude = np.sqrt(flow_field[:, :, 0]**2 + flow_field[:, :, 1]**2)
|
||||||
|
|
||||||
|
# Smooth by downsampling and interpolating back
|
||||||
|
downsample_factor = 10
|
||||||
|
h, w = magnitude.shape
|
||||||
|
magnitude_downsampled = magnitude[::downsample_factor, ::downsample_factor]
|
||||||
|
magnitude_smoothed = cv2.resize(magnitude_downsampled, (w, h), interpolation=cv2.INTER_CUBIC)
|
||||||
|
|
||||||
|
# Apply threshold - set below-threshold values to zero
|
||||||
|
magnitude_thresholded = magnitude_smoothed.copy()
|
||||||
|
magnitude_thresholded[magnitude_smoothed < threshold] = 0
|
||||||
|
|
||||||
|
# Normalize to 0-255 range
|
||||||
|
mag_min, mag_max = magnitude_thresholded.min(), magnitude_thresholded.max()
|
||||||
|
if mag_max > mag_min:
|
||||||
|
magnitude_norm = ((magnitude_thresholded - mag_min) / (mag_max - mag_min) * 255).astype(np.uint8)
|
||||||
|
else:
|
||||||
|
magnitude_norm = np.zeros_like(magnitude_thresholded, dtype=np.uint8)
|
||||||
|
|
||||||
|
# Apply colormap
|
||||||
|
magnitude_colored = cv2.applyColorMap(magnitude_norm, colormap)
|
||||||
|
|
||||||
|
# Resize to output size
|
||||||
|
out_img = cv2.resize(magnitude_colored, (400, 400), interpolation=cv2.INTER_CUBIC)
|
||||||
|
|
||||||
|
return out_img
|
||||||
|
|
||||||
|
# 实时图表
|
||||||
|
npoints = 100 # 图表数据长度
|
||||||
|
pg.setConfigOption('background', 'w')
|
||||||
|
pg.setConfigOption('foreground', 'k')
|
||||||
|
app = pg.mkQApp("Plotting Example")
|
||||||
|
win = pg.GraphicsLayoutWidget(show=True, title="Basic plotting examples")
|
||||||
|
win.setWindowTitle('pyqtgraph example: Plotting')
|
||||||
|
p1, p2, p3, plot_af, plot_tfx, plot_tfy = create_plot()
|
||||||
|
data = np.zeros([npoints,2,3])
|
||||||
|
start_time = None # Will be set when sensor starts
|
||||||
|
for i in range(3):
|
||||||
|
data[:,0,i] = np.linspace(-npoints,0,npoints)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
global start_time
|
||||||
|
|
||||||
|
# 打开视频
|
||||||
|
# sensor1 = Sensor("./s1.mp4",isstitch=True,cuda = True,verbose = True)
|
||||||
|
# 方式1: 从视频文件读取
|
||||||
|
sensor1 = orisys.Sensor(8, config_name="./config/ddjx01.json", cal_path= "./config/ddjx01.npy", cuda=False, verbose=True)
|
||||||
|
|
||||||
|
start_time = time.time()
|
||||||
|
is_save = False
|
||||||
|
frame_count = 0
|
||||||
|
writer = None
|
||||||
|
while True:
|
||||||
|
sensor1.get_img() # 提取并拼接复眼图像
|
||||||
|
|
||||||
|
if is_save and writer is not None and sensor1.frame is not None:
|
||||||
|
frame_count += 1
|
||||||
|
save_img = sensor1.frame
|
||||||
|
|
||||||
|
# Convert grayscale (1 channel) to BGR (3 channels) if needed
|
||||||
|
if len(save_img.shape) == 2 or (len(save_img.shape) == 3 and save_img.shape[2] == 1):
|
||||||
|
if len(save_img.shape) == 3:
|
||||||
|
save_img = save_img.squeeze(2)
|
||||||
|
save_img = cv2.cvtColor(save_img, cv2.COLOR_GRAY2BGR)
|
||||||
|
|
||||||
|
writer.write(save_img)
|
||||||
|
|
||||||
|
sensor1.compute_deformation(check_motion=False) # 计算形变和分解
|
||||||
|
# 提取信息:
|
||||||
|
# 向量场: VRAW, VNORMAL, VSHEAR: 原始,法向,切向
|
||||||
|
# 帧率,时间戳: FPS, TIMESTAMP
|
||||||
|
# 变形量总和: FNORMAL , FSHEARX, FSHEARY : 法向,切向(X),切向(Y)
|
||||||
|
fps, fn, fx, fy, flow = sensor1.read_info(sensor1.info.FPS, sensor1.info.FNORMAL, sensor1.info.FSHEARX, sensor1.info.FSHEARY, sensor1.info.VRAW)
|
||||||
|
# print(fps,fn,fx,fy)
|
||||||
|
# 显示向量场
|
||||||
|
arrows = orisys.util.draw_arrows(sensor1.img, flow, threshold=5, grid_spacing=10, arrow_scale=1.0)
|
||||||
|
cv2.imshow("Deformation", arrows)
|
||||||
|
# 显示深度图
|
||||||
|
mag = draw_magnitude_map(flow)
|
||||||
|
cv2.imshow("Magnitude", mag)
|
||||||
|
|
||||||
|
# 显示图表 - 更新时间轴
|
||||||
|
current_time = time.time() - start_time
|
||||||
|
for i in range(3):
|
||||||
|
data[:-1, 0, i] = data[1:, 0, i] # shift time data left
|
||||||
|
data[:-1, 1, i] = data[1:, 1, i] # shift force data left
|
||||||
|
data[-1, 0, :] = current_time # set current time for all plots
|
||||||
|
data[-1, 1, 0] = fn
|
||||||
|
data[-1, 1, 1] = fx
|
||||||
|
data[-1, 1, 2] = fy
|
||||||
|
fn_mean = np.mean(data[:,1,0])
|
||||||
|
fx_mean = np.mean(data[:,1,1])
|
||||||
|
fy_mean = np.mean(data[:,1,2])
|
||||||
|
print(f"fps: {fps}, fn_mean: {fn_mean:.2f}, fx_mean: {fx_mean:.2f}, fy_mean: {fy_mean:.2f}")
|
||||||
|
update(plot_af, plot_tfx, plot_tfy, data, p1, p2, p3) # Update plot
|
||||||
|
|
||||||
|
key = cv2.waitKey(1)
|
||||||
|
if key & 0xFF == ord("q"):
|
||||||
|
print("\n 停止程序")
|
||||||
|
break
|
||||||
|
if key == ord("s"):
|
||||||
|
save_path = f"./data/pulse_test.mp4"
|
||||||
|
# Ensure directory exists
|
||||||
|
os.makedirs(os.path.dirname(save_path), exist_ok=True)
|
||||||
|
# Get frame dimensions from the actual frame
|
||||||
|
save_img = sensor1.frame
|
||||||
|
|
||||||
|
if save_img is not None:
|
||||||
|
# Convert grayscale (1 channel) to BGR (3 channels) if needed for dimension check
|
||||||
|
temp_img = save_img.copy()
|
||||||
|
if len(temp_img.shape) == 2 or (len(temp_img.shape) == 3 and temp_img.shape[2] == 1):
|
||||||
|
if len(temp_img.shape) == 3:
|
||||||
|
temp_img = temp_img.squeeze(2)
|
||||||
|
temp_img = cv2.cvtColor(temp_img, cv2.COLOR_GRAY2BGR)
|
||||||
|
|
||||||
|
frame_height, frame_width = temp_img.shape[:2]
|
||||||
|
writer = cv2.VideoWriter(save_path, cv2.VideoWriter_fourcc(*'mp4v'), 30, (frame_width, frame_height))
|
||||||
|
if writer.isOpened():
|
||||||
|
is_save = True
|
||||||
|
print(f"Start writing to {save_path}")
|
||||||
|
else:
|
||||||
|
print(f"Failed to open video writer for {save_path}")
|
||||||
|
writer = None
|
||||||
|
else:
|
||||||
|
print("No frame available to determine video dimensions")
|
||||||
|
if key == ord("e"):
|
||||||
|
is_save = False
|
||||||
|
if writer is not None:
|
||||||
|
writer.release()
|
||||||
|
writer = None
|
||||||
|
if save_path is not None:
|
||||||
|
print(f"Stop writing to {save_path}, total frames: {frame_count}")
|
||||||
|
else:
|
||||||
|
print(f"Stop writing, total frames: {frame_count}")
|
||||||
|
frame_count = 0
|
||||||
|
|
||||||
|
sensor1.disconnect() # 断开传感器连接
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
+1
-1
@@ -12,7 +12,7 @@
|
|||||||
"stitcher": {
|
"stitcher": {
|
||||||
"min_area_frac": 0.01,
|
"min_area_frac": 0.01,
|
||||||
"max_area_frac": 0.04,
|
"max_area_frac": 0.04,
|
||||||
"max_aspect_ratio": 100,
|
"max_aspect_ratio": 50,
|
||||||
"index": [1,2,3,6,7,8,11,12,13],
|
"index": [1,2,3,6,7,8,11,12,13],
|
||||||
"margin": 10,
|
"margin": 10,
|
||||||
"nominal_ov_pos": 100,
|
"nominal_ov_pos": 100,
|
||||||
|
|||||||
@@ -124,21 +124,21 @@ def main():
|
|||||||
# 1. 配置多个传感器
|
# 1. 配置多个传感器
|
||||||
# =========================================================================
|
# =========================================================================
|
||||||
# 目标帧率:设为正数时,两路传感器会按此帧率限速,使 FPS 接近一致;设为 None 则不限速
|
# 目标帧率:设为正数时,两路传感器会按此帧率限速,使 FPS 接近一致;设为 None 则不限速
|
||||||
target_fps = 15
|
target_fps = 30
|
||||||
|
|
||||||
num_sensors = 2
|
num_sensors = 2
|
||||||
sensor_configs = [
|
sensor_configs = [
|
||||||
{
|
{
|
||||||
'sensor_id': 0,
|
'sensor_id': 0,
|
||||||
'vid_src': './s1_720p.mp4',
|
'vid_src': 4,
|
||||||
'config_name': './config/prototype_of3_720p.json',
|
'config_name': './config/prototype_of3_480p.json',
|
||||||
'cal_path': './config/dd01a_0_720p.npy'
|
'cal_path': './config/dd01a_0_480p.npy'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'sensor_id': 1,
|
'sensor_id': 1,
|
||||||
'vid_src': './s1_720p.mp4', # 可以改为不同的视频源或摄像头索引
|
'vid_src': 6, # 可以改为不同的视频源或摄像头索引
|
||||||
'config_name': './config/prototype_of3_720p.json',
|
'config_name': './config/prototype_of3_480p.json',
|
||||||
'cal_path': './config/dd01a_0_720p.npy'
|
'cal_path': './config/dd01a_0_480p.npy'
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ def main():
|
|||||||
# 打开视频
|
# 打开视频
|
||||||
# sensor1 = Sensor("./s1.mp4",isstitch=True,cuda = True,verbose = True)
|
# sensor1 = Sensor("./s1.mp4",isstitch=True,cuda = True,verbose = True)
|
||||||
# 方式1: 从视频文件读取
|
# 方式1: 从视频文件读取
|
||||||
sensor1 = orisys.Sensor(0, config_name="./config/prototype_of3.json", cal_path= "./config/dd01a_0.npy", isstitch=True, cuda=False, verbose=True)
|
sensor1 = orisys.Sensor(8, config_name="./config/ddjx01.json", cal_path= "./config/ddjx01.npy", cuda=False, verbose=True)
|
||||||
|
|
||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
is_save = False
|
is_save = False
|
||||||
@@ -115,7 +115,7 @@ def main():
|
|||||||
|
|
||||||
writer.write(save_img)
|
writer.write(save_img)
|
||||||
|
|
||||||
sensor1.compute_deformation() # 计算形变和分解
|
sensor1.compute_deformation(check_motion=False) # 计算形变和分解
|
||||||
# 提取信息:
|
# 提取信息:
|
||||||
# 向量场: VRAW, VNORMAL, VSHEAR: 原始,法向,切向
|
# 向量场: VRAW, VNORMAL, VSHEAR: 原始,法向,切向
|
||||||
# 帧率,时间戳: FPS, TIMESTAMP
|
# 帧率,时间戳: FPS, TIMESTAMP
|
||||||
|
|||||||
@@ -115,8 +115,10 @@ def generate_color_pattern(h, w, d, r):
|
|||||||
def main():
|
def main():
|
||||||
# Parameters for the pattern.
|
# Parameters for the pattern.
|
||||||
# For example, using 100x100 pixels image with patches of 3x3 pixels.
|
# For example, using 100x100 pixels image with patches of 3x3 pixels.
|
||||||
height = 2750
|
# height = 2750
|
||||||
width = 1950
|
# width = 1950
|
||||||
|
height = 1200
|
||||||
|
width = 1000
|
||||||
patch_size = 12
|
patch_size = 12
|
||||||
# Set r to a value that gives sufficient difference.
|
# Set r to a value that gives sufficient difference.
|
||||||
# Note: r is the threshold for squared difference per channel, and the condition is
|
# Note: r is the threshold for squared difference per channel, and the condition is
|
||||||
|
|||||||
@@ -449,7 +449,7 @@ class Stitcher:
|
|||||||
n_boxes = 0
|
n_boxes = 0
|
||||||
bk_thresh = 0 # initial black threshold
|
bk_thresh = 0 # initial black threshold
|
||||||
bk_thresh_step = 5
|
bk_thresh_step = 5
|
||||||
bk_thresh_max = 100
|
bk_thresh_max = 150
|
||||||
|
|
||||||
# Also include a low global V threshold to capture colored but dark tiles
|
# Also include a low global V threshold to capture colored but dark tiles
|
||||||
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
|
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
|
||||||
@@ -458,7 +458,12 @@ class Stitcher:
|
|||||||
while n_boxes != n_boxes_target and bk_thresh <= bk_thresh_max:
|
while n_boxes != n_boxes_target and bk_thresh <= bk_thresh_max:
|
||||||
_, v_mask = cv2.threshold(v, bk_thresh, 255, cv2.THRESH_BINARY) # tune 50 if needed
|
_, v_mask = cv2.threshold(v, bk_thresh, 255, cv2.THRESH_BINARY) # tune 50 if needed
|
||||||
|
|
||||||
mask = v_mask
|
mask = v_mask.copy()
|
||||||
|
# Exclude left and right boundary (20 pixels each) from detection
|
||||||
|
edge = 20
|
||||||
|
if w > edge * 2:
|
||||||
|
mask[:, :edge] = 0
|
||||||
|
mask[:, -edge:] = 0
|
||||||
|
|
||||||
# Morphology: remove small specks, fill small holes
|
# Morphology: remove small specks, fill small holes
|
||||||
k = max(1, morph_k)
|
k = max(1, morph_k)
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import pyopencl as cl
|
||||||
|
|
||||||
|
# Get all platforms
|
||||||
|
platforms = cl.get_platforms()
|
||||||
|
if not platforms:
|
||||||
|
raise RuntimeError("No OpenCL platforms found")
|
||||||
|
|
||||||
|
# Use the first platform (rusticl in your case)
|
||||||
|
platform = platforms[0]
|
||||||
|
print("Using platform:", platform.name)
|
||||||
|
|
||||||
|
# Get devices for that platform
|
||||||
|
devices = platform.get_devices()
|
||||||
|
if not devices:
|
||||||
|
raise RuntimeError("No devices found on platform")
|
||||||
|
|
||||||
|
for platform in cl.get_platforms():
|
||||||
|
for device in platform.get_devices():
|
||||||
|
print("Device:", device.name)
|
||||||
|
# if device.type & cl.device_type.GPU == 0:
|
||||||
|
# print("Skipping non-GPU device:", device.name)
|
||||||
|
|
||||||
|
# Use the first device (your Adreno GPU)
|
||||||
|
device = devices[0]
|
||||||
|
print("Using device:", device.name)
|
||||||
|
|
||||||
|
# Create a context with that device
|
||||||
|
ctx = cl.Context([device])
|
||||||
|
|
||||||
|
# Create a command queue
|
||||||
|
queue = cl.CommandQueue(ctx)
|
||||||
|
|
||||||
|
print("Context and command queue created successfully!")
|
||||||
Reference in New Issue
Block a user