Android - camera as motion detector Android - camera as motion detector android android

Android - camera as motion detector


Here is a Tutorial on how to take a photo with the camera.

If your take a photo every second, and then scale it down to something like 8x8 pixels, you can easily compare two photos and find out if something has happened, to trigger you action.

The reason why you should scale it down are the following:

  1. It is less error prone to noise introduced by the camera
  2. It will be much faster than doing a comparison of the whole image


I solved that taking pictures every n seconds and scaling it to 10*10 pixels and finding the difference between them. Here is the kotlin implementation:

private fun detectMotion(bitmap1: Bitmap, bitmap2: Bitmap) {    val difference =        getDifferencePercent(bitmap1.apply { scale(16, 12) }, bitmap2.apply { scale(16, 12) })    if (difference > 10) { // customize accuracy        // motion detected    }}private fun getDifferencePercent(img1: Bitmap, img2: Bitmap): Double {    if (img1.width != img2.width || img1.height != img2.height) {        val f = "(%d,%d) vs. (%d,%d)".format(img1.width, img1.height, img2.width, img2.height)        throw IllegalArgumentException("Images must have the same dimensions: $f")    }    var diff = 0L    for (y in 0 until img1.height) {        for (x in 0 until img1.width) {            diff += pixelDiff(img1.getPixel(x, y), img2.getPixel(x, y))        }    }    val maxDiff = 3L * 255 * img1.width * img1.height    return 100.0 * diff / maxDiff}private fun pixelDiff(rgb1: Int, rgb2: Int): Int {    val r1 = (rgb1 shr 16) and 0xff    val g1 = (rgb1 shr 8) and 0xff    val b1 = rgb1 and 0xff    val r2 = (rgb2 shr 16) and 0xff    val g2 = (rgb2 shr 8) and 0xff    val b2 = rgb2 and 0xff    return abs(r1 - r2) + abs(g1 - g2) + abs(b1 - b2)}