# Configuration file for ReSpeaker USB 4 Mic Array (ReSpeaker USB Mic Array v2.0)
version = "2.1";
# Raw
raw:
{
fS = 24000;
hopSize = 128;
nBits = 16;
nChannels = 16;
# Input with raw signal from microphones
interface: {
type = "soundcard";
card = 1;
device = 0;
}
}
# Mapping
mapping:
{
map: (2, 3, 4, 5);
}
# General
general:
{
epsilon = 1E-20;
size:
{
hopSize = 128;
frameSize = 256;
};
samplerate:
{
mu = 16000;
sigma2 = 0.01;
};
speedofsound:
{
mu = 343.0;
sigma2 = 25.0;
};
mics = (
# Microphone 2
{
mu = ( -0.032, +0.000, +0.000 );
sigma2 = ( +0.000, +0.000, +0.000, +0.000, +0.000, +0.000, +0.000, +0.000, +0.000 );
direction = ( +0.000, +0.000, +1.000 );
angle = ( 80.0, 100.0 );
},
# Microphone 3
{
mu = ( +0.000, -0.032, +0.000 );
sigma2 = ( +0.000, +0.000, +0.000, +0.000, +0.000, +0.000, +0.000, +0.000, +0.000 );
direction = ( +0.000, +0.000, +1.000 );
angle = ( 80.0, 100.0 );
},
# Microphone 4
{
mu = ( +0.032, +0.000, +0.000 );
sigma2 = ( +0.000, +0.000, +0.000, +0.000, +0.000, +0.000, +0.000, +0.000, +0.000 );
direction = ( +0.000, +0.000, +1.000 );
angle = ( 80.0, 100.0 );
},
# Microphone 5
{
mu = ( +0.000, +0.032, +0.000 );
sigma2 = ( +0.000, +0.000, +0.000, +0.000, +0.000, +0.000, +0.000, +0.000, +0.000 );
direction = ( +0.000, +0.000, +1.000 );
angle = ( 80.0, 100.0 );
}
);
# Spatial filter to include only a range of direction if required
# (may be useful to remove false detections from the floor)
spatialfilters = (
{
direction = ( +0.000, +0.000, +1.000 );
angle = (80.0, 100.0);
}
);
nThetas = 181;
gainMin = 0.25;
};
# Stationnary noise estimation
sne:
{
b = 3;
alphaS = 0.1;
L = 150;
delta = 3.0;
alphaD = 0.1;
}
# Sound Source Localization
ssl:
{
nPots = 4;
nMatches = 10;
probMin = 0.5;
nRefinedLevels = 1;
interpRate = 4;
# Number of scans: level is the resolution of the sphere
# and delta is the size of the maximum sliding window
# (delta = -1 means the size is automatically computed)
scans = (
{ level = 2; delta = -1; },
{ level = 4; delta = -1; }
);
# Output to export potential sources
potential: {
# format = "undefined";
format = "json";
interface: {
#type = "blackhole";
type = "socket"; ip = "127.0.0.1"; port = 9000;
#type = "terminal";
};
};
};
# Sound Source Tracking
sst:
{
# Mode is either "kalman" or "particle"
mode = "kalman";
# Add is either "static" or "dynamic"
add = "dynamic";
# Parameters used by both the Kalman and particle filter
active = (
{ weight = 1.0; mu = 0.4; sigma2 = 0.0025 }
);
inactive = (
{ weight = 1.0; mu = 0.25; sigma2 = 0.0025 }
);
sigmaR2_prob = 0.0025;
sigmaR2_active = 0.0225;
sigmaR2_target = 0.0025;
Pfalse = 0.1;
Pnew = 0.1;
Ptrack = 0.8;
theta_new = 0.9;
N_prob = 5;
theta_prob = 0.8;
N_inactive = ( 250, 250, 250, 250 );
theta_inactive = 0.9;
# Parameters used by the Kalman filter only
kalman: {
sigmaQ = 0.001;
};
# Parameters used by the particle filter only
particle: {
nParticles = 1000;
st_alpha = 2.0;
st_beta = 0.04;
st_ratio = 0.5;
ve_alpha = 0.05;
ve_beta = 0.2;
ve_ratio = 0.3;
ac_alpha = 0.5;
ac_beta = 0.2;
ac_ratio = 0.2;
Nmin = 0.7;
};
target: ();
# Output to export tracked sources
tracked: {
format = "json";
interface: {
type = "file"; path = "tracks.txt";
#type = "socket"; ip = "127.0.0.1"; port = 9001;
#type = "terminal";
};
};
}
sss:
{
# Mode is either "dds", "dgss" or "dmvdr"
mode_sep = "dds";
mode_pf = "ms";
gain_sep = 1.0;
gain_pf = 10.0;
dds: {
};
dgss: {
mu = 0.01;
lambda = 0.5;
};
dmvdr: {
};
ms: {
alphaPmin = 0.07;
eta = 0.5;
alphaZ = 0.8;
thetaWin = 0.3;
alphaWin = 0.3;
maxAbsenceProb = 0.9;
Gmin = 0.01;
winSizeLocal = 3;
winSizeGlobal = 23;
winSizeFrame = 256;
};
ss: {
Gmin = 0.01;
Gmid = 0.9;
Gslope = 10.0;
};
separated: {
fS = 16000;
hopSize = 128;
nBits = 16;
interface: {
type = "file";
path = "separated.raw";
};
};
postfiltered: {
fS = 16000;
hopSize = 128;
nBits = 16;
gain = 10.0;
interface: {
type = "file";
path = "postfiltered.raw";
};
};
};
classify:
{
frameSize = 4096;
winSize = 3;
tauMin = 88;
tauMax = 551;
deltaTauMax = 20;
alpha = 0.3;
gamma = 0.05;
phiMin = 0.5;
r0 = 0.2;
category: {
format = "undefined";
interface: {
type = "blackhole";
}
}
}
#!/usr/bin/env python
#改进后加入摄像头画面,实现声像融合,校正声像仪画面,配合usb4.cfg使用,加入热力图(一个声源座标点),标准圆那个方案尝试多个点绘图尝试一下(实际声源的四个点),可以显示,红蓝正常显示
import math
import socket
import sys
import threading
import random
import os
import time
import struct
import cv2
import signal
import json
import ast
import numpy as np
from heatmappy import Heatmapper
from PIL import Image
import matplotlib.pyplot as plt
matrix = np.array([[1150.4796065932892, 0.0, 866.7906072916296],
[0.0, 1154.5867399421018, 498.44391507650516],
[0.0, 0.0, 1.0]], dtype=float)
new_camera_matrix = np.array([[561.1795654296875, 0.0, 854.4371857272781],
[0.0, 523.6474609375, 371.79368114244426],
[0.0, 0.0, 1.0]], dtype=float)
dist = np.array([[-0.4210920702510668, 0.2214943232573482, 0.0012200103644413377, 0.001434741235348292, -0.06668565568366154]], dtype=float)
cmd ='build/bin/odaslive -c config/usb4.cfg'
os.system(cmd)
stop = False
HOST = "0.0.0.0"
PORT = 9000
SOCK_ADDR = (HOST, PORT)
def generate_random_points(center, x_range, y_range, num_points):
points = []
for _ in range(num_points):
x = random.randint(center[0] - x_range, center[0] + x_range)
y = random.randint(center[1] - y_range, center[1] + y_range)
points.append((x, y)) # 使用元组存储坐标点
return points
class SocketClientObject(object):
def __init__(self, socket, address ):
self.socket = socket
self.address = address
class ClientThread(threading.Thread):
def __init__(self, client_object):
threading.Thread.__init__(self)
self.client_object = client_object
def run(self):
global running
while running:
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1920)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 1080)
count = 0
while True:
ret, frame = cap.read()
frame = cv2.undistort(frame, matrix, dist, new_camera_matrix)
frame = cv2.resize(frame, (1920, 1080))
data = self.client_object.socket.recv(20480)
data = data.decode("utf-8")
data = data.replace("\n", "")
try:
src = (data.split('[')[1]).split(']')[0]
items = src.split(", ")
all_example_points = []
for item in items:
# 解析JSON数据
target = json.loads(item)
# 计算坐标
x = float(target["x"])
y = -float(target["y"])
z = float(target["z"])
camera_focal_length = 806
az = math.atan2(y, x)
inc = math.acos(z)
s = int(camera_focal_length * np.tan(inc))
m = int(s * np.cos(az))
n = int(s * np.sin(az))
center_x = 960 + m
center_y = 540 - n
example_points = (center_x, center_y)
# 将计算结果添加到列表中
all_example_points.append(example_points)
frame_pil = Image.fromarray(frame)
heatmapper = Heatmapper(point_strength=1, opacity=0.9, point_diameter=500)
heatmap = heatmapper.heatmap_on_img(all_example_points, frame_pil)
print("热度图生成完成")
#heatmap.save(f'heatmap_{count}.png') # 保存带有不同文件名的热度图
#count += 1 # 更新计数
heatmap_np = np.array(heatmap)
heatmap_np = cv2.cvtColor(heatmap_np, cv2.COLOR_BGR2RGB)
cv2.imshow('Heatmap', heatmap_np)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
except Exception as e:
print("发生异常:", e)
cap.release()
cv2.destroyAllWindows()
self.client_object.socket.close()
def stop_handler(signum, frame):
global running
running = False
signal.signal(signal.SIGINT, stop_handler)
def main():
global running
running = True
try:
sock1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock1.bind(SOCK_ADDR)
sock1.listen(5)
while running:
(clientsocket, address) = sock1.accept()
print (" Accept client: ", address)
ct = ClientThread(SocketClientObject(clientsocket, address))
ct.start()
except:
print ("#! EXC: ", sys.exc_info())
sock1.close()
print ("THE END! Goodbye!")
if __name__ == "__main__":
main()
#!/bin/bash
# 杀死之前可能仍在运行的程序,第二次启动时注意文件名与第一次启动的相一致
# 启动指令:./start.sh
pkill -f "python3 test33.py"
pkill -f "build/bin/odaslive"
# 启动第一个程序并在后台运行
python3 test33.py &
# 等待一段时间,确保第一个程序有足够的时间启动并打开麦克风设备
sleep 5
# 启动第二个程序并在后台运行
build/bin/odaslive -c config/usb4.cfg