Skip to content

Commit

Permalink
videoanalysis: improve similar character checker
Browse files Browse the repository at this point in the history
  • Loading branch information
koush committed Apr 18, 2024
1 parent 94055d0 commit 47897da
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 36 deletions.
4 changes: 2 additions & 2 deletions plugins/objectdetector/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion plugins/objectdetector/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@scrypted/objectdetector",
"version": "0.1.35",
"version": "0.1.36",
"description": "Scrypted Video Analysis Plugin. Installed alongside a detection service like OpenCV or TensorFlow.",
"author": "Scrypted",
"license": "Apache-2.0",
Expand Down
98 changes: 65 additions & 33 deletions plugins/objectdetector/src/edit-distance.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,68 @@
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;
const similarCharacters = [
['0', 'O', 'D'],
['1', 'I'],
['2', 'Z'],
['4', 'A'],
['5', 'S'],
['8', 'B'],
['6', 'G'],
// not sure about this one.
['A', '4'],
['C', 'G'],
['E', 'F'],
];

const similarCharactersMap = new Map<string, Set<string>>();
for (const similarCharacter of similarCharacters) {
for (const character of similarCharacter) {
if (!similarCharactersMap.has(character)) {
similarCharactersMap.set(character, new Set());
}
for (const similar of similarCharacter) {
similarCharactersMap.get(character)!.add(similar);
}

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;
}
}

function isSameCharacter(c1: string, c2: string) {
if (c1 === c2)
return true;

return similarCharactersMap.get(c1)?.has(c2);
}

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 = isSameCharacter(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);
}

return prev[len2];

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


return prev[len2];
}

0 comments on commit 47897da

Please sign in to comment.