Skip to content

Commit

Permalink
videoanalysis: wip license plate smart sensor
Browse files Browse the repository at this point in the history
  • Loading branch information
koush committed Apr 17, 2024
1 parent ad9e9f2 commit 6a221ee
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 4 deletions.
36 changes: 36 additions & 0 deletions plugins/objectdetector/src/edit-distance.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
export function levenshteinDistance(str1: string, str2: string): number {
const len1 = str1.length;
const len2 = str2.length;

// If either string is empty, the distance is the length of the other string
if (len1 === 0) return len2;
if (len2 === 0) return len1;

let prev: number[] = new Array(len2 + 1);
let curr: number[] = new Array(len2 + 1);

// Initialize the first row of the matrix to be the index of the second string
for (let i = 0; i <= len2; i++) {
prev[i] = i;
}

for (let i = 1; i <= len1; i++) {
// Initialize the current row with the distance from the previous row's first element
curr[0] = i;

for (let j = 1; j <= len2; j++) {
let cost = str1.charAt(i - 1) === str2.charAt(j - 1) ? 0 : 1;

// Compute the minimum of three possible operations: insertion, deletion, or substitution
curr[j] = Math.min(prev[j] + 1, curr[j - 1] + 1, prev[j - 1] + cost);
}

// Swap the previous and current rows for the next iteration
const temp = prev;
prev = curr;
curr = temp;
}

return prev[len2];
}

43 changes: 39 additions & 4 deletions plugins/objectdetector/src/smart-motionsensor.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import sdk, { Camera, EventListenerRegister, MediaObject, MotionSensor, ObjectDetector, ObjectsDetected, Readme, RequestPictureOptions, ResponsePictureOptions, ScryptedDevice, ScryptedDeviceBase, ScryptedDeviceType, ScryptedInterface, ScryptedNativeId, Setting, SettingValue, Settings } from "@scrypted/sdk";
import { StorageSetting, StorageSettings } from "@scrypted/sdk/storage-settings";
import type { ObjectDetectionPlugin } from "./main";
import { levenshteinDistance } from "./edit-distance";

export const SMART_MOTIONSENSOR_PREFIX = 'smart-motionsensor-';

Expand Down Expand Up @@ -43,8 +44,21 @@ export class SmartMotionSensor extends ScryptedDeviceBase implements Settings, R
type: 'number',
defaultValue: 0.7,
},
labels: {
title: 'Labels',
description: 'The labels that will trigger this smart motion sensor.',
multiple: true,
combobox: true,
choices: [],
},
labelDistance: {
title: 'Label Distance',
description: 'The maximum edit distance between the detected label and the desired label. Ie, a distance of 1 will match "abcde" to "abcbe" or "abcd".',
type: 'number',
defaultValue: 2,
},
requireDetectionThumbnail: {
title: 'Rquire Detections with Images',
title: 'Require Detections with Images',
description: 'When enabled, this sensor will ignore detections results that do not have images.',
type: 'boolean',
defaultValue: false,
Expand Down Expand Up @@ -157,6 +171,9 @@ export class SmartMotionSensor extends ScryptedDeviceBase implements Settings, R
if (this.storageSettings.values.requireDetectionThumbnail && !detected.detectionId)
return false;

let { labels, labelDistance } = this.storageSettings.values;
labels = labels?.map((l: string) => l.toUpperCase());

const match = detected.detections?.find(d => {
if (this.storageSettings.values.requireScryptedNvrDetections && !d.boundingBox)
return false;
Expand All @@ -181,10 +198,28 @@ export class SmartMotionSensor extends ScryptedDeviceBase implements Settings, R
this.console.warn('Camera does not provide Zones in detection event. Zone filter will not be applied.');
}
}
if (!d.movement)
if (d.movement && !d.movement.moving)
return false;

if (!labels?.length)
return true;
return d.movement.moving;
})

if (!d.label)
return false;

const du = d.label.toUpperCase();
for (const label of labels) {
if (label === du)
return true;
if (!labelDistance)
continue;
if (levenshteinDistance(label, du) <= labelDistance)
return true;
}

return false;
});

if (match) {
if (!this.motionDetected)
console.log('Smart Motion Sensor triggered on', match);
Expand Down

0 comments on commit 6a221ee

Please sign in to comment.