What's that Noise? : Working with sound on Android

Sound is diverse. It's nature is to comprise of so many forms that solid rules cannot draw lines between them. I always have been an admirer of sound.

I have spent a few weeks implementing sound acquisition and processing in android and have come up with something to begin with.

Presenting:



Shh..Silence 

An application that monitors sound level of an environment and plays a 'Shhhh...' when noise levels pass a limit.

You can download it here:

Get it on Google Play
Google Play and the Google Play logo are trademarks of Google LLC.

For the end user, it is a harmless application but from an engineering point of view, the internals are a window to a ton of possibilities. 

The application monitors sound in the following manner : 
  1. Acquire Microphone 
  2. Configure 
    • Sample Rate
    • Mono/Stereo
    • Encoding format
    • Buffer size
  3. Calculate average over the buffer size
  4. Compare obtained value with threshold 
  5. Trigger when above threshold
    The pipeline is simple when dealing only with the average. Here's a code snippet for step 3:

     private void readAudioBuffer() {  
         try {  
           short[] buffer = new short[bufferSize];  
           int bufferReadResult = 1;  
           if (audio != null) {  
             bufferReadResult = audio.read(buffer, 0, bufferSize);  //Audio Samples
             double sumLevel = 0;  
             for (int i = 0; i < bufferReadResult; i++) {  
               sumLevel += buffer[i];  
             }  
             lastLevel = Math.abs((sumLevel / bufferReadResult));  
           }  
         } catch (Exception e) {  
           e.printStackTrace();  
         }  
       }  
    

    The most intriguing part of it is at bufferReadResult. It contains a sequence of numbers that depict the sound received by the microphone. Following this, it is a matter of requirement what needs to be done next. On extracting audio features like Mel Coefficients, MFCC etc, the application can be stretched to domains of Audio Classification, Speech Recognition, User Identification and Keyword Detection.

    Implementing ML/DL on android has become easier than ever using TensorFlow with a light framework. The next step is to develop an application that uses TensorFlow for purpose of classifying sounds.

    The Optimist sees the potential in a seed

    Kudos.

    An Infinite point possibilities : Intel's Open3D Library

    Intel have recently launched its open source library for 3D data processing Open3D  [ research paper by Qian-Yi Zhou and Jaesik Park and Vladlen Koltun ]

    *not the official logo, only for personal representation

    Open3D is an open-source library that supports rapid development of software that deals with 3D data. The Open3D frontend exposes a set of carefully selected data structures and algorithms in both C++ and Python. The backend is highly optimized and is set up for parallelization. Open3D was developed from a clean slate with a small and carefully considered set of dependencies. It can be set up on different platforms and compiled from source with minimal effort. The code is clean, consistently styled, and maintained via a clear code review mechanism. Open3D has been used in a number of published research projects and is actively deployed in the cloud.

    With Open3D, the library enables developers to work with 3D models and point clouds.
    Open3D has the following features:

    • Basic 3D data structures
    • Basic 3D data processing algorithms
    • Scene reconstruction
    • Surface alignment
    • 3D visualization
    With Open3D, RGBD images (Images with 3 color components and a Depth component) can be converted into 3D models. Here' a python code snippet to achieve just that:

     import sys  
     import py3d  
     import matplotlib.pyplot as plt  
     sys.path.append("../Open3D/build/lib/")  
     print("Read Redwood dataset")  
     color_raw = py3d.read_image("/home/<username>/Open3D/build/lib/TestData/RGBD/color/00000.jpg")  
     depth_raw = py3d.read_image("/home/<username>/Open3D/build/lib/TestData/RGBD/depth/00000.png")  
     rgbd_image = py3d.create_rgbd_image_from_color_and_depth(  
         color_raw, depth_raw);  
     print(rgbd_image)  
     plt.subplot(1, 2, 1)  
     plt.title('Redwood grayscale image')  
     plt.imshow(rgbd_image.color)  
     plt.subplot(1, 2, 2)  
     plt.title('Redwood depth image')  
     plt.imshow(rgbd_image.depth)  
     plt.show()  
     pcd = py3d.create_point_cloud_from_rgbd_image(rgbd_image,  
                            py3d.PinholeCameraIntrinsic.prime_sense_default)  
     pcd.transform([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]])  
     py3d.draw_geometries([pcd])  
     print("Writing ply file")  
     py3d.write_point_cloud("Redwood.ply", pcd)  
    

    The result obtained is as follows:


    Open3D has been developed keeping in mind the computations required for solving 3-dimensional geometry and the need for parallelization for faster turn-around times. It has an inbuilt visualiser which enables developers to visually examine their work and also manipulate them using pan and rotate controls along with a dozen more manipulations such as lighting, changing point size, toggling mesh wireframe etc.

    Open Source community has always accelerated the development of advanced tools and libraries. Looking forward to the community to scale this one ahead too.

    Limitations only exist if you let them
    <This post is an attempt to integrate 3D model in a webpage using webVR, stay tuned for a post update>

    Peace Out.

    Project AlphaUI : Computer Vision and Virtual Menu Navigation

    We have always sought of new ways to interact with computers. From typed commands to automatic speech recognition, the aim is to make it appear natural to us, as if not interacting with a computer but a Human.

    Project AlphaUI

    AlphaUI is a virtual menu interface that lets you interact naturally with the GUI displayed. It works by using a webcam to capture live frames and through Image Processing finds out where the user wants to point out in the given space.



    The Program is written in C++ using OpenCV 3.1.0 Library and performs the following operations on each image from which relevant information is extracted.
    For the project to be demonstrated, I have utilised my computer vision project: Automatic Face Recognition System. The AlphaUI interface is built on top of the Face Recognition System with a custom GUI giving integrity to both projects.The functional response of interface have been disabled for the demo. Any developer can define their own GUI for their system that require user interaction in the same way.

    Screenshots of the system: 

    The AlphaUI interface

    Ball tracked continuously by the system

    Touchless Interaction with the interface


    The system can be trained on any object of interest provided it is distinct in color (read HSV segmentation) . The training is done by repeatedly marking all over the object with the mouse pointer. This step has to be done only once in a lifetime or when you need to use a new marker. The values are saved in a text file to be reused in next run.

    Disclaimer:
    This project was done about an year ago but never saw daylight until now. What would you do with the possibilities of this project? Do comment and let me know.

    Step By Step One Goes Very Far

    Used:
    Ubuntu 16.04
    Code::Blocks IDE
    OpenCV 3.1.0 : C++

    Visualising N-Body Simulation in OpenCV : Multicore Processing with OpenMP

    The Good side of OpenMP is its inherent simplicity. The ease with which it enables you to write parallel code is remarkable.





    This post is an update to a previous post: Building OpenCV with OpenMP In this post, it's all about performance analysis of OpenCV with and without OpenMP.

    The code being used is the popular N-body Simulation used to simulate gravitational effect on large particle systems. I have used source code as available on Mark Harris's github repo with a few modifications.

    Modifications made are as follows:
    • A 2-D Coordinate system in place of a 3-D system for visualisation in OpenCV
    • Integer precision for co-ordinate calculation for visualisation.
    • Integer time step dt which determines the speed of our simulation . 
    • Drawing circles with radius = 0, giving us particles the size of a unit pixel.
    • Dynamic Window size declaration and adaptation
    • Re-Wrote random coordinate generation method for 2-D coordinate system.
    The modified source code is available on my github profile/visualise-nbody-opencv  

    Benchmarking: 

    Approach #1: Total Execution Time
    The Total Execution time for computing N iterations for the particle system is directly indicative of performance for N-body Sim. In general terms, if N iterations take time T on a single core , then N iterations should theoretically take time T/4 on a Quad-core CPU. Though this might not always be the case, it is a good parameter to evaluate.

    Approach #2: CPU Resource Monitor
    All OSes are bundled with a resource monitor that maps CPU utilisation with time.The resource monitor is an effective tool to visually examine the CPU per core usage.

    A combination of approach #1 and #2 is used to examine OpenCV with and without OpenMP parallelization.

    Have a look at what my code for N-body simulation for N= 2500 particles looks like:



    The following benchmark has been evaluated for 1000 iterations of 2500 particles.

    EVALUATION:
    • Without OpenMP Parallelization
    Time:
    time is a command in the Unix operating systems. It is used to determine the duration of execution of a particular command.

      time ./nbody
      real        2m7.258s
      user        1m37.096s
      sys         0m0.500s  

    CPU Core Usage:

    The calculations being done on a single core with occasional core switching 
        The CPU usage graph shows that at any given time, Only a single core is being used for the calculation. Additionally, the core being used is also switched by the OS occasionally.
    • With OpenMP Parallelization
    Time:

       time ./nbody
       real        1m23.373s
       user        3m31.596s
       sys        0m0.696s 

    CPU Core Usage:



    The CPU usage during OpenMP being used is sufficient to show that the code is run parallel on multiple cores. The CPU time shows the same as we have a reduced real time (as in wall time) by running computations on 4 cores of the CPU. For details of how to interpret the time output, refer this answer on Stack Overflow.

    OpenMP is therefore an easy to use framework in cases where code needs to be distributed on multiple cores. Since its inception, it has advanced sufficiently and have been adopted among developers looking to leverage improved hardware capabilities. 
    To Know more about OpenMp, visit their official website.
    Kudos.

    Push Yourself Again and Again.Don't give an inch until the final buzzer sounds.

    Stats:
    Ubuntu 17.04
    Intel(R) Core(TM) i5-4200U CPU @ 1.60GHz
    8 GB DDR3 RAM
    Code::Blocks 16.01
    GCC 6.3.0

    Stepping up the game : Building OpenCV with OpenMP

    OpenCV API has been a choice for Image Processing over MATLAB for quite a while now especially on an SoC like Raspberry Pi 3.

    However I always had an inquisitive concern (too fancy?) whenever I ran an OpenCV project (as in my previous project for Real-Time Face Recognition System ) that when it seemed that the CPU is doing the best it can, the CPU usage graph never went above 25%.

    Since Raspberry Pi has a Quad-Cored BCM 2837 , this meant that the program is using a single core for all the tasks. The fact that my applications are unable to exploit the resources that are available posed a problem to be solved; OpenMP to the rescue.
    OpenMP API 

    Why OpenMP :

    Because it is simple and since Raspberry Pi has no significant GPU (for High Performance Computing) which puts OpenCL out of question and no Nvidia tag anywhere puts CUDA out of the picture too. OpenCL can be implemented on a CPU too but the lead time and the overhead will be too much for now.

    OpenMP API is designed for multi-processor/core, shared memory machines and has a compiler directive based usage which though simpler to implement does require careful considerations. A thoughtless "#Parallel For" loop can significantly back fire and cause things to break.

    A number of tutorials and documentations for OpenMP API are available.Two of those:  here and here!

    Building OpenCV with OpenMP requires a simple addition at the building process:

     cmake -D CMAKE_BUILD_TYPE=RELEASE -D WITH_OPENMP=ON -D CMAKE_INSTALL_PREFIX=/usr/local ..  
    

    I also used my tried and tested method of building extra modules that has never failed me since its discovery.
    The building process starts and completes as it should with the following OpenMP tag somewhere in the entire log:

      Parallel framework:      OpenMP  

    The OpenMP and OpenCV seem like a good pair to work with on Raspberry Pi.
    Will post an update to my inquisitive concern after I get the OpenMP implementation done.
    Lot of directives to add.

    Update [27/Aug/17]: Added follow up post : Multicore Processing using OpenMP

    There are no wrong turnings. Only paths we had not known we were meant to walk.
    Peace Out.

    Stats:
    Ubuntu 16.04
    OpenCV 3.2.0
    GCC 5.4.0