Php Motion Detection - php

Is it possible to achieve motion detection using php?
I'm not a GD/Image library expert, but shouldn't it be possible to detect if there's a significant difference between two images and have that trigger a warning?

I've been working on this type of problem recently. I've managed to compare two images together at any specified level resolution, and gather information about where change is happening, if any. An example using my code.
// setup two images to work with
$i1 = new SimpleImage("./img/0392.jpg");
$i2 = new SimpleImage("./img/0393.jpg");
$state = new State(15, 8, $i1);
$state = $state->difference(new State(15, 8, $i2), rgbColorDistance);
$state->abs()->denoiseStdDev()->scale(10)->round(0);
// $box will hold an array (x,y,w,h) that indicates location of change
$box = $state->getBoundingBox($i1->getWidth(), $i1->getHeight());
Examples and explanation on my blogpost
View code and download from Github
It's still rudimentary but it's a start towards my larger goal of constantly reading motion from a stream of images updated from a webcam.

I think in theory you can do this, you can come up with a basic image comparison. However doing this in PHP is not the best option, if you wanted to do fast frame by frame comparisons you would need to look into a compiled language.
As a basic image detection method you can do the following,
Greyscale Images, Sample every x pixels and compare (Use a threshold value). Then calculate the change percentage, if it's over say 15% you can assume motion.
It's a crude and basic method but it soulds like it will work for your needs.

Found something:
http://phpmotiondetect.sourceforge.net/
But I did not tested it.

Sure, you can use something like imagecolorat to get the colors from pixels on 2 different images.
So yeah, you could do it just like in any other language I guess.

Related

Convert px to mm

I am creating business card maker online, now so far everything was easy until i came to card rendering. In my html document i have:
width = 517px which is equals to 90mm
height = 287px which is equals to 50mm
And according to Photoshop 90mm -> 255px so I need to somehow convert 517px to 255px.
After some googling best solution i came up with so far is (517 / 5.7) * 3 which gives me 272 and it's far from correct answer.
Any suggestions would help a lot :)
P.S I am using php GD.
The correlation between pixels and physical measurements depends entirely on the display and how many physical pixels there are per (square) millimeter. 72ppi (pixels per inch) used to be a typical resolution, but with pixel density increasing across many devices, that's not a given anymore.
There's simply no standard formula.
The resulting pixel number depends on the DPI (resolution) of the output media.
Starting with 90mm equaling ~3,54in you get:
72dpi: 255px
96dpi: 340px
120dpi: 425px
146dpi: 517px
If you don't want to do all the calculation there is a PHP Class which can do this for you.
Here are some informatiosn what the Library can do:
When layouting things one often has to compute various positions, zoom factors, scalings and the like. When the specific sizes are of dynamical nature the layout code quicky gets a confusing endless series of mathematical equations. You name it: spaghetti code. This library tries to offer two approaches to solve this problem:
by taking handling of units from explicit recomputation to implicit
consideration, so all you have to do is name what unit a specific
value is to be interpreted as
by offering well known arithmetical concepts as types which allows to
think in a more high level way about layouting instead of just
simple numeric values.
https://github.com/arkascha/php-urithmetic
I think px divided by 2.02 works perfect in my case at any size of page. In php code i use :
<?php $mm = $px/2.02 ?>

PHP: Building Smooth Image Transitions on the Fly

I'm trying to figure out via PHP if I can do the following. Imagine I have a two images. The first is an image of a square (50px by 50px). The second image, is that exact same square, only offset by 5px to the left.
I'm wondering if there is a way to dynamically generate all the images in-between to make this a smooth looking image transition (ie in this case generate the other 4 images to make it look like it moved from left to right). This would be a pretty simple situation, however would be applied to more complex images with the exact same premises, essentially using two images to predict the mediums.
Thank you in advance for your help
php would only be a wrapper, think eval() and google it, like http://www.linuxfocus.org/English/September2001/article139.shtml
regards,
/t
I believe the best thing you could hope to do with PHP is to do a 'morph' animation, where you sample the pixels for the first image and the second image, then create a third image consisting of the average color values. Repeating this process you could create as many sub-frames as you would like, but the result would be a blurring / morphing of image A -> image B, and would only be perceived as an animation with the simplest of input images.
More complicated algorithms including edge-detection or hinted-shape tweening could be utilized and implemented, however PHP might not be the best choice for this.
You can dynamically create images with a combination of PHP and ImageMagick.
You can pass in each dimension to ImageMagick, and it will generate an image on the fly for you. Create an image for each pixel you offset, resulting (in this case) in four extra images you can use later for your animation.

How to detect similar Images in PHP?

I have many files of a same picture in various resolution, suitable for every devices like mobile, pc, psp etc. Now I am trying to display only unique pictures in the page, but I dont know how to. I could have avoided this if I maintained a database at the first place, but I didn't. And I need your help detecting the largest unique pictures.
Install gd2 and lib puzzle in your server.
Lib puzzle is astonishing and easy to play with it. Check this snippet
<?php
# Compute signatures for two images
$cvec1 = puzzle_fill_cvec_from_file('img1.jpg');
$cvec2 = puzzle_fill_cvec_from_file('img2.jpg');
# Compute the distance between both signatures
$d = puzzle_vector_normalized_distance($cvec1, $cvec2);
# Are pictures similar?
if ($d < PUZZLE_CVEC_SIMILARITY_LOWER_THRESHOLD) {
echo "Pictures are looking similar\n";
} else {
echo "Pictures are different, distance=$d\n";
}
# Compress the signatures for database storage
$compress_cvec1 = puzzle_compress_cvec($cvec1);
$compress_cvec2 = puzzle_compress_cvec($cvec2);
Well, even thou there are quite a few algorithms to do that, i believe it would still be faster to do that manually. Download all the images feed them into something like windows live photo gallery or any other software which could match similar images.
This will take you few hours, but implementing image matching algorithm could take far more. After that you could spend extra time on amending your current system to store everything in a DB.
Fix cause of the problem, not it's symptoms.
Firstly, your problem has hardly anything to do with PHP, so I have removed that tag and added more relevant tags.
Smartly doing it will not require NxN comparisions. You can use lots of heuristics, but first I would like to ask you:
Are all the copies of one image exact resize of each other (is there some cropping done - matching cropped images to the original could be more difficult and time consuming)?
Are all images generated (resized) using the same tool?
What about parameters you have used to resize? For example, are all pictures for displaying on PSP in the same resolution?
What is your estimate of how many unique images you have (i.e, how many copies of each picture there might be - on an average)?
Do you have any kind of categorization already done. For example, are all mobile images in separate folder (or of different resolution than the PC images)? This alone could reduce the number of comparisons a lot, even if you do brute force otherwise.
A very top level hint on why you don't need NxN comparisions: you can devise many different approximate hashes (for example, the distribution of high/low frequency jpeg coefficients) and group "potentially" similar images together. This can reduce the number of comparisions required by 10-100 times or even more depending on the quality of heuristic used and the data set. The hashing can even be done on parts of images. 30000 is not a very large number if you use right techniques.
You should check which of the 2 images is the smallest, take the size of that and then compare only the pixels within the rectangle size.

How to distribute the chance to display each SWF evenly among banner collection?

I am working on The ausdcf.org to try adding several banner ads in swf format to the top.
Everything starts to work, but I've got several questions that need your help:
The client chose not to go with Google AdManager, but prefer a "minimal approach" to do this task.
What I am trying to do is sort of "mimicking" the way Google AdManager does for banners, that is, to split the chance of each particular swf to be shown to the visitor evenly among the banner collection.
Definitely I can add some jQuery code to do this from client-side, a random number generator and if-else statement would work - just $.load() it!
However, what if I'd like to make sure those disabled Javascript (is there any now btw?) still be able to see different swfs in each visit.
Any suggestion on how to approach this?
Many thanks in advance.
The keyword you're looking for is "rotation script" or "banner rotator", and server-side is definitely the way to do something like this.
For PHP, try:
//available banners
$banners = array(
'banner1.swf',
'banner2.swf',
'banner3.swf'
//add more here
);
//get random banner
srand((double) microtime() * 1000000);
$rand = rand(0,count($banners)-1);
//display it
echo $banners[$rand];
This won't evenly rotate the inventory, just randomly. To rotate banners evenly, you'd have to keep track of things. Let me know if you need that and I'll post it here.

What is a good algorithm or library for cropping images to avoid whitespace or empty areas?

I have a whole bunch of images of illustrations that I would like to crop to a smaller preview size.
The problem is that I want to crop them to show an "interesting" part of the illustration (ie avoid areas of whitespace).
The images typically have a flat color or a subtle gradient for the background. They are mostly vector style artwork with fairly distinct shapes.
Here are some examples: link ;-)
I've been thinking about using some sort of image feature detection algorithm with a sliding window to find the area with the greatest number of features.
I'm implementing this in PHP, but I don't mind implementing it myself if there isn't a library or extension available.
Ideas?
ImageMagick has a trim operation. It's available as a library but I don't know how hard it is to use from PHP. There are some PHP interfaces.
OK, so here's what I would've done, after looking at the examples:
Sum all rows and all columns of each image. You'll get two arrays, both looking like this:
/-----\ /--\
_/ -- |
___- \_________
By looking at these arrays for a few images, find a suitable threshold (probably something just above zero). Then the leftmost and the rightmost crossing of this threshold is where you have to crop. I hope I've managed to make it clear enough, if not -- ask!
Here's a fairly simple approach using an edge-detection filter, and then cropping around the center-of-edginess of the image to generate a thumbnail. It works pretty well on most images, but not if there are more than one subject. I'm open to suggestions on other ways of identifying the "interesting" points in a source image.
Well, you might want to consider just using an edge detection algorithm. Pick the area with the largest number of edges. Give higher weight to edges that are not blurry (as they may be from the background).
ImageMagick for PHP has automated generation of thumbnails. This SO question has a link to an ImageMagick auto-crop operator, and I'm not sure, but I think this is the PHP interface to it.
From the link:
bool Imagick::trimImage ( float
$fuzz )
Remove edges that are
the background color from the image.
For more general "interestingness", maybe try an inverse of seam carving (to find the highest energy, rather than lowest energy areas).
A CLI program using http://pecl.php.net/package/imagick:
<?php
dl('imagick.so');
$img = new Imagick();
$img->readImage($argv[1]);
# (* 0.0: exact match; * 1.0: crop entire image)
$fuzz = current($img->getQuantumRange()) * 0.25;
$img->trimImage($fuzz);
$img->writeImage($argv[2]);
?>
It should work good enough, as long as the image doesn't have a frame around its border.
Drupal has a project called smartcrop, which has PHP code to find highest entropy and "interesting" areas in images. See the output examples.
You should be able to use the functions in the module and the library in none-Drupal projects too.

Categories