基于麦克风阵列的声源定位_python播放声音模块

基于麦克风阵列的声源定位_python播放声音模块上一篇文章说到odas_web界面非常难安装,并且运行也很卡。所以我自己用python写了一个界面程序,用来接收odas处理完的结果。这个界面程序与odas之间是通过socket连接的,界面作为服务器,odas作为客户端,由于有两路数据,所以各有两个服务器和客户端。但是实际绘制在界面上的是SSL的结果,不是SST的结果。其实我也试过SST的结果,从直观的感受而言,效果会比SSL差一些,实时性不是很高,我的理解SST的好处是可以跟踪音源是否有活动。

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

上一篇文章说到odas_web界面非常难安装,并且运行也很卡。所以我自己用python写了一个界面程序,用来接收odas处理完的结果。

这个界面程序与odas之间是通过socket连接的, 界面作为服务器,odas作为客户端,由于有两路数据,所以各有两个服务器和客户端。但是实际绘制在界面上的是SSL的结果,不是SST的结果。其实我也试过SST的结果,从直观的感受而言,效果会比SSL差一些,实时性不是很高,我的理解SST的好处是可以跟踪音源是否有活动。 

另外,我也试过把这个代码在树莓派3上跑,性能会比odas_web好不少,但是还是不如笔记本电脑跑得流畅。在树莓派上先要装python3-opencv,然后用python3来运行这个界面程序。

安装命令和两个程序的运行命令可以参考如下:

sudo apt install python3-opencv
python3 DOA_sound.py
./bin/odaslive -c config/odaslive/shao.cfg

视频:

麦克风阵列 声源定位 定向拾音_哔哩哔哩_bilibili基于麦克风阵列的声源定位_python播放声音模块https://www.bilibili.com/video/BV1xu411B7s3

下面附上我写的界面程序:

#!/usr/bin/env python
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

stop = False
HOST = "0.0.0.0"
PORT = 9000
SOCK_ADDR = (HOST, PORT)

PORT2 = 9001
SOCK_ADDR2 = (HOST, PORT2)


def stop_handler(signum, frame):
    global running
    running = False

signal.signal(signal.SIGINT, stop_handler) 

spectrum_rgb3_lut = [
	[   0,   0,   0 ],
	[   0,   0,   3 ],
	[   0,   0,   6 ],
	[   0,   0,   9 ],
	[   0,   0,  12 ],
	[   0,   0,  15 ],
	[   0,   0,  18 ],
	[   0,   0,  21 ],
	[   0,   0,  24 ],
	[   0,   0,  27 ],
	[   0,   0,  30 ],
	[   0,   0,  33 ],
	[   0,   0,  36 ],
	[   0,   0,  39 ],
	[   0,   0,  42 ],
	[   0,   0,  45 ],
	[   0,   0,  48 ],
	[   0,   0,  51 ],
	[   0,   0,  54 ],
	[   0,   0,  57 ],
	[   0,   0,  60 ],
	[   0,   0,  63 ],
	[   0,   0,  66 ],
	[   0,   0,  69 ],
	[   0,   0,  72 ],
	[   0,   0,  75 ],
	[   0,   0,  78 ],
	[   0,   0,  81 ],
	[   0,   0,  84 ],
	[   0,   0,  87 ],
	[   0,   0,  90 ],
	[   0,   0,  93 ],
	[   0,   0,  96 ],
	[   0,   0,  99 ],
	[   0,   0, 102 ],
	[   0,   0, 105 ],
	[   0,   0, 108 ],
	[   0,   0, 111 ],
	[   0,   0, 114 ],
	[   0,   0, 117 ],
	[   0,   0, 120 ],
	[   0,   0, 123 ],
	[   0,   0, 126 ],
	[   0,   0, 129 ],
	[   0,   0, 132 ],
	[   0,   0, 135 ],
	[   0,   0, 138 ],
	[   0,   0, 141 ],
	[   0,   0, 144 ],
	[   0,   0, 147 ],
	[   0,   0, 150 ],
	[   0,   0, 153 ],
	[   0,   0, 156 ],
	[   0,   0, 159 ],
	[   0,   0, 162 ],
	[   0,   0, 165 ],
	[   0,   0, 168 ],
	[   0,   0, 171 ],
	[   0,   0, 174 ],
	[   0,   0, 177 ],
	[   0,   0, 180 ],
	[   0,   0, 183 ],
	[   0,   0, 186 ],
	[   0,   0, 189 ],
	[   0,   0, 192 ],
	[   0,   0, 195 ],
	[   0,   0, 198 ],
	[   0,   0, 201 ],
	[   0,   0, 204 ],
	[   0,   0, 207 ],
	[   0,   0, 210 ],
	[   0,   0, 213 ],
	[   0,   0, 216 ],
	[   0,   0, 219 ],
	[   0,   0, 222 ],
	[   0,   0, 225 ],
	[   0,   0, 228 ],
	[   0,   0, 231 ],
	[   0,   0, 234 ],
	[   0,   0, 237 ],
	[   0,   0, 240 ],
	[   0,   0, 243 ],
	[   0,   0, 246 ],
	[   0,   0, 249 ],
	[   0,   0, 252 ],
	[   0,   0, 255 ],
	[   0,   3, 252 ],
	[   0,   6, 249 ],
	[   0,   9, 246 ],
	[   0,  12, 243 ],
	[   0,  15, 240 ],
	[   0,  18, 237 ],
	[   0,  21, 234 ],
	[   0,  24, 231 ],
	[   0,  27, 228 ],
	[   0,  30, 225 ],
	[   0,  33, 222 ],
	[   0,  36, 219 ],
	[   0,  39, 216 ],
	[   0,  42, 213 ],
	[   0,  45, 210 ],
	[   0,  48, 207 ],
	[   0,  51, 204 ],
	[   0,  54, 201 ],
	[   0,  57, 198 ],
	[   0,  60, 195 ],
	[   0,  63, 192 ],
	[   0,  66, 189 ],
	[   0,  69, 186 ],
	[   0,  72, 183 ],
	[   0,  75, 180 ],
	[   0,  78, 177 ],
	[   0,  81, 174 ],
	[   0,  84, 171 ],
	[   0,  87, 168 ],
	[   0,  90, 165 ],
	[   0,  93, 162 ],
	[   0,  96, 159 ],
	[   0,  99, 156 ],
	[   0, 102, 153 ],
	[   0, 105, 150 ],
	[   0, 108, 147 ],
	[   0, 111, 144 ],
	[   0, 114, 141 ],
	[   0, 117, 138 ],
	[   0, 120, 135 ],
	[   0, 123, 132 ],
	[   0, 126, 129 ],
	[   0, 129, 126 ],
	[   0, 132, 123 ],
	[   0, 135, 120 ],
	[   0, 138, 117 ],
	[   0, 141, 114 ],
	[   0, 144, 111 ],
	[   0, 147, 108 ],
	[   0, 150, 105 ],
	[   0, 153, 102 ],
	[   0, 156,  99 ],
	[   0, 159,  96 ],
	[   0, 162,  93 ],
	[   0, 165,  90 ],
	[   0, 168,  87 ],
	[   0, 171,  84 ],
	[   0, 174,  81 ],
	[   0, 177,  78 ],
	[   0, 180,  75 ],
	[   0, 183,  72 ],
	[   0, 186,  69 ],
	[   0, 189,  66 ],
	[   0, 192,  63 ],
	[   0, 195,  60 ],
	[   0, 198,  57 ],
	[   0, 201,  54 ],
	[   0, 204,  51 ],
	[   0, 207,  48 ],
	[   0, 210,  45 ],
	[   0, 213,  42 ],
	[   0, 216,  39 ],
	[   0, 219,  36 ],
	[   0, 222,  33 ],
	[   0, 225,  30 ],
	[   0, 228,  27 ],
	[   0, 231,  24 ],
	[   0, 234,  21 ],
	[   0, 237,  18 ],
	[   0, 240,  15 ],
	[   0, 243,  12 ],
	[   0, 246,   9 ],
	[   0, 249,   6 ],
	[   0, 252,   3 ],
	[   0, 255,   0 ],
	[   3, 252,   0 ],
	[   6, 249,   0 ],
	[   9, 246,   0 ],
	[  12, 243,   0 ],
	[  15, 240,   0 ],
	[  18, 237,   0 ],
	[  21, 234,   0 ],
	[  24, 231,   0 ],
	[  27, 228,   0 ],
	[  30, 225,   0 ],
	[  33, 222,   0 ],
	[  36, 219,   0 ],
	[  39, 216,   0 ],
	[  42, 213,   0 ],
	[  45, 210,   0 ],
	[  48, 207,   0 ],
	[  51, 204,   0 ],
	[  54, 201,   0 ],
	[  57, 198,   0 ],
	[  60, 195,   0 ],
	[  63, 192,   0 ],
	[  66, 189,   0 ],
	[  69, 186,   0 ],
	[  72, 183,   0 ],
	[  75, 180,   0 ],
	[  78, 177,   0 ],
	[  81, 174,   0 ],
	[  84, 171,   0 ],
	[  87, 168,   0 ],
	[  90, 165,   0 ],
	[  93, 162,   0 ],
	[  96, 159,   0 ],
	[  99, 156,   0 ],
	[ 102, 153,   0 ],
	[ 105, 150,   0 ],
	[ 108, 147,   0 ],
	[ 111, 144,   0 ],
	[ 114, 141,   0 ],
	[ 117, 138,   0 ],
	[ 120, 135,   0 ],
	[ 123, 132,   0 ],
	[ 126, 129,   0 ],
	[ 129, 126,   0 ],
	[ 132, 123,   0 ],
	[ 135, 120,   0 ],
	[ 138, 117,   0 ],
	[ 141, 114,   0 ],
	[ 144, 111,   0 ],
	[ 147, 108,   0 ],
	[ 150, 105,   0 ],
	[ 153, 102,   0 ],
	[ 156,  99,   0 ],
	[ 159,  96,   0 ],
	[ 162,  93,   0 ],
	[ 165,  90,   0 ],
	[ 168,  87,   0 ],
	[ 171,  84,   0 ],
	[ 174,  81,   0 ],
	[ 177,  78,   0 ],
	[ 180,  75,   0 ],
	[ 183,  72,   0 ],
	[ 186,  69,   0 ],
	[ 189,  66,   0 ],
	[ 192,  63,   0 ],
	[ 195,  60,   0 ],
	[ 198,  57,   0 ],
	[ 201,  54,   0 ],
	[ 204,  51,   0 ],
	[ 207,  48,   0 ],
	[ 210,  45,   0 ],
	[ 213,  42,   0 ],
	[ 216,  39,   0 ],
	[ 219,  36,   0 ],
	[ 222,  33,   0 ],
	[ 225,  30,   0 ],
	[ 228,  27,   0 ],
	[ 231,  24,   0 ],
	[ 234,  21,   0 ],
	[ 237,  18,   0 ],
	[ 240,  15,   0 ],
	[ 243,  12,   0 ],
	[ 246,   9,   0 ],
	[ 249,   6,   0 ],
	[ 252,   3,   0 ],
	[ 255,   0,   0 ]]


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 == True:
            img = np.zeros((800,800,3),np.uint8)
            data = self.client_object.socket.recv(1024)
            data = data.decode("utf-8")
            data = data.replace("\n", "")
            try:
                src = (data.split('[')[1]).split(']')[0]
                items = src.split(",        ")
                target = json.loads(items[0])
                x = int(float(target["x"]) * 400) + 400
                y = int(-float(target["y"]) * 400) + 400
                energy = int(float(target["E"]) * 255)
                if (energy > 80):
                    cv2.circle(img,  (x, y),  30,  (spectrum_rgb3_lut[255- energy][0], spectrum_rgb3_lut[255- energy][1], spectrum_rgb3_lut[255- energy][2]), -1)
                cv2.imshow('pu', img)
                if cv2.waitKey(1) & 0xFF == ord('q'):
                    break

            except:
                print "problem1"

        cv2.destroyAllWindows()
        self.client_object.socket.close()


class VideoThread(threading.Thread):
    def __init__(self,dest_object):
        threading.Thread.__init__(self)
        self.dest_object=dest_object

    def run(self):
        global running
        while running == True:
            #img = np.zeros((800,800,3),np.uint8)
            data = self.dest_object.socket.recv(1024)
            data = data.decode("utf-8")
            data = data.replace("\n", "")
            try:
                src = (data.split('[')[1]).split(']')[0]
                items = src.split(",        ")
                for item in items:
                    target = json.loads(item)
                    x = int(float(target["x"]) * 400) + 400
                    y = int(-float(target["y"]) * 400) + 400
                    activity = int(float(target["activity"]) * 255)
                    #if (activity > 100):
                    #    cv2.circle(img,  (x, y),  30, (0,255,0), -1)

                #cv2.imshow('pu2', img)
                #if cv2.waitKey(1) & 0xFF == ord('q'):
                    #break

            except:
                print "problem2"

        #cv2.destroyAllWindows()
        self.dest_object.socket.close()


def main():
    global running
    running = True

    try:
        sock1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock1.bind(SOCK_ADDR)
        sock1.listen(5)

        sock2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock2.bind(SOCK_ADDR2)
        sock2.listen(2)

        while running:
            (clientsocket, address) = sock1.accept()
            print " Accept client: ", address
            ct = ClientThread(SocketClientObject(clientsocket, address))
            ct.start()

            (dst,dst_addr) = sock2.accept()
	    print "Destination Connected by", dst_addr
            vt = VideoThread(SocketClientObject(dst,dst_addr))
	    vt.start()

    except:
        print "#! EXC: ", sys.exc_info()
        sock1.close()
        sock2.close()
        print "THE END! Goodbye!"

if __name__ == "__main__":
    main()

另外,我还附上我使用的shao.cfg文件:

# Configuration file for ReSpeaker USB 4 Mic Array (ReSpeaker USB Mic Array v2.0)

version = "2.1";

# Raw

raw: 
{

    fS = 16000;
    hopSize = 128;
    nBits = 16;
    nChannels = 6; 

    # Input with raw signal from microphones
    interface: {
        type = "soundcard";
        card = 2;
        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";
        }

    }

}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/193733.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • pycharm的运行环境_pycharm新环境怎么选

    pycharm的运行环境_pycharm新环境怎么选一直用pycharm写代码一直用anaconda管理python环境但是今天我居然发现我不会更改pycharm当前的运行环境到我新建的anacondaenvironment中!配置:系统:win10;GPU:NVIDIAGeForceGTX1050Ti管理平台:anaconda3IDE:Pycharm问题我的anaconda里面有三个环境,第一个是自…

    2022年8月26日
    3
  • 下载安装postman_POSTMAN

    下载安装postman_POSTMAN首先安装postman安装地址到这个连接下载对应的中文包

    2022年9月30日
    0
  • MAC双系统如何切换_mac双系统怎么进入mac系统

    MAC双系统如何切换_mac双系统怎么进入mac系统Mac上面安装双系统是一个很常见的系统选择方案。双系统之间的切换对于使用Mac的用户都不会陌生,但是对于许多初次接触Mac系统的用户而言,也有很多并不知道如何切换双系统,以及如何设置默认进入的系统。虽然只是一个很小的技巧,但是对于新接触Mac系统的用户如果不了解这个的话,那么使用中会有一定的麻烦。双系统的切换以及设置系统默认启动也有几种方法。-w+I4g$u#H#T1K一、开机按Op…

    2022年10月6日
    0
  • 让你彻底理解浅拷贝和深拷贝的区别是什么_怎么让文件无法拷贝

    让你彻底理解浅拷贝和深拷贝的区别是什么_怎么让文件无法拷贝在写js的时候经常会遇到复制对象,在复制对象的过程中往往会出现新对象改变原对象等等的一些问题,今天特意梳理一下,希望能帮助到遇到这些问题的开发人员。什么是浅拷贝,深拷贝以及和他们之间的区别赋值浅拷贝深拷贝在开始梳理之前先说一下值类型和引用类型:值类型(基本类型):字符串(string)、数值(number)、布尔值(boolean)、undefined、null;引用类型:对象(Object)、数组(Array)、函数(Function);1、什么是浅拷贝,深拷贝以及和他们之间的区别

    2022年10月1日
    0
  • poi系列(二):通过poi、poi-ooxml读取写出excel

    poi系列(二):通过poi、poi-ooxml读取写出excel(根据网上多篇文档实践整理加工,非原创也非转载)本类主要是读取后缀为xlsx或xls的excel操作。需要导入包<dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId>…

    2022年7月16日
    18
  • C/C++中随机函数rand()和srand()的用法「建议收藏」

    C/C++中随机函数rand()和srand()的用法「建议收藏」一、rand()函数名:rand功能:随机数发生器用法:intrand(void);所在头文件:stdlib.h函数说明:rand()的内部实现是用线性同余法做的,它不是真的随机数,因其周期特别长,故在一定的范围里可看成是随机的。

    2022年4月29日
    39

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号