Showing posts with label Data. Show all posts
Showing posts with label Data. Show all posts

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.

    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

    Line Follower using Neural Nets : Part 2 (Designing the Neural Net )

    This post is the second in the series of developing a neural net line follower. For the post covering dataset generation, go here

    Once data is handy, the next objective in a Neural Net is to plan out its structure.
    Neural nets are mostly used for uncertain and non-linear operations as is our task of pattern matching a.k.a Classification.

    A neural net has mainly the following layers which map the input to the output
    • Input Layer
    • Hidden Layer(s)
    • Output Layer
    The Number of Hidden Layer is a deterministic on the complexity of the task being performed.For example, A deep learning net might contain more hidden layers for a deeper defragmentation of data.However there is a trade off between Depth and Speed of execution, therefore for our case, a single hidden layer would be enough.

    The Designed Network looks as depicted here:

    8 : 1 mapping through a hidden layer of two nodes (and one bias unit)

    Intuition says this will be sufficient for our task as a partition in half can easily tell which side of our sensor strip sees the line.

    For details of what a neural network is, I would recommend going through the following site: Neural Networks and Deep Learning

    For activation function in our network, I have used tangent sigmoid function:
    Tangent Sigmoid Function
    For faster development time, the neural net designer tool in MATLAB is used.For the sake of understanding, an algorithmic view is as shown:

    x = 1 X 8;                                             {Input from 8 nodes}
    W12   =   2 X 8;                                     {Weight Matrix from Input layer to Hidden Layer}
    Z1= x*(W12)= (1X8 * 8X2)= 1X2;   {Mapping from Input layer to Hidden layer}
    A1= TanSig(Z1)= 1X2;                         {Activation of Hidden Layer}
    W23 = 1 X 2;                                        {Weight Matrix from Hidden layer to Output Layer}
    Z2 =A1*(W23)= (1X2 * 2X1)=1X1; {Mapping from Hidden layer to Output Layer}
    A2=TanSig(Z2);                                    {Activation of Output Node}
    Y=A2;                                                                    {Output}

    The specifications are set up in the NNFit tool in MATLAB and data obtained from the previous post is used to train the network using Backpropagation Algorithm. After the training completes, the entire process is stored as a script using the prompt window.

    By default the script generated contains a lot of redundant information which can be optimised on examination.
    The entire script is reduced to the following:

     function [y1] = NNLF(x1)   
     %NNLF neural network simulation function.  
     %  
     % Generated by Neural Network Toolbox function genFunction, 13-Aug-2016 14:40:30.  
     %  
     % [y1] = NNLF(x1) takes these arguments:  
     %  x = Qx8 matrix, input #1  
     % and returns:  
     %  y = Qx1 matrix, output #1  
     % where Q is the number of samples.  
     %#ok<*RPMT0>  
     %(c)Sanjeev Tripathi ( AlphaDataOne.blogspot.in )   
     % ===== NEURAL NETWORK CONSTANTS =====  
     % Layer 1  
     b1 = [-8.8516132798193108e-10;2.1615423176361062];  
     IW1_1 = [-30.312171052276302 -15.230142543653209 -7.5989117276441904 -3.8426480381828529 3.8426480396510354 7.5989117277872076 15.230142543113857 30.312171051352024;1.1787493338995503 1.1684723902794487 -0.30187584946551604 -1.2505266965306716 -0.85655951742083458 -0.61361689937359887 -0.51938433720151178 0.43601182390986715];  
     % Layer 2  
     b2 = -3.5519126834821509e-10;  
     LW2_1 = [1.0000000099939996 2.6043564908190074e-09];  
     % ===== SIMULATION ========  
     Q = size(x1,1); % samples  
     x1 = x1';  
     xp1=2*x1 -1;  
     xp1=cast(xp1,'double');  
     a1 = tansig_apply(b1 + IW1_1*xp1);  
     a2 = repmat(b2,1,Q) + LW2_1*a1;  
     y1=a2;      
     end  
     % Sigmoid Symmetric Transfer Function  
     function a = tansig_apply(n,~)  
     a = 2 ./ (1 + exp(-2*n)) - 1;  
     end  
    

    The Neural Net being run uses the pre optimized weights to map the input to the output with an accuracy of 100% (High Variance) as the dataset contained all the possibilities. A demo of our net for different inputs entered manually is as shown:


    As stated earlier,
            -1 informs to move left 
            +1 informs to move right 
            ~0 informs to keep moving forward

    The network of nodes can compute with accuracy any width,orientation or order of line with absolute accuracy. It can also detect multiple lines simultaneously as the network has been trained for all the possible inputs that it can encounter.

    An Implementation on AVR Atmega32 microcontroller to be covered soon.
    Stay Tuned for more.

    Peace Out

    Used:
    Matlab 2016a

    Line Follower using Neural Nets : Part 1 (Generating Data Set)

    Neural Networks are convenient when mapping a function which behaves non-linearly. However, for Training and Testing purpose , Data is the most important piece of the puzzle.

    The Neural Network Line Follower to be designed uses 8 Line sensing elements where each will return
     1 : Line Detected
     0 : Line Not Detected

    So the possible dataset is the combination of 8 binary units arranged in different pattern leading to a total of
                28 =  256 Samples of data.

    I wrote the following MATLAB script to create the data for training the Neural Network.

     function [bin,out]=DataGen(m)  
    
     % Function to Generate Training Data set for training neural network of a  
     % line follower  
     %    
     %     [bin,out]=DataGen(number of inputs)  
     %       
     % It is a good practice to have an even number of input units for the  
     % NN Network to be trained  
     n=(2^m)-1;              
     bin=decimalToBinaryVector(0:n);   
     [p,q]=size(bin);             
     out=zeros(p,1);   
     bLeft=bin(:,1:(q/2));  
     bRight=bin(:,((q/2)+1):end);  
     wL=bi2de(bLeft,'left-msb');  
     wR=bi2de(bRight,'right-msb');  
      for i=1:p  
        if wL(i)>wR(i)  
          out(i)=-1;  
        end   
        if wL(i)<wR(i)  
          out(i)=1;  
        end  
        if wL(i)==wR(i)  
          out(i)=0;  
        end    
      end  
     end  
    

    Here:
             bin holds the binary input sequence of 8 bits    
             out holds the output corresponding to the input bin

    Such that:
              if bin=[1 0 0 0 0 0 0 0]  then out = -1      (Line Sensed on far left : Move Left)
              if bin=[0 0 0 0 0 0 1 0]  then out =  1      (Line sensed on right : Move Right)
              if bin=[0 0 1 0 0 1 0 0]  then out =  0      (Line sensed symetrically : Keep Moving Forward)

    For a Neural Network,  0 is pretty much a perfection so it allocates a really small value (~0) such that it can be considered as zero.

    From the script above with 8 as a parameter via the following syntax:
               [bin,out]=DataGen(8);
    we get:
               bin = 256 X 8 Input Data Matrix
               out = 256 X 1 Output Data Matrix

    In the screenshot of the varibles, Left Segment shows the input from the sensors while we have the expected output in the blue bounded box on right:


    These Data elements are ready to be used as Training Parameters for our Neural Network.
    Further Development to be covered by subsequent posts.

    Update 7/Sep/16 : Read Part II: Designing Neural Network

    Peace Out.

    Used:
    Matlab 2016a

    RoboAuto : Arduino Bluetooth Joystick for Android™


    HC-05 has an added advantage in embedded systems that pretty much every smartphone is equipped with in built Bluetooth hardware.This opens up a large number of possibilities for access and control of embedded systems.

    There are apps that do the task of controlling a system via bluetooth however none sufficed to my requirement. So I developed one,

    Presenting  
    RoboAuto

    An Android Application for communication with HC-05 Bluetooth Module.
    RoboAuto is a clean and effective app using which you can control your Robots or Devices with a Simple Joystick!
      
    What RoboAuto does:

    Program Flow

    So, You as an embedded developer have to configure your robot only for the commands received from the app!

    Here are few screenshots:






    RoboAuto connects to the Bluetooth Module using a Wireless Serial Link. Android already provides support for this in their native API.

    After a successful connection, characters are sent to the module on actuation of joystick ,buttons or check boxes which can be read and executed by Arduino or other microcontrollers.

    Special Thanks to zerokol for his JoystickView Library.
    The Joystick sends the following :

    Forward: F
    Backward: B
    Left : L
    Right : R

    Additionally I have assigned intermediate directions , for example, FL for Front-Left, BR for Backward-Right and so on.
    No Changes are to be required on the Embedded side as the UART only parses a single character at a time, giving us simultaneous (in theory) Forward and Left motion. Kind of like what happens in a PWM.

    Download RoboAuto here:
    Get it on Google Play
    Google Play and the Google Play logo are trademarks of Google LLC.

    This Post therefore will be updated soon and is worth a bookmark.
    UPDATE (22/October/17): Savvy has been renamed to RoboAuto and published on Google Playstore
    UPDATE (10/August/16) : Few Screenshots and content have been updated!
    UPDATE (25/August/16 ):  Savvy(Now RoboAuto) is available for testing and debugging for FREE
    UPDATE (12/September/16): Added Internet Access permission for Google Form Integration.
    UPDATE (19/March/17): Fixed a lot of bugs in the layout scale. Renamed "Turn Light" to "Rear Light."

    Do report any bugs you encounter.
    Credits (19/March/17):  Thank You Shivani for your Feedback on Design Issues

    Good Stuff Take Time.

    Used:
    Android Studio 2.3.3
    Lenovo S6600 , Micromax Knight Cameo for Debugging.

    A Simple Edge Detection Algorithm

    In tasks of image processing, finding edges in an image occasionally serves as the basis for the evaluations.

    However, imaging functions usually take up a lot of memory and computation power due to the complexity of  the equations which limit their usage on low memory devices like microcontrollers and single chip boards.

    In such case a Linear equation can serve our purpose with a low computation complexity, efficient memory utilisation and faster execution time.

    Loading image to find edges :

    Self advertisement at its best ;)
    Reading and displaying image to process


    Edge finding algorithm with intuitive coefficient representation:

    Edge Finder 

    Edges obtained by the difference equation:

    Processed image overlayed on original image

    Here is the Edgefinder function, Lines 8-10 are what we are supposed to be looking at :


    1:  function out=Edgefinder(I)  
    2:    I1=rgb2gray(I);      % conversion to grayscale  
    3:    I2=imbinarize(I1);   % conversion to binary image,using Otsu's method  
    4:    [m,n]=size(I2);      % size of the image  
    5:    out=zeros(size(I2)); % preallocating memory  
    6:    for i=2:m-1  
    7:      for j=2:n-1  
    8:         out(i,j)=  (0.25*I2(i+1,j+1))-   I2(i+1,j) + (0.25*I2(i+1,j-1)) ...  
    9:                        - I2(i,j+1)   + 3*I2(i,j)   -       I2(i,j-1) ...  
    10:                  +(0.25*I2(i-1,j+1))-   I2(i-1,j) + (0.25*I2(i-1,j-1));  
    11:      end  
    12:    end  
    13:  out=imoverlay(I,out,'red');  %  'I' was preserved for image overlay,not really necessary  
    14:  imshow(out);  
    15:  end 

    Take a look at the coefficients of the difference equation:
    
    

    Observe the oscillatory nature of the coefficients: A characteristics of a high pass filter.
    Also you may observe that the sum of all coefficients is equal to Zero,
    quite intuitive.

    It is also evident that this algorithm can find edges at all inclinations so simplicity and efficiency are the key factors here.

    Peace out.

    Used:
    MATLAB 2016a

    Quick Start Button for Jupyter Notebook

    Running Jupyter from the CMD all the time on a windows machine is quite tedious and time consuming.

    You gotta navigate to your prefered directory ,then call up CMD (or vice versa) and then execute the command "Jupyter Notebook"

    Sure we can write a python program to do that for us, I prefer to use Windows Command Shell for such stuff. Its easy, quick and gets the job done everytime!

    Take a look at the script below, only the last two lines are crucial.

     @echo off  
     title Jupyter_Jumpstart  
     color 70  
     cd C:\Users\Sanjeev\Documents\Jupyter Notebook\  
     jupyter notebook  
    

    Copy Paste the above code and save the notepad file as "anything.bat" (exclude the commas).
    You are free to choose anything for the Title, Color and Location of your notebook.

    I kept the script on desktop among others softwares. Double click and you are good to go!

    Most prominent benefit of this method that I found is that all your .ipynb files are stored at a location of your choice thus no chance of misplacing your notebooks

    Peace.

    Linear Regression using Gradient Descent

    Gradient is the generalization of the usual concept of derivative to a function of several variables. Err... Simply put, the variation of a parameter in  an environment  such that measuring any two points inform us about the direction of increasing density.

    Descent is well.. descent ..on the gradient. That is to reach the highest (or lowest?) density in gradual steps.
    The task of Gradient Descent algorithm is to find t0 and t1 such that y = t0 +  (t1 * x)
    For more, go here Gradient Descent

    Input Process
    Gradient Descent 
    Observe that :
               if x is input ,
                  then
                      output   y= 3x
    This is learnt by the algorithm through the input training data.  
    And the fitting parameter  t1 also gradually converges to ~3

    Regression on new input 

    The machine learns that the output needs to be 3 times that of input just by learning from data.
    Well documented Code is on GitHub

    Due to limited buffer space, all iterations with their respective parameters are logged into a data file.Here is the data file for the above set:

    Everything done in Visual Studio 2010