精华内容
下载资源
问答
  • 测斜原始数据处理工具

    千次阅读 2019-04-04 15:33:37
    测斜原始数据处理工具 敬告:软件仅可以用于科学研究或数据分析等常规使用,不可应用于违反法律法规的活动中。 使用说明:、一、按钮: , 【 清屏 】 清除第 6 行以后的所有数据和表格.对两个测斜孔进行连续演算...

    测斜原始数据处理工具

    敬告:软件仅可以用于科学研究或数据分析等常规使用,不可应用于违反法律法规的活动中。

    1. 软件简介

    本软件用于模拟测斜原始数据。工程监测技术交流QQ群:452847739,会提供持续的软件更新及通知。软件作者QQ:3339745885,关于软件的任何问题欢迎咨询作者。

    1.1 主要功能

    根据模版中测孔 深度、本次累计、位移变化量模拟不同型号测斜仪的原始数据。

    1.2 软件下载与安装

    体验链接 https://pan.baidu.com/s/1xRE1Xp03t4uc8LSKmbAHsg 提取码:v3ex
    下载“测斜数据处理专家x86”文件中的所有内容。

    系统要求:windows xp/win7/win8/win10,不依赖office软件。
    软件为免安装版本,打开“测斜数据处理专家x86”文件夹,找到并安装vcredist_x86.exe后即可打开:测斜数据处理专家x86.exe 使用。

    2. 软件使用说明

    2.1 软件主界面

    基本参数设置选择默认。

    软件界面参数的设置
    测斜仪: 武汉基深、河北北方、北京航天,这里选择不同的牌子,可以自动的设置系数k的值,以及输出该品牌仪器的结果。不同仪器品牌测斜仪的原始结果是不同的。

    深度测段长度 这两个参数用于软件生成模版时候使用,模拟时候不起作用。
    系数K:不同的测斜仪该数值有所不同, K 为“ A + ”和“ A-”计算“测值”时所乘的系数,武汉基深和河北北方的仪器 K 值一般为 1 ,北京航夭的仪器 K 值一般为 0.01。
    系统偏差: 仪器一般都有一个系统偏差,不是太重要,如果你的原始数据中无该值就从生成的原始数据中删去该列即可。
    起算数据: 孔底或者孔口作为起算基准的选项,软土地基的测斜,常采用孔口起算数据,并用孔口的水平位移加以改正。
    首行数据: 有的喜欢把孔口数据放在第一行,有的喜欢把孔底数据放在第一行,应人而异。

    2.2 数据模版讲解

    软件不能凭空产生数据,处理数据前提是需要数据模版。软件所在目录下已经存在了一些数据模版,可以使用自带模版学习软件的使用方法和技巧。然后根据自带模版和模版制作说明制作自己的模版。

    深度: 即为测斜孔的深度;
    本次累计: 模拟数据的基础数据,即上一次的监测数据;
    位移变化量: 下次一希望的变化多少的量值。

    2.3 模拟出测斜数据讲解

    A+A- :分别是测斜观测时两个放心(基坑内和基坑外朝向)。
    测值: 与测段有关,测段 0.5米时,测值=(A+ 减 A-);测段1米时,测值=A+减A-。

    3. 服务支持与常见问题

    试用版软件无法保存,注册后即可保存成安装包中excel格式文件。
    关于软件使用上的反馈和改进可以随时联系作者,作者QQ:3339745885或者加入工程监测技术交流群获得新版软件信息,群号为:452847739。

    展开全文
  • Android 获取GNSS原始数据

    千次阅读 热门讨论 2020-04-05 12:03:17
    获取安卓设备的GNSS测量数据方法 2016 年 5 月,Google 在 I/O 开发者会议上宣布,将为 Android Nougat 操作系统中的应用程序提供原始 GNSS 观测数据。 API参考(Google中文官网)DEMO参考(GNSSLogger) 1. 用到的...

    获取安卓设备的GNSS测量数据方法

    2016 年 5 月,Google 在 I/O 开发者会议上宣布,将为 Android Nougat 操作系统中的应用程序提供原始 GNSS 观测数据。
    API参考(Google中文官网)DEMO参考(GNSSLogger

    1. 用到的类

    注释
    LocationManager用于注册GNSSmeasurement
    GnssMeasurementsEvent.Callback用于从GNSS引擎接收GNSS卫星测量值
    GnssMeasurementsEvent一个包含测量值数据的容器
    GnssClock包含GPS时钟时间戳记的类
    Gnssmeasurement代表GNSS卫星测量的类,其中包含原始信息和计算信息

    2.设置权限
    必须先在Manifest文件中设置相应的权限,否则将无法获取测量的回调数据

    <!--    所需权限-->
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
        <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
        <uses-permission android:name="android.permission.INTERNET" />
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
        <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/>
        <uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION"/>
        <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
        <uses-permission android:name="com.google.android.providers.gsf.permission.WRITE_GSERVICES"/>
        <!--    所需权限-->
    

    3.注册GNSSmeasurement

    private LocationManager mLocationManager;
    private GnssMeasurementsEvent.Callback gnssMeasurementEventListener =
                new GnssMeasurementsEvent.Callback()
    //这里先声明,重写方法将在下一步添加
    
    public void RegisterMeasurements(){
            @SuppressLint("MissingPermission")
            boolean is_register_success=
            mLocationManager.registerGnssMeasurementsCallback(gnssMeasurementEventListener);
            //注册GNSSmeasurement回调监听,返回是否注册成功的信息
            //测量信息将在GnssMeasurementsEvent.Callback中接收
        }
    //顺便把注销的方法也写了
    public void unRegisterMeasurements(){
            mLocationManager.unregisterGnssMeasurementsCallback(gnssMeasurementEventListener);
        }
    

    4.重写GnssMeasurementsEvent.Callback里的两个方法

    private GnssMeasurementsEvent.Callback gnssMeasurementEventListener =
                new GnssMeasurementsEvent.Callback() {
                    @Override
                    public void onGnssMeasurementsReceived(GnssMeasurementsEvent eventArgs) {
                        super.onGnssMeasurementsReceived(eventArgs);
                        //这里我们获取到了回调的测量数据容器:GnssMeasurementsEvent eventArgs
                        //TODO:
                    }
    
                    @Override
                    public void onStatusChanged(int status) {
                        super.onStatusChanged(status);
                    }
        };
    

    5.将测量数据转换为字符串

    1. 把GnssMeasurementsEvent拆分为GnssClock和Gnssmeasurement
    //写一个接收测量信息的方法
    public void onGnssMeasurementsReceived(GnssMeasurementsEvent event) {
            StringBuilder builder=new StringBuilder("GNSS测量数据:\n\n");
             //这里的toStringClock和toStringMeasurement将写在下一步里
            builder.append(toStringClock(event.getClock()));//写入gnss时钟的数据
            builder.append("\n");
            
            for (GnssMeasurement measurement : event.getMeasurements()) {
                builder.append(toStringMeasurement(measurement));//写入gnss测量数据
                builder.append("\n");
            }
    		//这里可以写runOnUiThread(...),将builder打印在屏幕上
    		//也可以修改返回值
        }
    
    
    1. 分别把GnssClock和Gnssmeasurement转化为字符串
    private String toStringClock(GnssClock gnssClock){
            //将GPS接收器时钟的值转换为字符串
            final String format = "   %-4s = %s\n";//定义数据显示格式,“%-4”表示左对齐、不足四位补足四位
            StringBuilder builder=new StringBuilder("GNSS时钟:\n");
            DecimalFormat numberFormat = new DecimalFormat("#0.000");//定义格式化数字
    
    
            if (gnssClock.hasLeapSecond()) {
                //如果闰秒存在则显示闰秒
                builder.append(String.format(format, "闰秒(LeapSecond)", gnssClock.getLeapSecond()));
            }
            builder.append(String.format(format, "硬件时钟(TimeNanos)", gnssClock.getTimeNanos()));//获取以毫秒为单位的GNSS接收器内部硬件时钟值
            if (gnssClock.hasTimeUncertaintyNanos()) {
                //获取硬件时钟的误差估计(不确定度)
                builder.append(String.format(format, "时钟误差估计(TimeUncertaintyNanos)", gnssClock.getTimeUncertaintyNanos()));
            }
    
            if (gnssClock.hasFullBiasNanos()) {
                //如果存在接收机本地时钟总偏差,则显示
                builder.append(String.format(format, "总时钟偏差(FullBiasNanos)", gnssClock.getFullBiasNanos()));
            }
            if (gnssClock.hasBiasNanos()) {
                //亚纳秒偏差
                builder.append(String.format(format, "亚偏差(BiasNanos)", gnssClock.getBiasNanos()));
            }
            if (gnssClock.hasBiasUncertaintyNanos()) {
                //FullBiasNanos和BiasNanos的误差估计
                builder.append(String.format(format, "时钟偏差估计(BiasUncertaintyNanos)", numberFormat.format(gnssClock.getBiasUncertaintyNanos())));
            }
            /**
             * 注意:以上五个数据用于计算GPS时钟
             * 具体计算方法为:local estimate of GPS time = TimeNanos - (FullBiasNanos + BiasNanos)
             *     世界标准时:UtcTimeNanos = TimeNanos - (FullBiasNanos + BiasNanos) - LeapSecond * 1,000,000,000
             */
            if (gnssClock.hasDriftNanosPerSecond()) {
                //以每秒纳秒为单位获取时钟的漂移
                builder.append(String.format(format, "时钟漂移(DriftNanosPerSecond)", numberFormat.format(gnssClock.getDriftNanosPerSecond())));
            }
            if (gnssClock.hasDriftUncertaintyNanosPerSecond()) {
                //时钟偏差的估计
                builder.append(String.format(format, "时钟漂移估计(DriftUncertaintyNanosPerSecond)", numberFormat.format(gnssClock.getDriftUncertaintyNanosPerSecond())));
            }
            //获取硬件时钟不连续的计数,即:每当gnssclock中断时,该值+1
            builder.append(String.format(format, "中断计数(HardwareClockDiscontinuityCount)", gnssClock.getHardwareClockDiscontinuityCount()));
            return builder.toString();
        }
    
    private String toStringMeasurement(GnssMeasurement measurement){
            //将GNSS测量结果转换为字符串
            //定义显示格式
            final String format = "   %-4s = %s\n";
            StringBuilder builder = new StringBuilder("GNSS测量结果:\n");
            DecimalFormat numberFormat = new DecimalFormat("#0.000");
            DecimalFormat numberFormat1 = new DecimalFormat("#0.000E00");
    
            //获取卫星ID
                /**
                 * 取决于卫星类型
                 * GPS:1-32
                 * SBAS:120-151、183-192
                 * GLONASS:OSN或FCN + 100之一
                 * 1-24作为轨道槽号(OSN)(首选,如果知道)
                 * 93-106作为频道号(FCN)(-7至+6)加100。即将-7的FCN编码为93,0编码为100,+ 6编码为106
                 * QZSS:193-200
                 * 伽利略:1-36
                 * 北斗:1-37
                 */
            builder.append(String.format(format, "卫星ID", measurement.getSvid()));
    
            //获取卫星类型
                /**
                 *  1:CONSTELLATION_GPS 使用GPS定位
                 *  2:CONSTELLATION_SBAS 使用SBAS定位
                 *  3:CONSTELLATION_GLONASS 使用格洛纳斯定位
                 *  4:CONSTELLATION_QZSS 使用QZSS定位
                 *  5:CONSTELLATION_BEIDOU 使用北斗定位 (^-^)!
                 *  6:CONSTELLATION_GALILEO 使用伽利略定位
                 *  7:CONSTELLATION_IRNSS 使用印度区域卫星定位
                 */
            builder.append(String.format(format, "卫星类型", measurement.getConstellationType()));
    
            //获取进行测量的时间偏移量(以纳秒为单位)
            builder.append(String.format(format, "测量时间偏移量", measurement.getTimeOffsetNanos()));
    
            //获取每个卫星的同步状态
            //具体数值含义请查表
            builder.append(String.format(format, "同步状态", measurement.getState()));
    
            //获取时间戳的伪距速率,以m/s为单位
            builder.append(
                    String.format(
                            format,
                            "伪距速率",
                            numberFormat.format(measurement.getPseudorangeRateMetersPerSecond())));
            //获取伪距的速率不确定性(1-Sigma),以m/s为单位
            builder.append(
                    String.format(
                            format,
                            "伪距速率不确定度",
                            numberFormat.format(measurement.getPseudorangeRateUncertaintyMetersPerSecond())));
            //
            if (measurement.getAccumulatedDeltaRangeState() != 0) {
                // 获取“累积增量范围”状态
                // 返回:MULTIPATH_INDICATOR_UNKNOWN(指示器不可用)=0
                // notice 即:指示器可用时,收集数据
                builder.append(
                        String.format(
                                format, "累积增量范围状态", measurement.getAccumulatedDeltaRangeState()));
    
                //获取自上次重置通道以来的累积增量范围,以米为单位.
                //该值仅在上面的state值为“可用”时有效
                //notice 累积增量范围= -k * 载波相位(其中k为常数)
                builder.append(
                        String.format(
                                format,
                                "累积增量范围",
                                numberFormat.format(measurement.getAccumulatedDeltaRangeMeters())));
    
                //获取以米为单位的累积增量范围的不确定性(1-Sigma)
                builder.append(
                        String.format(
                                format,
                                "累积增量范围不确定度",
                                numberFormat1.format(measurement.getAccumulatedDeltaRangeUncertaintyMeters())));
            }
    
            if (measurement.hasCarrierFrequencyHz()) {
                //获取被跟踪信号的载波频率
                builder.append(
                        String.format(format, "信号载波频率", measurement.getCarrierFrequencyHz()));
            }
    
            if (measurement.hasCarrierCycles()) {
                //卫星和接收器之间的完整载波周期数
                builder.append(String.format(format, "载波周期数", measurement.getCarrierCycles()));
            }
    
            if (measurement.hasCarrierPhase()) {
                //获取接收器检测到的RF相位
                builder.append(String.format(format, "RF相位", measurement.getCarrierPhase()));
            }
    
            if (measurement.hasCarrierPhaseUncertainty()) {
                //误差估计
                builder.append(
                        String.format(
                                format, "RF相位不确定度", measurement.getCarrierPhaseUncertainty()));
            }
    
            //获取一个值,该值指示事件的“多路径”状态,返回0或1或2
            //MULTIPATH_INDICATOR_DETECTED = 1 测量显示有“多路径效应”迹象
            // MULTIPATH_INDICATOR_NOT_DETECTED = 2 测量结果显示没有“多路径效应”迹象
            builder.append(String.format(format, "多路经效应指示器", measurement.getMultipathIndicator()));
    
            //
            if (measurement.hasSnrInDb()) {
                //获取信噪比(SNR),以dB为单位
                builder.append(String.format(format, "信噪比", measurement.getSnrInDb()));
            }
    
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
                if (measurement.hasAutomaticGainControlLevelDb()) {
                    //获取以dB为单位的自动增益控制级别
                    builder.append(String.format(format, "自动增益控制级别", measurement.getAutomaticGainControlLevelDb()));
                }
                if (measurement.hasCarrierFrequencyHz()) {
                    builder.append(String.format(format, "载波频率", measurement.getCarrierFrequencyHz()));
                }
            }
    
            return builder.toString();
    
        }
    

    最后将这些方法整合起来即可,UI显示的部分就不再赘述了。
    关于伪距如何计算见下一篇博客:通过GNSS原始数据计算伪距

    展开全文
  • 视频数据流的获取Android设备视频数据的获取,是调用Camera,所以需要在AndroidManifest中添加以下的权限: <uses-feature androi

    视频数据流的获取

    Android设备视频数据的获取,是调用Camera,所以需要在AndroidManifest中添加以下的权限:

    <uses-permission android:name="android.permission.CAMERA" />
    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />
    

    如果当前设备不支持自动对焦,则相关的设置将不起作用。

    首先,是拿到Camera对象并且设置摄像头采集的参数配置:

    mCamera = Camera.open(mCamId);
    Camera.Parameters params = mCamera.getParameters();//摄像头的参数
    

    参数如果不设置的话,一般会采用默认值,但现在市面上的所有设备配置不相同,如果全部按照默认的来可能出现未知的错误。例如相机拍照和预览的分辨率设置,如果和真实的手机不一样就会报错。

    params.setPictureSize(mEncoder.getPreviewWidth(), mEncoder.getPreviewHeight());//保存的照片的尺寸
    params.setPreviewSize(mEncoder.getPreviewWidth(), mEncoder.getPreviewHeight());//预览分辨率
    

    如果你不知道自己的设备支持哪些拍照或者是预览时的分辨率,Camera提供了相应的方法:

    for(int num = 0; num < params.getSupportedPreviewSizes().size(); num++){       
        Log.d(TAG,params.getSupportedPreviewSizes().get(num).width+"*"
            +params.getSupportedPreviewSizes().get(num).height);
        }
    

    上面的代码获取的是设备支持的所有的预览分辨率。下面贴一下我们设备相应的分辨率:

    分辨率

    除了设置采集的视频数据流的分辨率,还可以设置以下的相应参数:

    params.setPreviewSize(mEncoder.getPreviewWidth(), mEncoder.getPreviewHeight());//设置预览分辨率
        params.setPreviewFpsRange(int min, int max);//设置摄像头采集时的帧率
    

    之前的setPreviewFrameRate方法被现在的setPreviewFpsRange方法取代,该方法是设置摄像头每秒采集多少帧的视频数据流,min一般是用户自己预期设置的值,max是设备所能支持的最大帧数值(我的设备帧数的支持7.5到30),这个值计算时需要再*1000.

    当然设备支持的帧率也可以通过Camera提供的相应的方法获得:

        for(int num = 0; num < params.getSupportedPreviewFpsRange().size(); num++)
        {
            int[] SupPreRange = params.getSupportedPreviewFpsRange().get(num);
           Log.d(TAG, "< " + num + " >" + " Min = " + SupPreRange[0]
                    + "  Max = " + SupPreRange[1]);
        }
    
        params.setPreviewFormat(ImageFormat.NV21);//NV21 设置预览帧格式 默认是NV21(YUV420SP)格式
        关于这些我的上篇博客有着更加详细的介绍
        [上篇博客链接](http://blog.csdn.net/qq_26986211)
    
        params.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);//关闭闪光灯
        params.setWhiteBalance(Camera.Parameters.WHITE_BALANCE_AUTO);//曝光平衡
        params.setSceneMode(Camera.Parameters.SCENE_MODE_AUTO);//设置场景模式
        if (!params.getSupportedFocusModes().isEmpty()) {
            params.setFocusMode(params.getSupportedFocusModes().get(0));//自动对焦的效果
        }
    

    当然了,这些参数不一定在所有的设备上都是通用的,需要根据自的情况而定。如果你设置了相关的参数,而设备又不支持,那么这么的方法就不会被执行。

     mCamera.setParameters(params);//设置配置的参数
    
    mCamera.setDisplayOrientation(mPreviewRotation);//设置屏幕的旋转角度
    

    上面主要是针对垂直来说,因为这样设置的话一般是设置90,180,270。所以当用户大幅度转动设备的时候,设备就直接旋转了,如果需要自适应预览接连始终是正确的(这里的正确是指,无论用户怎么旋转,设备不会出现大幅度的旋转,保证了预览界面是正常的),就需要将重写setDisplayOrientation方法:

      public static void setCameraDisplayOrientation ( Activity activity ,
          int cameraId , android . hardware . Camera camera ) {
         android . hardware . Camera . CameraInfo info =
              new android . hardware . Camera . CameraInfo ();
         android . hardware . Camera . getCameraInfo ( cameraId , info );
      int rotation = activity . getWindowManager (). getDefaultDisplay ()
              . getRotation ();
      int degrees = 0 ;
      switch ( rotation ) {
          case Surface . ROTATION_0 : degrees = 0 ; break ;
          case Surface . ROTATION_90 : degrees = 90 ; break ;
          case Surface . ROTATION_180 : degrees = 180 ; break ;
          case Surface . ROTATION_270 : degrees = 270 ; break ;
      }
    
      int result ;
      if ( info . facing == Camera . CameraInfo . CAMERA_FACING_FRONT ) {
         result = ( info . orientation + degrees ) % 360 ;
         result = ( 360 - result ) % 360 ;   // compensate the mirror
      } else {   // back-facing
         result = ( info . orientation - degrees + 360 ) % 360 ;
      }
     camera . setDisplayOrientation ( result );
    

    }

    接下就是预览回调的注册了,在Camera提供了三种方法:

                setPreviewCallback(Camera.PreviewCallback) 
                setOneShotPreviewCallback(Camera.PreviewCallback) 
                setPreviewCallbackWithBuffer(Camera.PreviewCallback)
    

    setPreviewCallback(Camera.PreviewCallback) 。这个方法不需要用户自己分配相应的Buffer数组,由系统默认自动分配。只要预览帧可用,该方法就会一直被调用,此时其他的回调函数将会被覆盖。

    setOneShotPreviewCallback(Camera.PreviewCallback)。这个方法也不需要用户自己分配数组大小,从字面上也可以理解出来,调用一次之后,数据将会被清楚,但该方法可以随时被调用,执行此函数时,其他的回调函数将会被覆盖。

    setPreviewCallbackWithBuffer(Camera.PreviewCallback)。使用该函数之前我们需要指定一个字节数组作为缓冲区,大小一般也是有用户自己根据实际情况自己设置的。由于摄像头采集的数据流是YUV格式的,一般 Y = width*height,U = Y/4,V = Y/4;所以YUV数据的大小是width*height*3/2,所以字节数组的大小一般是width*height*3/2。需要先调mCamera.addCallbackBuffer()方法,参数是分配大小的字节数组。所以这两个方法是绑定在一起的使用的。

    回调函数的具体注册使用如下:以setPreviewCallbackWithBuffer为例

    mCamera.setPreviewCallbackWithBuffer(this);
    

    接下来就是视频真正开始预览,获取数据了

    mCamera.startPreview();
    

    开始预览之后,同时之前也设置了回调函数,程序就会自动调用onPreviewFrame函数,在主类继承了implements SurfaceHolder.Callback, Camera.PreviewCallback。系统就会重载onPreviewFrame函数。

    public void onPreviewFrame(byte[] data, Camera camera) {
        //将取得的视频数据发送出去,在这了你也可以实现别的功能
        onGetYuvFrame(data);
        //这个接口调用前,我们需要提前分配一块buffer,并且这个接口调用一定要放在onPreviewFrame()回调中:
        camera.addCallbackBuffer(mYuvPreviewFrame);
    }
    

    该函数的参数中 data就是最原始的视频数据流,如果你需要进行预览时的一些摄像头操作,一般也可以在onPreviewFrame函数中进行设置,例如人脸识别,但与视频数据打交道的时候,算法一般是非常的复杂的,所以一般是开启新的线程进行后续的操作。

    最后,摄像头不用的时候一定要释放资源:如果程序中加入了previewCallback,在surfaceDestroy释放camera的时候,最好执行myCamera.setOneShotPreviewCallback(null); 或者myCamera.setPreviewCallback(null);中止这种回调,然后再释放camera更安全。否则可能会报错。

    //关闭摄像头
    private void stopCamera() {
        if (mCamera != null) {
            // 停止预览前需要将摄像头的回调函数设置为空
            mCamera.setPreviewCallback(null);
            mCamera.stopPreview();
            mCamera.release();
            mCamera = null;
        }
    }
    

    音频数据流的获取

    Android音频设备是麦克风,使用时需要添加以下权限:

    音频的获取相比较视频获取来说,步骤简单得多,并没有太多复杂的配置:

    if (mic != null) {
            return;
        }
        //根据自己设置的音频格式配置相应的数组大小,用于存储数据,同时可以提高效率,节约空间
        int bufferSize = 2 * AudioRecord.getMinBufferSize(SrsEncoder.ASAMPLERATE, SrsEncoder.ACHANNEL, AudioFormat.ENCODING_PCM_16BIT);
        mic = new AudioRecord(MediaRecorder.AudioSource.MIC, SrsEncoder.ASAMPLERATE, SrsEncoder.ACHANNEL, AudioFormat.ENCODING_PCM_16BIT, bufferSize);
        mic.startRecording();
        byte pcmBuffer[] = new byte[2048];
        while (aloop && !Thread.interrupted()) {
            int size = mic.read(pcmBuffer, 0, pcmBuffer.length);
            if (size <= 0) {
                break;
            }
            //将获取的数据发送出去
            mEncoder.onGetPcmFrame(pcmBuffer, size);
        }
    

    这里介绍一下参数:

    ASAMPLERATE:音频采样率,有44100、22050、11025、4000、8000 等,代表了采样的品质高低,采样率越高品质越高。
    ACHANNEL:声道设置:android支持双声道立体声和单声道。MONO单声道,STEREO立体声
    AudioFormat.ENCODING_PCM_16BIT:采样大小为16bit 还可以设置成8bit

    这列涉及到要算一个PCM音频流的码率,采样率值×采样大小值×声道数bps。一个采样率为44.1KHz,采样大小为16bit,双声道的PCM编码的WAV文件,它的数据速率则为 44.1K×16×2 =1411.2 Kbps。我们常说128K的MP3,对应的WAV的参数,就是这个1411.2 Kbps,这个参数也被称为数据带宽,它和ADSL中的带宽是一个概念。将码率除以8,就可以得到这个WAV的数据速率,即176.4KB/s。这表示存储一秒钟采样率为44.1KHz,采样大小为16bit,双声道的PCM编码的音频信号,需要176.4KB的空间,1分钟则约为10.34M,这对大部分用户是不可接受的,尤其是喜欢在电脑上听音乐的朋友,要降低磁盘占用,只有2种方法,降低采样指标或者压缩。降低指标是不可取的,因此专家们研发了各种压缩方案。也就是我们后来说到的编码压缩。

    总结一下,如有不足之处请大家见谅,望指出批评。我是Mr.小艾

    展开全文
  • Android 相机回调原始数据解析

    千次阅读 2019-06-26 21:19:44
    首先说明一下,标题中的“相机”指的是Android原生接口Camera,“回调数据”指的是通过对Camera实例设置预览回调获取的数据: camera.setPreviewCallback(new Camera.PreviewCallback() { @Override public void...

    首先说明一下,标题中的“相机”指的是Android原生接口Camera,“回调数据”指的是通过对Camera实例设置预览回调获取的数据:

    camera.setPreviewCallback(new Camera.PreviewCallback() {
                @Override
                public void onPreviewFrame(byte[] data, Camera camera) {
                   
                    }
            });

    “解析”是指这里的byte[]数据无法直接保存为图片供我们使用,所以需要转码为我们常用的图片编码数据。这里先给出方法,再说明原因

     YuvImage image = new YuvImage(data, ImageFormat.NV21, width, height, null);
     ByteArrayOutputStream stream = new ByteArrayOutputStream();
     image.compressToJpeg(new Rect(0, 0, width, height), value, stream);
     byte[] newData=stream.toByteArray();

    注:上述中的data就是回调的原始数据,newData就是转换后的数据。宽高对应为预览的宽高数据,value是图片质量数值;这样转换之后就可以通过新的数据进行各种操作,保存为图片,转为bitmap等等。

     

    下面说明一下原因,可以选择不看;我们知道,Camera在使用的时候,我们可以通过获取Camera中的支持的各种参数用于我们的个性化设置:

    Camera.Parameters params = mCamera.getParameters();

    我们从params中可以读取当前Camera支持的预览尺寸列表,预览格式,拍照格式,闪光灯模式,白平衡,颜色效果等等,如:

     params.getSupportedPictureFormats();
     params.getSupportedPreviewFormats();
     params.getColorEffect();
     params.getWhiteBalance();
     params.getFlashMode();
     .........

    ok,我们重点关注数据类型,我们知道上面的原始数据来源于预览回调,所以我们重点查看Camera支持的预览数据格式,也即:

     List<Integer> list = params.getSupportedPreviewFormats();

    返回的是一个List列表,其中的元素是整形,其中的数值对应到ImageFormat类中定义的常量,我们调用上述方法可以查看当前摄像头支持的预览数据格式,可以通过下面的接口方法修改摄像头支持的预览格式:

     params.setPreviewFormat(ImageFormat.NV21);
     mCamera.setParameters(params);

    默认的格式就是NV21的,因为基本所以摄像头都支持该种格式,我们这个时候再回到上面的处理逻辑上:

    YuvImage image = new YuvImage(data, ImageFormat.NV21, width, height, null);

    这里的YuvImage API专门用于处理YUV编码的数据,我们先看一下文档介绍:

    * YuvImage contains YUV data and provides a method that compresses a region of
    * the YUV data to a Jpeg. The YUV data should be provided as a single byte
    * array irrespective of the number of image planes in it.
    * Currently only ImageFormat.NV21 and ImageFormat.YUY2 are supported.

    YuvImage内部包含有YUV编码数据,并且提供方法把这种转换为一张Jpeg图片。目前只支持ImageFormat.NV21与ImageFormat.YUY2类型的YUV数据

    我们知道YUV编码指的是一个类别,其中有很多种颜色编码格式,主要用于视频处理上,关于这块可以自行百度一下。上述通过预览的元素数据以及预览的宽高和格式就可以构建出一个YuvImage实例,我们在上面的文档中了解到,这个类中提供了把YUV数据转换为Jpeg图片的方法:

    image.compressToJpeg(new Rect(0, 0, width, height), value, stream);

    这个就实现了原始YUV数据到图片数据流的转换功能。其实到这里我们一直有一个疑惑,那就是我们可以把byte[]数据通过BitmapFactory中接口直接转为Bitmap数据,或者直接把原始的YUV数据data写到图片文件中,实际上这样操作的结果就是下列接口获取的Bitmap为空,图片文件也不能正常使用

     Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
    private void bytesToImageFile(byte[] data) {
            try {
                File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/why.jpeg");
                FileOutputStream fos = new FileOutputStream(file);
                fos.write(data, 0, bytes.length);
                fos.flush();
                fos.close();
            } catch (Exception e) {
                e.printStackTrace();
            }

    主要原因还是编码的问题,就好比是写了一篇作文,转化为16进制字符串保存为文件传给你的老师,他在没有转码的情况下觉得你的作文有问题;或者我用base64对其解码肯定也是不行的。本篇内容其实很单薄也很简单,但是在不了解的情况下还是会遇到这样的问题,一般遇到之后我们都会搜索byte[]数据与Bitmap,File等等之间的转换实现,但是在原始数据不转码的情况下,网上的工具类方法都是无法使用的。其实这里还有一种方法获取JPEG的byte数据,那就是通过回调回来的Camera的takePicture()接口实现:

     camera.takePicture(new Camera.ShutterCallback() {
                        @Override
                        public void onShutter() {
    
                        }
                    }, new Camera.PictureCallback() {
                        @Override
                        public void onPictureTaken(byte[] data, Camera camera) {
                         //data和预览的data一样
                        }
                    }, new Camera.PictureCallback() {
                        @Override
                        public void onPictureTaken(byte[] data, Camera camera) {
                          //data可以直接保存jpeg类型图片或者转为Bitmap都可以  
                        }
                    });

    上面的方式就是内部做了转换。

    注:欢迎扫码关注

     

     

    展开全文
  • 初传着可能会碰到各种疑问,可能试了好多次,无果,咨询同门仍是无果,大家涉及的内容有动植物微生物等,转录组、基因组等等不一,方法也不尽相同。为了避免多走弯路,下面就给大家介绍一下扩曾子数据上传NCBI的步骤...
  • GPS原始信号数据解析

    千次阅读 2020-05-06 11:04:04
    GPS 上电后,每隔一定的时间就会返回一定格式的数据数据格式为: $信息类型,x,x,x,x,x,x,x,x,x,x,x,x,x每行开头的字符都是'$',接着是信息类型,后面是数据,以逗号分隔开。 一行完整的数据如下: $...
  • Java程序员都要懂得知识点:原始数据类型

    万次阅读 多人点赞 2021-04-02 11:45:03
    本文分享自华为云社区《Java知识点问题总结之原始数据类型》,原文作者:breakDraw。 java原始数据类型有short、byte、int、long、boolean、char、float、double。原始数据是未处理的或简化的数据,它构成了物理...
  • 凯斯西储大学轴承数据具体处理过程 本文阐述处理类似凯斯西储大学的...如何将原始数据文件处理成可用的数据格式呢? 1、先用MATLAB将读出数据文件的内容 Y=load(‘E:\电脑桌面\实验资料\轴承数据\12kF_0hp\ball_0...
  • 常见视频原始数据格式分析 — YUV

    千次阅读 2018-12-22 10:22:46
    YUV 是比较常用的原始视频数据数据格式,视频采集芯片输出的码流大部分都是 YUV 数据流形式,而视频处理(如 H264、H265编码等),也是在原始 YUV 码流进行编码和解析。所以,了解熟悉 YUV 数据流对于做视频领域的人...
  • echarts设置原始数据及其自定义样式

    千次阅读 2018-03-22 15:37:41
    echarts 自定义原始数据样式 工作中遇到的echarts设置原始数据的问题 toolbox: { show: true, right: '10%', feature: { dataView: { readOnly: true //原始数据的textarea框只读 ...
  • 单片机采集的MPU6050原始数据对应关系

    万次阅读 多人点赞 2017-04-08 15:00:04
    单片机采集的MPU6050原始数据对应关系1.陀螺仪如下图,陀螺仪的范围有±250、±500、±2000可选,而对应的精度分别是131LSB/(°/s)、65.5LSB/(°/s)、32.8LSB/(°/s)、16.4 LSB/(°/s)a.那么这个精度和范围的关系是...
  • 我们已知均数、标准差及例数,如何生成一组模拟的原始数据呢?对大多数人来说,这是一个艰难的作业,下面分享一个简单的方法。 【工具/原料】临床医师统计学助手 V15.0 【方法/步骤】 一、首先我们到网上下载一个...
  • 【Java】原始数据类型与其包装类

    千次阅读 热门讨论 2018-04-01 21:23:40
      Java语言中默认定义了8个原始数据类型,大致可以分为4类: 整型:包含byte、short、int、long 浮点型:float、double 布尔型:boolean 字符:char   这8个基本的数据类型如果在声明的时候没有初始化,...
  • 原始数据极速上传NCBI SRA教程

    千次阅读 2018-05-17 00:00:00
    本文转载自“美吉生物”,己获授权,有修改。近日依旧收到不少老师的邮件,咨询如何将数据上传NCBI数据库的。今天小美就老话再谈,各位老师跟着小美再乘坐一次极速上传SRA的高铁,准备好了吗?...
  • 常见视频原始数据格式分析 — RGB

    千次阅读 2018-12-22 17:04:38
    3. 如果仍然有未填充的位,继续使用原始数据的低位进行循环补偿 例子: 16 bit RGB565 -> 24 bit RGB888 的转换 16 bit RGB656: R4 R3 R2 R1 R0 G5 G4 G3 G2 G1 G0 B4 B3 B2 B1 B0 24 bit RGB888: R4 R3 R2 R1 R0...
  • 本软件支持模拟数据的类型包括:天宝、莱卡、索佳、中纬、南方DL等数字水准仪原始数据。工程监测技术交流QQ群:452847739,会提供持续的软件更新及通知。软件作者QQ:3339745885,关于软件的任何问题欢迎咨询作者。...
  • Matlab从Figure中提取原始数据

    千次阅读 2020-01-06 21:39:17
    1 如果你的fig文件中的图像每个像素都有数据,可以通过以下方式获得图像每个点的值,输出data是矩阵,大小是图像像素的行列数 open('figname.fig'); h=get(gca,'Children'); data=get(h,'Cdata');...
  • 本文中,将给出一些Hello world级的图像数据集生成方法,以及其他相关图像数据资源的整理. 本文的主要内容包括: MNIST, CIFAR-10, CIFAR-100等.png或.jpg格式数据集的生成方法;如何编写脚本生成图
  • jqgrid获取原始数据,js对象拷贝

    千次阅读 2017-11-30 16:36:40
    用vue做项目碰到的一个js中关于对象拷贝的问题1.jqGrid获取行数据不能获取原始json数据的问题.jqGrid的$(your tableId).jqGrid(“getRowData”,id);方法是获取对应行id的行数据的,这就有个问题了,若返回数据的list是...
  • 导线、平面位移原始数据处理

    千次阅读 2018-07-14 16:07:50
    导线、平面位移原始数据模拟器 1. 软件简介 本软件用于模拟导线、平面位移等测量的原始数据。工程监测技术交流QQ群:452847739,会提供持续的软件更新及通知。软件作者QQ:3339745885,关于软件的任何问题欢迎...
  • 使用Retrofit获取原始的json数据

    千次阅读 2018-08-22 22:41:11
    之前项目的数据获取都是通过Okhttp来获取的,但是听说retrofit获取数据跟优越,就尝试使用retrofit在同样的数据接口上获取数据,由于是第一次所以走了很多弯路,现在做下记录方便自己或者大家以后直接使用,减少撞墙...
  • 一、原始数据质控 1.原始测序数据(也是reads) 从测序仪中直接取下来的数据,它包括了所有的碱基,无论是测序质量低的,还有可能包含测错的,可能还会包含实验误差。 2.数据质控 把原始测序数据 (raw data)据输入到...
  • PHP获取POST的原始数据方法小结

    万次阅读 2011-05-31 10:35:00
    PHP获取POST的原始数据方法
  • 但是由于原始数据量大,无法放到一个excel文件中,被分成了多个,在处理的时候选择了从文件夹获取数据的方式,处理后通过powerpivot进行了一系列的计算,发给同事后,发现修改文件夹路径是比较麻烦,通过百度,找到...
  • 原始数据,xi
  • 建模方法(四)-因子分析定义和应用

    万次阅读 多人点赞 2018-08-20 20:58:05
    因子分析(factor analysis)也是...原始的变量是可观测的显在变量,而 因子一般是不可观测的潜在变量。 例如:商店的环境、商店 的服务和商品的价格作为因子,这三个方面除了价格外,商店的环境 和服务质量,都是客观...
  • 用 Python 排序数据的多种方法

    万次阅读 2016-07-01 16:44:46
    用 Python 排序数据的多种方法 目录 【Python HOWTOs系列】排序 Python 列表有内置就地排序的方法 list.sort(),此外还有一个内置的 sorted() 函数将一个可迭代对象(iterable)排序为一个新的有序列表。...
  • 甲问:数仓建模时,涉及到uv(去重用户数)指标时,数据从哪里取,只能走ods原始数据层吗,汇总到dw层时,由于数据量太大,不能到用户粒度,所以在dw层中不包含用户粒度的数据,而且电商的报表分析,几乎每张报表都会...
  • 如下方法: public static boolean isArray(Object array) { if (array instanceof Object[]) { return true; } else if (array instanceof boolean[]) { return true; ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 783,463
精华内容 313,385
关键字:

原始数据方法