Aplicatia ghost surveillance system



Aplicatia ghost surveillance system

10.1. Scopul aplicatiei Ghost Surveillance System

Ghost Surveillance System este o aplicatie software bazata pe platforma JAVA care realizeaza implementarea unui sistem de securitate. Datele video sunt obtinute de la un dispozitiv de captura, cum ar fi un o camera video conectata la un TV Tuner. Software-ul dispune de un subsistem de captura automata care (daca este activat) salveaza cadrele dupa detectia miscarii.

O alta parte a aplicatiei permite accesul la cadrele salvate anterior. Interfata utilizator a acestui subsistem permite accesul usor si intuitiv la arhiva de imagini, marirea si listarea la imprimanta a imaginii selectate.



Aplicatia dispune de un submeniu cu istoricul supravegherii care furnizeaza informatii vizuale despre subsistemul de captura automata.

Mediul de programare folosit este Java, mai exact JSDK 1.3. Pentru partea de captura am folosit tehnologiile din Java Media Framework 2.1.1. (vezi Capitolul 8). Functionarea corecta a aplicatiei este conditionata de instalarea corecta a acestor pachete.

10.2. Prezentarea aplicatiei

Pentru a evita accesul persoanelor neautorizate, la intrarea in aplicatie, utilizatorul este solicitat sa introduca o parola. Parola implicita este “UTCN”. Dupa introducerea corecta a parolei, apare ecranul de intrare in program, care cuprinde sigla aplicatiei si informatii legate de Copyright (Figura 10.1).

 

Figura 10.1.. Ecranul de intrare in aplicatie

Dupa initializarea camerei video, apare ecranul principal (vezi Figura 10.2 si Figura 10.3). Acesta este format din:

 

  • Fereastra Live video – afiseaza continuu imaginile primite de la camera video. Rezolutia la care se realizeaza afisarea este 320x240 pixeli. Vizualizarea poate fi intrerupta prin apasarea butonului Pause.

  • Fereastra informatii utile – afiseaza informatii despre data si ora curenta, cat timp a rulat aplicatia, numarul de cadre salvate. Reimprospatarea informatiilor se face automat.

  • Sigla aplicatiei – este afisata in coltul dreapta sus.

  • Reglaj senzitivitate – permite reglarea senzitivitatii supravegherii. Valorile posibile sunt intre 0 si 100. O valoare de 0 inseamna ca diferenta dintre doua cadre trebuie sa fie de 100% pentru ca aplicatia sa salveze un cadru. O valoare de 100 inseamna ca diferenta intre cadre trebuie sa fie 0 pentru ca aplicatia sa salveze un cadru. In urma testelor a rezultat ca valoarea optima pentru senzitivitate este aproximativ 65.

  • Reglaj rata verificare – permite reglarea perioadei la care sa se faca compararea de cadre. Valorile posibile sunt intre 1 si 10. Valoarea 1 inseamna ca verificarea se face la fiecare 2 secunde, valoarea 10 inseamna ca verificarea se face la fiecare 0.2 secunde.

  • Istoric supraveghere (History) – furnizeaza informatii utile despre diferentele intre cadre. Este activat doar cand supravegherea este pornita. Cu o linie de culoare rosie este afisat pragul de senzitivitate stabilit. Sub forma de dreptunghiuri galbene sunt reprezentate diferentele intre doua cadre analizate succesiv. Daca o diferenta trece peste pragul de senzitivitate, se salveaza automat ultimul cadru analizat. Este foarte util pentru calibrarea sistemului de supraveghere avand in vedere faptul ca pot exista variatii ale calitatii semnalului.

  • Intrare in submeniul Image – este un submeniu care permite vizualizarea, marirea si listarea la imprimanta a imaginilor capturate manual sau automat

  • Captura manuala de cadru – la apasare se realizeaza captura unui cadru, cadru care este salvat intr-un fisier ce include in numele lui ora exacta (la precizie de milisecunda) la care s-a realizat captura, fisier aflat intr-un director cu numele data curenta

  • Buton pornire/oprire supraveghere – permite oprirea/pornirea operatiei de supraveghere. Implicit este Off.Salvarea imaginilor se face in format .JPG.

 

 

 

Informatii utile

 

Fereastra

Live video

Sigla aplicatie

 

Reglaj senzitivitate

Reglaj rata de verificare

Istoric supraveghere

Buton pornire/oprire supraveghere

Captura manuala de cadru

Intrare in submeniul Image

Figura 10.2. Meniul principal cu supravegherea dezactivata

 

History

furnizeaza

informatii

Supravegherea

este activata

Figura 10.3. Meniul principal cu supravegherea activata

 

Prin apasarea butonului Image din meniul principal se ajunge in submeniul Image, unde se pot efectua unele operatii asupra imaginilor, indiferent daca acestea au fost salvate manual sau automat. Fereastra este compusa din:

 

  • In partea din stanga sunt afisate imagini scalate (thumbnails) ale imaginilor salvate. Prin selectarea uneia dintre aceste imagini, in partea din dreapta a ecranului apare imaginea la marimea ei originala (vezi Figura 10.4).

  • Sub imagine se dau informatii despre data si ora exacta la care a fost capturata imaginea.

 

Data si ora capturarii

Buton Back

Buton Revert

Buton Zoom

Preview imagini si selectare

Buton Print

Imaginea afisata

Figura 10.4. Meniul vizualizare imagini

 

  • Butonul de Zoom permite marirea unei anumite zone a imaginii. Marirea zonei de interes implica selectarea cu mouse-ul si apasarea butonului Zoom (vezi Figura 10.5)

 

Imaginea marita

Figura 10.5. Meniul vizualizare imagini – imaginea marita

 

  • Prin apasarea butonului Print aparea fereastra standard de printare din Windows. Imprimarea se realizeaza pentru imaginea originala sau imaginea marita, in functie de operatiile efectuate asupra imaginii (vezi Figura 10.6).

 

Figura 10.6. Meniul vizualizare imagini – imprimare imagine

  • Prin apasarea butonului Back (vezi Figura 10.4) se revine la meniul principal

 

Din meniul principal se pot accesa informatii despre autorul aplicatiei si despre motivele realizarii ei. Pentru aceasta trebuie activata din meniu fereastra HELP/ABOUT. Aici mai gasiti o scurta descriere a aplicatiei, in limba engleza.

Ceea ce ne intereseaza pe noi din aceasta aplicatie este modul cum se realizeaza captura. In primul rand, camera trebuie sa fie detectata cu JMF Registry, care poate fi adus de la www.java.sun.com. Nu toate camerele sunt detectate, dar in general probleme au aparut doar la camerele Logitech.

10.3. Interfata aplicatiei cu camera video

Codul pentru detectia si initializarea camerei video este dat in Exemplul 10.1. Pentru o buna intelegere a tehnologiilor folosite, consultati Capitolul 8.

 

Exemplul 10.1. Interfata aplicatiei GSS cu camera video
/**
Aceasta clasa creaza un processor pentru dispozitivul de capura care a fost inregistrat in prealabil cu JMF Registry si salveaza cadrele capturate intr-un buffer.
*/
import javax.media.*;
import javax.media.format.YUVFormat;
import javax.media.format.JPEGFormat;
import java.util.*;
import javax.media.protocol.*;
import javax.media.datasink.*;
import java.io.IOException;
import java.awt.image.BufferedImage;
import java.awt.Component;
import javax.media.util.BufferToImage;
import javax.media.format.VideoFormat;
import java.awt.Image;
public class CameraInterface extends Thread implements ControllerListener, DataSinkListener{
/**
clasa CameraImterface returneaza OK daca poate trimite
imaginea in buffer
*/
public static final int OK=0;
/**
clasa CameraImterface returneaza NOT_OK daca nu s-a
initiat inca
*/
public static final int NOT_OK=1;
 
private boolean state_transition_OK = true;
private int state=NOT_OK;
private boolean Proceesorstart=false;
private Buffer readBuffer=new Buffer();
private DataSource InitDataSource = null;
//aceasta este DataSource initiala pentru Camera
//private Processor processor;
private Player player;
private Object waitSync = new Object();
private DataSource out_data_source=null;
private DataSource rtpDataSource=null;
private DataSource cloneableDataSource=null;
private DataSourceHandler handler=new DataSourceHandler();
private BufferedImage clip_img=null;
 
/***********************************************************************
* Constructorul
***********************************************************************/
 
/**
Acesta este singurul constructor pentru CameraInterface.
Detecteaza dispozitivul captura si creeaza processorul pentru el
*/
public CameraInterface(){
//out_data_source = processor.getDataOutput();
try {
handler.setSource(ProcessorSetUp());
} catch (IncompatibleSourceException e) {
System.err.println("Cannot handle the output
DataSource from the processor: " + out_data_source);
}
handler.addDataSinkListener(this);
 
// Trece procesorul in starea Prefetch
//processor.prefetch();
//waitForState(processor.Prefetched);
System.out.println("Starts the processor");
handler.start();
//porneste procesorul
//processor.start();
player.start();
state=OK;
}
 
private DataSource ProcessorSetUp(){
CaptureDeviceInfo _cap_info=null;
YUVFormat VF=new
YUVFormat(YUVFormat.YUV_420);
Vector _device_list =
CaptureDeviceManager.getDeviceList(VF);
if (_device_list.size() > 0){
Enumeration _enu=_device_list.elements();
_cap_info = (CaptureDeviceInfo)_enu.nextElement();
_enu=null;
System.out.println(" Capture device info
:"+_cap_info.getName());
}else{
System.out.println("Cannot find a video capture device");
System.exit(0);
}
MediaLocator _mlocator=_cap_info.getLocator();
_cap_info=null;
if (_mlocator == null) {
System.err.println("Cannot build media locator from video
listener " );
System.exit(0);
}
 
// Creaza o DataSource pentru media locatorul dat
try {
InitDataSource = Manager.createDataSource(_mlocator);
cloneableDataSource=Manager.
createCloneableDataSource(InitDataSource);
}catch (Exception e) {
System.err.println("Cannot create DataSource from: " +
_mlocator);
System.exit(0);
}
_mlocator=null;
System.out.println("create processor for: " +
InitDataSource.getContentType());
//creaza un processor pentru DataSource-ul obtinut de
//la Camera
try {
//processor =
Manager.createProcessor(cloneableDataSource);
player=Manager.createPlayer(((SourceCloneable)
cloneableDataSource).createClone());
}catch (Exception e) {
System.err.println("Failed to create a processor from the
given DataSource: " + e);
System.exit(0);
}
// processor.addControllerListener(this);
player.addControllerListener(this);
 
// Trece processorul in starea configured
// processor.configure();
// waitForState(processor.Configured);
 
// primeste iesirea de la processor
// processor.setContentDescriptor(new
ContentDescriptor(ContentDescriptor.RAW));
 
// pune processorul in starea realize
// processor.realize();
// waitForState(processor.Realized);
return (cloneableDataSource);
}
 
/**
Aceasta metoda returneaza starea curenta a CameraInterface
*/
public int getStatus(){
return state;
}
 
public void run() {
}
public synchronized Component getPlayerVisual () {
return (player.getVisualComponent());
}
public synchronized Component getPlayerControl() {
return (player.getControlPanelComponent());
}
public synchronized BufferedImage getBufferedImage(){
BufferedImage bim=null;
VideoFormat vf;
synchronized(readBuffer){
vf=(VideoFormat)readBuffer.getFormat();
BufferToImage bufferToImage = new BufferToImage(vf);
bim= (BufferedImage)bufferToImage.createImage(readBuffer);
if(vf==null){System.out.println("Video format null");};
}
clip_img=bim;
return bim;
}
 
/**
Urmatoarea metoda returneaza imaginea creata din bufferul
de intrare
*/
public BufferedImage getImage(){
return clip_img;
}
 
/**
Aceasta metoda termina Camera Interface
*/
public void Delete(){
//processor.close();
handler.close();
InitDataSource.disconnect();
readBuffer=null;
}
 
public boolean canDelete(){
return true;
}
/**
Aceasta metoda opreste procesarea din buffer
*/
public void Stop(){
handler.Stop();
state=NOT_OK;
}
 
public void controllerUpdate(ControllerEvent evt) {
if (evt instanceof ConfigureCompleteEvent ||
evt instanceof RealizeCompleteEvent ||
evt instanceof PrefetchCompleteEvent) {
synchronized (waitSync) {
state_transition_OK = true;
waitSync.notifyAll();
}
}else if (evt instanceof ResourceUnavailableEvent) {
synchronized (waitSync) {
state_transition_OK = false;
waitSync.notifyAll();
}
}else if (evt instanceof EndOfMediaEvent) {
//processor.close();
}else if (evt instanceof SizeChangeEvent) { }
}
 
public void dataSinkUpdate(DataSinkEvent evt) {
if (evt instanceof EndOfStreamEvent) {
System.err.println("All done!");
evt.getSourceDataSink().close();
System.exit(0);
}
}
 
/**
Aceasta clasa citeste din DataSource si imparte streamul in buffere
*/
 
private class DataSourceHandler extends Thread implements
DataSink,BufferTransferHandler {
DataSource source;
PushBufferStream pushStrms[] = null;
private Vector listeners = new Vector(1);
//Stocheaza toate streamurile care nu s-au terminat
SourceStream unfinishedStrms[] = null;
 
/**
Seteaza DataSource pentru DataSourceHandler
*/
public void setSource(DataSource source) throws
IncompatibleSourceException {
if (source instanceof PushBufferDataSource) {
System.err.println("The source is push Buffer Data Source ");
pushStrms = ((PushBufferDataSource)source).getStreams();
unfinishedStrms = new SourceStream[pushStrms.length];
for (int i = 0; i < pushStrms.length; i++) {
pushStrms[i].setTransferHandler(this);
unfinishedStrms[i] = pushStrms[i];
}
}else
throw new IncompatibleSourceException();
this.source = source;
}
 
public void setOutputLocator(MediaLocator ml) {
}
public MediaLocator getOutputLocator() {
return null;
}
 
public String getContentType() {
return source.getContentType();
}
 
public void open() {
}
 
public void run() {
try {