Tuesday, November 29, 2016

Yol Tarifi, Harita Bilgisi: osrm-backend

Verili herhangi bir enlem / boylam kordinatına en yakın sokak, yol isimlerini, yerlerini bulabilen, hatta bir noktadan diğerine nasıl gidileceğini veren bir veri tabanı ve program ÖSRM. Aslında bu arkadaşlar OpenStreetMap adli projenin veri tabanını daha iyi erişilebilir hale getirmişler.

https://github.com/Project-OSRM

Proje C++ bazlı, hızlı işliyor. İçinde OSM projesinin dosyalarını alıp onları daha ufaltan, ve bir servis ve APİ üzerinden dış erişime hazır hale getiren kodlar var. Bu servisin nasıl işlediğini göstermek için kendileri bir bedava servis işletiyorlar,

http://router.project-osrm.org

Mesela alttaki kordinata en yakin cadde hangisidir

http://router.project-osrm.org/nearest/v1/foot/29.036428,40.987659

ile bulunabiliyor, çıktı JSON formatında. İki nokta arasında nasıl gidilir, hangi caddeler kullanılır,

http://router.project-osrm.org/route/v1/foot/29.036428,40.987659;29.039228,40.992186

URL icinde v1 ardindan gidis sekli verilmeli, araba icin car, bisiklet icin bicycle; ustteki yuruyerek.

İstenen her  türden veri üstteki bedava servisten alınabilir, ama başkasının servisini fazla yormamak (!) için (ve yerel bazlı erişim daha hızlı olur tabii) kendi servisimizi oluşturabiliriz.

Kod Github'dan indirilir, ve apt-get install alttakiler uzerinde isletilir,

cmake libtbb-dev lua5.2 libboost-all-dev liblua52 libluabind-dev liblua5.2-dev libluabind-dev libstxxl-dev libxml2 libxml2-dev libosmpbf-dev libbz2-dev libprotobuf-dev

Simdi proje dizinine girilip

mkdir -p build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
cmake --build .
sudo cmake --build . --target install

isletilir. Ayrica ayni dizinde hangi ulasim sekli var ise, onun lua dosyasina Unix sembolik baglanti kurulmali, mesela araba yontemi icin

ln -s profiles/car.lua .

Kurulum bitti, simdi veri lazim, mesela Turkiye icin

http://download.geofabrik.de/europe/turkey.html turkey-latest.osm.bz2

Tum veri icin http://download.geofabrik.de

Bu dosya acilir, simdi dosya uzerinde

osrm-extract turkey-latest.osm

ve

osrm-contract turkey-latest.osrm

Dikkat bu komutlari lua linki neredeyse oradan isletmek lazim. O zaman osrm dosya referansina dizin ismi eklemek gerekebilir.

Bu son komut uzun surecek, 30-40 dakika gibi.. Bittikten sonra artik veri hazir, veri dizininde

osrm-routed map.osrm

isletilir. Bu komut 5000 port'unu dinleyen bir servis baslatir. Artik ustteki turunden tum komutlarda http://router.project-osrm.org yerine http://localhost:5000 kullanilabilir.

Baglantilar

https://www.digitalocean.com/community/tutorials/how-to-set-up-an-osrm-server-on-ubuntu-14-04

https://github.com/Project-OSRM/osrm-backend/wiki/Running-OSRM

https://github.com/Project-OSRM/osrm-backend/blob/master/docs/http.md

Harita Uygulamasi, GPS, Android

Cep telefonunda nerede oldugumuzu harita uzerinde bulmak icin bir uygulama.

https://github.com/burakbayramli/kod/tree/master/mycamera4

Ayrica kamera goruntuleri, yon algilayicisi, GPS verilerini kaydetme ozelligi var. Ben bu uygulamayi baska bir proje icin veri kaydi, test etme ve sonradan analiz amacli yazdim, baslangic noktasi olarak baskalari icin faydali olabilir.

Harita gosteren kodun zoom ozelligi var, haritada ayrica saga, sola, yukari, asagi kaydirma hareketi ile dogu, bati, vs. yonundeki diger haritalari da gormek mumkun.

Uygulama tum bir sehrin haritasini tek bir zip dosyasinda tutuyor, baska hicbir veriye, ya da Google Maps baglantisina ihtiyac yok. Haritalama uygulamasi boyle calismali; Internet baglantisi olmayinca harita calismazsa bu iyi olmaz, turist, gezgin yolda kalir. "Merkezle" fazla baglanti iyi bir sey degil, saglam bilgi islem sistemleri de bu mantikla kurulur.

Derlemek icin ant yeterli, ant debug, ant installd, ya da ant release ile apk yaratilir.

Tuesday, November 22, 2016

Bilgisayari Konusturmak, Metinden Konusma (Text-to-Speech)

Python

pip install gtts, pyttsx

from gtts import gTTS
import os
tts = gTTS(text='Good morning', lang='en')
tts.save("good.mp3")

ya da 

import pyttsx
engine = pyttsx.init()
engine.say('Good morning.')
engine.runAndWait()

Android uygulamasi icinde cep telefonunu konusturmak icin arayuz var. Herhangi bir Activity icinde

import android.speech.tts.TextToSpeech;

public class MyActivity extends Activity
{
    ...

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        ...
        t1=new TextToSpeech(getApplicationContext(), new TextToSpeech.OnInitListener() {
                @Override
                public void onInit(int status) {
                    if(status != TextToSpeech.ERROR) {
                        t1.setLanguage(Locale.UK);
                    }
                }
            });
     }
}

Ustteki onInit konusturma yapmadan once islemis olmali. Simdi herhangi bir metni okutmak icin

String toSpeak = "How much wood could a woodchuck chuck";
t1.speak(toSpeak, TextToSpeech.QUEUE_FLUSH, null);    

Thursday, November 10, 2016

Google Maps'den Harita Imaji

Diyelim ki mobil uygulama gelistiriyoruz, ve nerede oldugumuza bagli olarak bir harita gostermemiz gerekiyor.. Haritalama Google Maps arayuz baglantisi uzerinden ihtiyac oldugu anda alinabilir, fakat telefonun baglantisiz olabilecegi durumlara hazir olmak lazim. Google Maps'in statik harita imaji uretmek icin API'si var,

from io import BytesIO
import Image, urllib

url = "http://maps.googleapis.com/maps/api/staticmap?center=41.0870,29.0373&size=800x800&zoom=14"
buffer = BytesIO(urllib.urlopen(url).read())
image = Image.open(buffer)
image.save("map.png")

41.0870,29.0373 parametreleri enlem ve boylam, center ile bu kordinatlari harita merkezine al diyoruz, ve staticmap URL'ine giderek bir imaj uretmek istedigimizi soyluyoruz. Uretilen harita imaj dosyasi yerel diskte kaydedilebilir.

Sonuc


O zaman belli bir zoom seviyesini kullanarak tum bir sehir icin harita parcalari uretip telefonda tutabiliriz. Mesela Istanbul icin sol ust kose 41.123039, 28.930376 sag alt ust kose 40.959904, 29.129503'de olan bir dikdortgeni parcalara boleriz, her parca icin ustteki cagriyi yapariz. Cok fazla imaj gerektirmez herhalde, zaten imajlar format degisimi vs. sonrasinda da iyice kuculebilir (80 kb civari mesela). 10 MB icinde tum bir sehri tutmak zor olmasa gerek.

Zoom seviye 17 icin 88 pixel 50 metreye, seviye 15 icin 200 metreye tekabul ediyor.

Tuesday, November 8, 2016

Android, Kamera, Yon, GPS Verisini Kaydetmek

Test amacli olarak cep telefonunda kamera goruntusu (video olarak), hangi yone donuk oldugumuz, ve varsa GPS verisini telefon uzerinde bazi dosyalara kaydedebiliriz (DCIM dizini). Bir kaydedici program isleyince goruntu, GPS, vs. kaydedilir, program bitisinde dizine yazilir.. Veri

ANDROID/platform-tools/adb -d pull /sdcard/DCIM/cam.txt /tmp
ANDROID/platform-tools/adb -d pull /sdcard/DCIM/orientations.txt /tmp
ANDROID/platform-tools/adb -d pull /sdcard/DCIM/gps.txt /tmp
ANDROID/platform-tools/adb -d pull /sdcard/DCIM/sizes.txt /tmp

ile dizustu ortamina indirilebilir. Kamera goruntusunu gormek icin Python ile


from PIL import Image
import pandas as pd
import io

data = np.fromfile("/home/burak/Downloads/cam.txt", dtype=np.uint8)
df = pd.read_csv("/home/burak/Downloads/sizes.txt",header=None)
df['cum'] = df.cumsum()
df['cum2'] = df.cum.shift(-1)
df.columns = ['x','fr','to']
frame = 3
arr = data[int(df.ix[frame]['fr']) : int(df.ix[frame]['to'])]
im = Image.open(io.BytesIO(arr))

im.save('out.png')

Ardi ardina tum resimler tek bir byte dizisi icinde koyuldu, dizinden ayri ayri resimleri cekip cikartmak lazim. Bir problem su, JPG formatinda her resim farkli boyutlarda olabilir, o yuzden hangi byte'tan hangi byte'a kadar cekip cikarma yapacagimizi bilmemiz lazim, yani resim buyukluklerini bilmemiz lazim, bu buyuklukleri ayri bir dosyadan aliyoruz.

Kayit yapilirken kayit hangi aralikta yapilir? Bizim kullandigimiz zaman birimi kamera tek goruntusudur. Android'de onizleme (preview) mod'unda iken onPreviewFrame adli cagriya her kamera goruntusu teker teker gecilir. Bu gecilme sirasinda (ve bizim tanimladigimiz bir sabite gore bazi goruntuler atlanarak) o anda elde bulunan diger tum algilayici verilerini de kamera goruntusu ile birlikte yaziyoruz. Yani kayit sonunda elde bir ufak video'nun 40 tek imaji (frame) var ise, o zaman yon ve GPS icin de 40 tane veri noktasi olacak. 

GPS verisi her zaman mevcut olmayabilir, olmadigi zaman onun yerine null yazilir. GPS bilindigi gibi her zaman uydu baglantisi ve hesaplarini kitleyemiyor. Odada, kapali bir yerde olundugu zaman GPS islemez. 

Alttaki kod daha once paylastigimiz altyapi icine atilabilir, derleme orada halledilir.

package my.project.MyCamera;

import java.io.FileOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.OutputStreamWriter;
import java.io.IOException;
import java.io.File;
import android.view.SurfaceHolder;
import android.os.Environment;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.YuvImage;
import android.graphics.Rect;
import android.graphics.ImageFormat;
import android.graphics.BitmapFactory;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.ShutterCallback;
import android.util.Log;
import java.util.ArrayList;

public class CameraPreview implements SurfaceHolder.Callback,
                                      Camera.PreviewCallback
{
    private Camera mCamera = null;
    private int PreviewSizeWidth;
    private int PreviewSizeHeight;
    private String NowPictureFileName;
    private Boolean TakePicture = false;
    private ArrayList<byte[]> images = null;
    private ArrayList<String> orientations = null;
    private ArrayList<String> gps = null;
    public MyCamera mCameraActivity = null;

    public CameraPreview(int PreviewlayoutWidth, int PreviewlayoutHeight)
    {
        PreviewSizeWidth = PreviewlayoutWidth;
        PreviewSizeHeight = PreviewlayoutHeight;
    }

    private int frameCounter = 0;

    @Override
    public void onPreviewFrame(byte[] arg0, Camera arg1)
    {
        frameCounter++;
        if (frameCounter < 10) return;
        frameCounter = 0;
        images.add(arg0);
        orientations.add(Float.toString(mCameraActivity.mOrientationAngles[0]) + " " +
                         Float.toString(mCameraActivity.mOrientationAngles[1]) + " " +
                         Float.toString(mCameraActivity.mOrientationAngles[2]));
        if (gps != null) gps.add(mCameraActivity.gpsInfo);

    }

    @Override
    public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3)
    {
        Parameters parameters;

        parameters = mCamera.getParameters();
        // Set the camera preview size
        parameters.setPreviewSize(PreviewSizeWidth, PreviewSizeHeight);
        // Set the take picture size, you can set the large size of the camera supported.
        parameters.setPictureSize(PreviewSizeWidth, PreviewSizeHeight);
        parameters.setPreviewFormat(ImageFormat.NV21);

        mCamera.setParameters(parameters);

        images = new ArrayList();
        orientations = new ArrayList<String>();
        gps = new ArrayList<String>();

        mCamera.startPreview();
    }

    @Override
    public void surfaceCreated(SurfaceHolder arg0)
    {
        mCamera = Camera.open();
        try {
            // If did not set the SurfaceHolder, the preview area will be black.
            mCamera.setPreviewDisplay(arg0);
            mCamera.setPreviewCallback(this);
        }
        catch (IOException e){
            mCamera.release();
            mCamera = null;
        }
    }


    @Override
    public void surfaceDestroyed(SurfaceHolder arg0)
    {
        Log.d("cam","images size "+ Integer.toString(images.size()));

        mCamera.setPreviewCallback(null);
        mCamera.stopPreview();
        mCamera.release();
        mCamera = null;

        final File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM );

        File fileo = new File(path, "orientations.txt");
        try
            {
                fileo.createNewFile();
                FileOutputStream fOut = new FileOutputStream(fileo);
                OutputStreamWriter myOutWriter = new OutputStreamWriter(fOut);
                for (String xx : orientations) {
                    myOutWriter.append(xx);
                    myOutWriter.append("\n");
                }
                myOutWriter.close();
                fOut.flush();
                fOut.close();
            }
        catch (IOException e)
            {
                Log.e("Exception", "File write failed: " + e.toString());
            }

        File fileg = new File(path, "gps.txt");
        try
            {
                fileg.createNewFile();
                FileOutputStream fOut = new FileOutputStream(fileg);
                OutputStreamWriter myOutWriter = new OutputStreamWriter(fOut);
                for (String xx : gps) {
                    myOutWriter.append(xx);
                    myOutWriter.append("\n");
                }
                myOutWriter.close();
                fOut.flush();
                fOut.close();
            }
        catch (IOException e)
            {
                Log.e("Exception", "File write failed: " + e.toString());
            }

        File filec = new File(path, "cam.txt");
        File files = new File(path, "sizes.txt");
        try
            {
                filec.createNewFile();
                files.createNewFile();
                FileOutputStream fOut = new FileOutputStream(filec);
                FileOutputStream fOut2 = new FileOutputStream(files);
                OutputStreamWriter myOut2Writer = new OutputStreamWriter(fOut2);
                for (byte[] xx : images) {
                    ByteArrayOutputStream out = new ByteArrayOutputStream();
                    YuvImage yuv = new YuvImage(xx, ImageFormat.NV21, PreviewSizeWidth, PreviewSizeHeight, null);
                    yuv.compressToJpeg(new Rect(0, 0, PreviewSizeWidth, PreviewSizeHeight), 50, out);
                    byte[] bytes = out.toByteArray();
                    fOut.write(bytes);
                    myOut2Writer.append("" + bytes.length);
                    myOut2Writer.append("\n");
                    Log.d("cam","single jpg size "+ bytes.length);
                }
                myOut2Writer.close();
                fOut.flush();
                fOut.close();
                fOut2.flush();
                fOut2.close();
            }
        catch (IOException e)
            {
                Log.e("Exception", "File write failed: " + e.toString());
            }
    }
}

package my.project.MyCamera;

import java.io.File;

import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.hardware.SensorEventListener;
import android.hardware.SensorEvent;
import android.location.GpsStatus;
import android.location.LocationManager;
import android.location.LocationListener;
import android.location.GpsSatellite;
import android.location.Location;
import android.util.Log;
import android.os.HandlerThread;

public class MyCamera extends Activity implements SensorEventListener
{
    private CameraPreview camPreview;
    private FrameLayout mainLayout;
    private int PreviewSizeWidth = 320;
    private int PreviewSizeHeight= 240;
    private Handler mHandler = new Handler(Looper.getMainLooper());

    private SensorManager mSensorManager;
    public float[] mAccelerometerReading = new float[3];
    public float[] mMagnetometerReading = new float[3];
    public float[] mRotationMatrix = new float[9];
    public float[] mOrientationAngles = new float[3];

    public String gpsInfo = null;
    LocationManager locationManager = null;

    private PrisLocationListener mLocationListener;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        mSensorManager.registerListener(this,mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),SensorManager.SENSOR_DELAY_GAME);
        mSensorManager.registerListener(this,mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD),SensorManager.SENSOR_DELAY_GAME);
        mSensorManager.registerListener(this,mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION),SensorManager.SENSOR_DELAY_GAME);

        PrisLocationListener locationListener = new PrisLocationListener();
        locationListener.parent = this;
        HandlerThread t = new HandlerThread("LocationHandlerThread");
        t.start();
        locationManager = (LocationManager)getSystemService(LOCATION_SERVICE);
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener, t.getLooper());

        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                             WindowManager.LayoutParams.FLAG_FULLSCREEN);

        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.main);

        SurfaceView camView = new SurfaceView(this);
        SurfaceHolder camHolder = camView.getHolder();
        camPreview = new CameraPreview(PreviewSizeWidth, PreviewSizeHeight);
        camPreview.mCameraActivity = this;

        camHolder.addCallback(camPreview);
        camHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

        mainLayout = (FrameLayout) findViewById(R.id.frameLayout1);
        mainLayout.addView(camView, new LayoutParams(PreviewSizeWidth, PreviewSizeHeight));
    }

    @Override
    public boolean onTouchEvent(MotionEvent event)
    {
        return true;
    };

    @Override
    public void onSensorChanged(SensorEvent event) {
        if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
            System.arraycopy(event.values, 0, mAccelerometerReading,
                             0, mAccelerometerReading.length);
        }
        else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
            System.arraycopy(event.values, 0, mMagnetometerReading,
                             0, mMagnetometerReading.length);
        }
        else if (event.sensor.getType() == Sensor.TYPE_ORIENTATION) {
            System.arraycopy(event.values, 0, mOrientationAngles,
                             0, mOrientationAngles.length);
        }
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
    }

    public static class PrisLocationListener implements LocationListener{

        private static final String TAG = PrisLocationListener.class.getSimpleName();
        public MyCamera parent = null;

        @Override
        public void onLocationChanged(Location arg0) {
            String s = "" +
                arg0.getLatitude() + "," +
                arg0.getLongitude() + "," +
                arg0.getSpeed() + "," +
                arg0.getAccuracy() + "," +
                arg0.getAltitude() ;
            parent.gpsInfo = s;
        }

        @Override
        public void onProviderDisabled(String provider) {
        }

        @Override
        public void onProviderEnabled(String provider) {
        }

        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {
        }
    }
}




Monday, November 7, 2016

Android, Gelistirme, Kurmak, Komut Satiri

Uzun zamandir Android gelistirmesi yapmamistik, bir goruntu isleme uygulamasi icin gerekti.

Ubuntu uzerinde alttakiler kurulur,

sudo apt-get install -y build-essential  zlib1g-dev  libncurses5:i386 libstdc++6:i386 zlib1g:i386 default-jre default-jdk ant

Android SDK ve NDK (belki gerekebilir)

https://dl.google.com/android/android-sdk_r24.4.1-linux.tgz

https://dl.google.com/android/repository/android-ndk-r13b-linux-x86_64.zip

Kurduktan sonra ANDROID_SDK/tools/android ile bir GUI baslatilir, buradan telefonumuz icin gerekli derleme hedefi ve diger bazi ekler kurulur. Mesela Android 4.2.2 var ise o kurulur, derleme hedefi 17 aktif hale gelir. Bu hedef altta uretilecek build.xml icin gerekli.

Simdi telefona USB'den baglaninca bazi cici uygulamalari kullanabilmek icin (mesela adb), ve ileride rooting yapabilmek icin telefonda gelistirici secenekleri (developer option) aktive etmek gerekli. Bunun icin bazi farkli yollar var(mis) benim telefonda secenekler (options) sonra About Device'a gidip "Build number" uzerinde 7 kere tiklama yapmak gerekti.


Kod

Altta arkadas baz bir kamera uygulamasi kodlamis, baslangic noktasi olarak iyi olabilir,

https://github.com/ikkiChung/MyCamera

Actiktan sonra baktik, icinde sadece cok temel kodlar, ayarlar var. Derlenebilir proje icin o dizine gidip alttaki komut isletilir,

ANDROID_SDK/tools/android update project  --target 1 --name MyName  --path .

Bu gerekli tum script'leri yaratir. Simdi ant debug yapilir, bu bir apk  yaratir, bu apk telefona kopyalabilir, vs.

Android icindeki algilayicilarin degerlerini gormek icin ornek kod

https://github.com/onyxbits/sensorreadout