Showing posts with label php. Show all posts
Showing posts with label php. Show all posts

Monday, March 31, 2014

Collect - A PHP/JQM Mobile Framework

For nearly as long as I can remember, I've been trying to simplify my programming projects by breaking down long repetitive tasks down into as short and concise steps as I can. I shudder to think of the hours in my life spent putting together a web page that reads a list of items from a database, filters or transforms them, then renders out the appropriate html and attachments. So many times have I done this, across many languages, projects, and technologies.

For the past two years I've been reforming my interest in web, to an interest in mobile web. During this time, I've also run through all my regular distractions like creating a little mobile RSS reader, a mobile client profile database for a cousin, a mobile plumbing inspection checklist for another friend. All these very different projects have a lot in common. They need to capture, edit, delete and list objects. Throw in a little menu navigation and there you have a system. My goal with this PHP/JQM MVC project is to turn my dev cycle for small projects into 90% deciding what I want, 10% typing it in.

Now since I'm targeting mobile devices, form layout can simply default to a vertical list of form controls down the page. All that's really left is deciding what data needs to be captured in my simple data capture app. Here's an example set of definitions...

The Client Profile Demo

There are three object models there: A client, a client state, and a product. Clients have several details, among which is a state. They can be in only one state at a time. Clients can have many products. That may or may not look like a lot,.. but what does it get you?

  • Six tables in your database, three data tables, each with a respective log table tracking all changes
  • An API on the serverside to manipulate that data
  • Clientside forms to edit instances of each of the models
  • Some simple regex error detection in the forms
  • Overview and list pages to navigate the data
  • A dashboard to hold it all together
  • The login procedure and managing users are also thrown in already
Here's some screen grabs of the app produced by the above definitions:

Download and Setup

You can freely download, copy, hack and sell this project from GitHub. To setup your own mobile app, the general process is as follows:

  • Copy this project folder into your htdocs or respective web directory
  • Edit the app/schema.json file to define your models and views
  • Delete any existing app/database.sqlite files (if you want to start from a clean slate)
  • Open api/check.php in a browser. This will create any tables that don't exist
  • Now open your mobile web app in a browser window

Some Caveats

As per usual, I offer this simply as a mostly working prototype. I was actively working on this project more than a year ago, but since then time and priority has led to the inevitable disregard of maintaining it. I still use it often when I need a little admin panel for a website or project I'm working on. I find it workable, but there are definitely bugs, and features half baked in. Have fun with it.

Wednesday, March 27, 2013

PHP Image Comparison: Motion Detection

So a few years ago I spent quite a while using Java to dismantle images from a video feed to detect motion. Using some of the tricks I learned there, I started porting the concept to PHP. Some of my current goals here include but are not limited to the following:
  • Merging/blending images together.
  • Finding motion/changes between two or more images.
  • Reporting said motion/changes as a center coordinate, bounding rectangle, or best yet a vector.

Download

If you're anything like me and don't want to read all my mumbo-jumbo, then you can just go ahead and checkout and download the code on Github here.

Breakdown

First a break down of the main classes... What do they do:
SimpleImage
A class that represents an image. Has functions that help load images from files, stream images to a client, crop, resize, merge/overlay another image, etc.
State
Basically a wrapper for a 2D array of numbers. Provides functions for determining the average, standard-deviation and some other interesting things about said array of numbers. Also some manipulators to filter or change the numbers into other meaningful data. States can be derived from images, or functions of other states.

Code Examples

Blending images together.
What for?
  • Artificial super long exposure photography.
  • Part of my process to display motion detection in a feed of images from a webcam.
include "SimpleImage.php";
include "Util.php";

// get a list of images from a subdirectory
$imagePath = "./img/3/";
$files = listFilesInDirectory($imagePath);

// setup an image to work with
$baseImage = new SimpleImage($imagePath.$files[0]);

// setup an array of all other images
$images = array();
for ($i = 1; $i < count($files); $i++)
 $images[] = new SimpleImage($imagePath.$files[$i]);

// merge the latter images into the first image.
$baseImage->merge($images);

// stream image to client
$baseImage->output();
The above process was run on some images like this:
The result looking like this:
Motion/Change detection
In the following example, the actual change is determined within the first few lines. The second half of the code is just there to display results of said detection.
include "SimpleImage.php";
include "State.php";

// setup two images to work with
$i1 = new SimpleImage("./img/4/IMG_0392.JPG");
$i2 = new SimpleImage("./img/4/IMG_0393.JPG");

// setup the states that will work with and interpret the numbers
$state = new State(15, 8, $i1);
$state = $state->difference(new State(15, 8, $i2), rgbColorDistance);
$state->abs()->denoiseStdDev()->scale(10)->round(0);

// for purposes of visual debugging, merge the two images together
$i1->merge($i2);

// using the merged image, layer on a visual of state differences
$result = $state->drawImageIndicator($i1);

// $box will hold an array (x,y,w,h) that indicates location of change
$box = $state->getBoundingBox($i1->getWidth(), $i1->getHeight());
$color = imagecolorallocate($result->getImage(), 10, 255, 10);
imagerectangle($result->getImage(), $box["x"]-1, $box["y"]-1, 
 $box["x"]+$box["w"]+1, $box["y"]+$box["h"], 
 $color);

// $cog will hold an array (x,y) indicating center of change
$cog = $state->getCenterOfGravity($i1->getWidth(), $i1->getHeight());
imagearc($result->getImage(), 
 $cog["x"], $cog["y"], 7, 7,  0, 360, 
 imagecolorallocate($result->getImage(), 255, 255, 0));
imagearc($result->getImage(), 
 $cog["x"], $cog["y"], 9, 9,  0, 360, 
 imagecolorallocate($result->getImage(), 255, 0, 0));

// stream image to client
$result->output();
The above process was run on these two images:
The result looking like this:

Goals for my next version

  • Add edge detection and island detection (multiple hotspots of change) in one image.
  • Removing non-still objects from a set of images to produce one still image. (ie: Remove tourists from my picture of some famous monument)