Author Topic: bachelor thesis on side scan sonars  (Read 7511 times)

0 Members and 1 Guest are viewing this topic.

Offline peterv6i

  • Full Member
  • ***
  • Joined: Oct 2013
  • Location: Izola, Slovenia, EU
  • Posts: 132
  • Unit(s): 998ci
  • Software: 4.500
  • Accessories: 998ci
bachelor thesis on side scan sonars
« on: October 30, 2014, 07:57:46 AM »
Hello,
In short time I will start to write a bachelor thesis on side scan sonars.. (my second thesis)
So if someone could help me I need to find some material to work on (pdf, url link, ...how the sonar works, differnet frequencies, sonar lobes, etc. etc...).


thank you..
regards

Peter


Offline Rickard

  • Hero Member
  • *****
  • Joined: May 2009
  • Location: Mariefred, Sweden
  • Posts: 512
  • Unit(s): 999, 981, M37, LowBird-1, LowBird-2
Re: bachelor thesis on side scan sonars
« Reply #1 on: October 30, 2014, 10:40:27 AM »
Hi Peter,

This is where I found most of what I know about this technology. The zipped PP slides are fantastic!
http://www.omg.unb.ca/GGE/SE_3353.html

Good luck with the thesis!

Rickard

Offline peterv6i

  • Full Member
  • ***
  • Joined: Oct 2013
  • Location: Izola, Slovenia, EU
  • Posts: 132
  • Unit(s): 998ci
  • Software: 4.500
  • Accessories: 998ci
Re: bachelor thesis on side scan sonars
« Reply #2 on: November 01, 2014, 05:52:15 PM »
Thank you!

Offline peterv6i

  • Full Member
  • ***
  • Joined: Oct 2013
  • Location: Izola, Slovenia, EU
  • Posts: 132
  • Unit(s): 998ci
  • Software: 4.500
  • Accessories: 998ci
Re: bachelor thesis on side scan sonars
« Reply #3 on: February 03, 2015, 06:32:15 AM »
Is there or has enyone some example in java or other languages to read humminbird sonar files?
Is there some specification of humminbird file format?



Offline N9Phil

  • Full Member
  • ***
  • Joined: Jan 2011
  • Location: West Chicago, IL
  • Posts: 188
  • Unit(s): Solix 15 SI - Onix10 CI SI - 1198 CSI
  • Accessories: 80Terova W/ i-Link -- 360
Re: bachelor thesis on side scan sonars
« Reply #5 on: February 04, 2015, 08:41:19 AM »
Great information Peter.  Great research and thanks for sharing.

Phil
Solix 15 SI  Onix10 CI SI - 1198 CSIAccessories:80Terova W/ i-Link -- Transom 360

Offline peterv6i

  • Full Member
  • ***
  • Joined: Oct 2013
  • Location: Izola, Slovenia, EU
  • Posts: 132
  • Unit(s): 998ci
  • Software: 4.500
  • Accessories: 998ci
Re: bachelor thesis on side scan sonars
« Reply #6 on: February 05, 2015, 03:24:23 PM »
Ok.. I must also write some pice of code in the thesis to show how to draw sonar images..
I have asked if someone has some file specification about humminbird files (son, idx, dat)..
meanwhile I have decompiled HumViewer and used code from github to display side scan recorded file..

Here is source code in java (modified source from github sonnarwidget)..

What you need is to change path to your DAT file... and the code will generate jpg file on the c:\ drive..
You can change the height variable to modify image width.. and also you can change RGB value for different color (barva variable)

Code: [Select]
import java.io.DataInputStream;
import java.io.File;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import com.data.Ping;
import java.awt.Color;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 *
 * @author Peter
 */
public class Main {

    private static final double RAD_CONVERSION = 180 / Math.PI;
    private static final double EARTH_RADIUS = 6356752.3142;
    private static File datafile = null;
    private static File seconddatafile = null;
    private static int blocksize = 0;
    private static List<Integer> index = null;
    private static List<Integer> secondindex = null;
    private static int timestamp;
    private static int longitude;
    private static int latitude;

    //output picture height (modify this)
    static int height = 1024;

    //modify this to obtain different color (RGB value)
    static Color barva = new Color(179, 255, 153);

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        try {
            File file = new File("C:/Documents and Settings/Peter/Desktop/peter/RECORD/maona.dat");
            String name = initFromDAT(file);
            String dirname = name.substring(0, name.length() - 4);
            String path = file.getParent() != null ? file.getParent() + "/" + dirname : dirname;

            System.out.println("name: " + name);
            System.out.println("dirname: " + dirname);
            System.out.println("path: " + path);

            index = getIDXData(new File(String.format("%s/B002.idx", path)));
            datafile = new File(String.format("%s/B002.SON", path));

            secondindex = getIDXData(new File(String.format("%s/B003.idx", path)));
            seconddatafile = new File(String.format("%s/B003.SON", path));

            System.out.println("Index length: " + getLength() + " pings");

            Ping[] pingRange = getPingRange(0, (int) getLength() - 1);
            for (int i = 0; i < pingRange.length; i++) {
                System.out.println("ping range: " + i);
                System.out.println("speed: " + pingRange[i].getSpeed());
                System.out.println("lat: " + pingRange[i].getLatitude());
                System.out.println("lon: " + pingRange[i].getLongitude());
                byte[] soundings = pingRange[i].getSoundings();
               

                System.out.println("===================================");
            }

            //shranimo sliko
           
           
            BufferedImage image = new BufferedImage((int)getLength() - 1, height, BufferedImage.TYPE_INT_RGB);
            for (int loop = 0; loop < (int)getLength() - 1; loop++) {
                byte[] soundings = pingRange[loop].getSoundings();

                //gremo čez podatke iz zapisa
                for (int i = 0; i < height; i++) {
                    int mapped = (int) ((i * soundings.length) / (double) height);
                    byte sounding = soundings[mapped];
                 
                    int color = (barva.getRGB() & sounding) | (barva.getRGB() & (sounding << 8))
                            | (barva.getRGB() & (sounding << 16));


                    //set pixel color
                    image.setRGB(loop, i, color);
                }

            }
            File outputfile = new File("c:/image.jpg");
            ImageIO.write(image, "jpg", outputfile);



        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

   

    static long getLength() {
        return index.size();
    }

    public int getTimeStamp() {
        return this.timestamp;
    }

    static double getLongitude() {
        return toLongitude(longitude);
    }

    static double getLatitude() {
        return toLatitude(latitude);
    }

    static List<Integer> getIDXData(File idxfile) throws FileNotFoundException,
            IOException {
        DataInputStream stream = new DataInputStream(new FileInputStream(idxfile));
        try {
            List<Integer> index = new ArrayList<Integer>();

            while (stream.available() > 0) {
                int time = stream.readInt(); //no need
                int offset = stream.readInt();
                index.add(offset);
            }

            return index;
        } finally {
            stream.close();
        }
    }

    /**
     *
     * @param file
     * @return
     * @throws FileNotFoundException
     * @throws IOException
     */
    static String initFromDAT(File file) throws FileNotFoundException, IOException {

        System.out.println("File: " + file.toString());
        DataInputStream stream = new DataInputStream(new FileInputStream(file));
        try {
            stream.skipBytes(20);
            timestamp = stream.readInt();
            longitude = stream.readInt();
            latitude = stream.readInt();

            System.out.println("timestamp: " + timestamp);
            System.out.println("longitude: " + longitude + " " + toLongitude(longitude));
            System.out.println("latitude: " + latitude + " " + toLatitude(latitude));


            byte[] namebytes = new byte[10];
            stream.read(namebytes, 0, 10);
            String filename = new String(namebytes);
            stream.skipBytes(2); //skip null character \0000

            int ks = stream.readInt(); //don't know what this is
            int tk = stream.readInt(); //don't know what this is
            blocksize = stream.readInt();
            return filename;
        } finally {
            stream.close();
        }
    }

    /**
     * Convert Lowrance/Humminbird mercator meter format into WGS84.
     * Used this article as a reference: http://www.oziexplorer3.com/eng/eagle.html
     * @return
     */
    static double toLongitude(int mercator) {
        return mercator / EARTH_RADIUS * RAD_CONVERSION;
    }

    static double toLatitude(int mercator) {
        double temp = mercator / EARTH_RADIUS;
        temp = Math.exp(temp);
        temp = (2 * Math.atan(temp)) - (Math.PI / 2);
        return temp * RAD_CONVERSION;
    }

    static void reverseBytes(byte[] array) {
        int lastindex = array.length - 1;
        for (int loop = 0; loop < array.length / 2; loop++) {
            byte temp = array[loop];
            array[loop] = array[lastindex - loop];
            array[lastindex - loop] = temp;
        }
    }

    static Ping[] getPingRange(int offset, int length) throws IOException {

        //With side images soundings needs to be combined into one array.
        //Assumption is that both channels have same amount of samples.
        HumminbirdPing[] firstChannel = getPingRangeFromFile(offset, length, datafile, index);
        HumminbirdPing[] secondChannel = getPingRangeFromFile(offset, length, seconddatafile, secondindex);

        for (int loop = 0; loop < firstChannel.length; loop++) {
            HumminbirdPing first = firstChannel[loop];
            HumminbirdPing second = secondChannel[loop];

            //združi oba kanala v en array in vrne rezultat
            byte[] firstsoundings = first.getSoundings();
            byte[] secondsoundings = second.getSoundings();
            reverseBytes(firstsoundings);

            byte[] soundings = new byte[firstsoundings.length + secondsoundings.length];
            System.arraycopy(firstsoundings, 0, soundings, 0, firstsoundings.length);
            System.arraycopy(secondsoundings, 0, soundings, firstsoundings.length, secondsoundings.length);
            first.setSoundings(soundings);
        }


        return firstChannel;

    }

    static HumminbirdPing[] getPingRangeFromFile(int offset, int length, File file, List<Integer> index) throws IOException {
        RandomAccessFile raf = new RandomAccessFile(file, "r");

        try {
            HumminbirdPing[] pings = new HumminbirdPing[length];
            for (int loop = 0; loop < length; loop++) {
                raf.seek(index.get(offset + loop));
                HumminbirdPing ping = new HumminbirdPing(raf, blocksize);
                pings[loop] = ping;
            }
            return pings;
        } finally {
            raf.close();
        }
    }

    static class HumminbirdPing implements Ping {

        private int time;
        private int longitude;
        private int latitude;
        private short speed;
        private short heading;
        private byte[] soundings;

        public HumminbirdPing(RandomAccessFile stream, int blocksize) throws IOException {
         
           /*
            System.out.println("block size: " + blocksize);
            byte[] vrstica = stream.readLine().getBytes();
            for (int x=0; x < vrstica.length; x++)
            {
                System.out.print(vrstica[x]+"|");
            }
            System.out.println("-----------");
           */

            stream.skipBytes(10);
            time = stream.readInt();
            stream.skipBytes(1);
            longitude = stream.readInt();
            stream.skipBytes(1);
            latitude = stream.readInt();
            stream.skipBytes(3);
            heading = stream.readShort();
            stream.skipBytes(3);
            speed = stream.readShort();
            stream.skipBytes(5);
            int freq = stream.readInt();
            stream.skipBytes(10);
            int son = stream.readInt();
            stream.skipBytes(1);

            //vrnemo zapis, ki ga izrisujemo
            System.out.println(blocksize-58);
            soundings = new byte[blocksize - 58];
            stream.read(soundings, 0, blocksize - 58);
        }

        public byte[] getSoundings() {
            return soundings;
        }

        public void setSoundings(byte[] soundings) {
            this.soundings = soundings;
        }

        public float getLowLimit() {
            // Humminbird file does not provide this
            return 0;
        }

        public float getTemp() {
            // Humminbird file does not provide this
            return 0;
        }

        public float getDepth() {
            // Humminbird file does not provide this
            return 0;
        }

        public int getTimeStamp() {
            return this.time;
        }

        public float getSpeed() {
            return this.speed * 3.6f;
        }

        public float getTrack() {
            return this.heading / 10.0f;
        }

        public double getLongitude() {
            return toLongitude(longitude);
        }

        public double getLatitude() {
            return toLatitude(latitude);
        }
    }
}
Code: [Select]
package com.data;

/**
 *
 * @author Peter
 */
public interface Ping {
byte[] getSoundings();
float getLowLimit();
float getTemp();
float getDepth();
int getTimeStamp();
float getSpeed();
float getTrack();
double getLongitude();
double getLatitude();
}

Offline peterv6i

  • Full Member
  • ***
  • Joined: Oct 2013
  • Location: Izola, Slovenia, EU
  • Posts: 132
  • Unit(s): 998ci
  • Software: 4.500
  • Accessories: 998ci
Re: bachelor thesis on side scan sonars
« Reply #7 on: February 05, 2015, 03:30:43 PM »

Offline peterv6i

  • Full Member
  • ***
  • Joined: Oct 2013
  • Location: Izola, Slovenia, EU
  • Posts: 132
  • Unit(s): 998ci
  • Software: 4.500
  • Accessories: 998ci


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo

 

Related Topics

  Subject / Started by Replies Last post
1 Replies
11498 Views
Last post April 07, 2009, 12:48:02 PM
by RGecy
10 Replies
13458 Views
Last post August 08, 2011, 02:09:33 PM
by lolar3288
7 Replies
6196 Views
Last post November 21, 2011, 04:37:29 PM
by sonar2000
7 Replies
6317 Views
Last post December 03, 2012, 09:53:19 AM
by Rickard
17 Replies
10358 Views
Last post August 06, 2013, 03:58:32 PM
by Rüdiger
3 Replies
4308 Views
Last post December 09, 2013, 02:58:50 PM
by peterv6i
20 Replies
14065 Views
Last post December 21, 2013, 11:03:29 PM
by newkid4si
8 Replies
12525 Views
Last post May 26, 2014, 03:27:49 AM
by Rüdiger


SimplePortal 2.3.3 © 2008-2010, SimplePortal