Képfelismerés info – Image recognition

forrás: Facebook beszélgetésből

Egy rajzfelismerő alkalmazást akarok írni, ami tök egyszerű formákat, pl Kör, négyzet, háromszög stb… felismer. Mármint hogy a júzer lerajzolja a képernyőre és a program felismeri az előre megadottak közül, hogy melyik az.
Ki hogyan csinálna egy ilyen algoritmust?

A jelenlegi elgondolásom:
Először azonos méretűre skálázza a 2 mintát. Azután a bal felső sarkot használva mint nézőpont X mintát vesz a rajzból, legyen mondjuk X = 90, tehát 1 fokonként minden szögnél. Majd ezen a Xi-edik mintán (ami egy vonal a bal felső saroktól indulva) lekéri az összes pontot ami átmegy a rajzon. Ezt megteszi mind a két rajzzal, végül minden egyes mintánál megnézi hogy az átmeneti pontok mennyire vannak messze egymástól. Végül kiszámolja, hogy átlagosan mennyire voltak messze a kapott mintavételi pontok és ha ez túllép egy értéket akkor nem az adott rajz van a képernyőn.
De hátha van valakinek egy jobb megoldása erre.- Jelenleg a turning Function-on állok, hogy azzal vizsgálom meg az egyes formákat, egyszerűnek tűnik és gyorsnak


Bármit felismerni nyilván nem lehet. Kell lennie egy “ABC”-dnek, amiket ismersz.

Szerintem inkább regressziót használj, vagy klaszterezést. Egy csomó templatelős marhaságot megspórolsz magadnak

****
Detecting some simple shapes in images : http://www.aforgenet.com/articles/shape_checker/

*****

Hough transform : https://en.wikipedia.org/wiki/Hough_transform

******

Handwriting Recognition with Python :

https://www.youtube.com/watch?v=PO4hePKWIGQ

******

Mi az egyetemen MatLabot használtunk erre a célra, egy jó algoritmussal nagyon jó felismerőt lehet készíteni. A konkrét metodikára már nem emlékszem de elérhetőek példakódok is és ha mélyebben beleásol tudod optimalizálni a felismerést (pontosságot javítani illetve beállítani mennyire legyen megengedő a program a felismerés során).

Recognition methods in image processing : http://www.mathworks.com/discovery/image-recognition.html?requestedDomain=www.mathworks.com&requestedDomain=de.mathworks.com

*************************

Tegnap kértem segítséget egy alakzatfelismerő apphoz, mára sikerült az első protoípust megírnom Unity Engine-hez

Szeretném megköszönni mindenkinek a segítséget. Egyébben a TurningFunction-t alkalmaztam.

https://sites.google.com/site/turningfunctions/

Itt a kód annak aki kérte:

http://pastebin.com/95VS8p4h

using UnityEngine;
using System.Collections;

public class Pattern
{
const float angleDivider = 180f;

public Vector2[] points;
public float vectorsLengthSum;
public float[] positions;
public float[] valueOnLines;

public Pattern(Vector2[] points)
{
this.points = points;

vectorsLengthSum = 0f;
Vector2 prevPoint = points[0];
for (int i = 0; i < points.Length; i++) { vectorsLengthSum += Vector2.Distance(prevPoint, points[i]); prevPoint = points[i]; } GenerateTurningFuncion(); } void GenerateTurningFuncion() { positions = new float[points.Length]; valueOnLines = new float[points.Length - 1]; float pos = 0f; Vector2 prevPoint = points[0]; Vector2 prevLine = points[0] - Vector2.right; float value = SignedAngle(Vector2.right, prevLine) / angleDivider; //Count the positions of the points in the shape. for (int i = 0; i < points.Length; i++) { pos += Vector2.Distance(prevPoint, points[i]) / vectorsLengthSum; positions[i] = pos; //Count each value on each line if (i > 0)
{
Vector2 line = points[i] - points[i - 1];
value += SignedAngle(prevLine, line) / angleDivider;
valueOnLines[i - 1] = value;

Debug.Log("Line: " + line + " - " + prevLine + "\t Angle: " + SignedAngle(prevLine, line) + "\t Value: " + value + "\t Added: " + SignedAngle(prevLine, line) / angleDivider);

prevLine = line;
}
prevPoint = points[i];
}
}

public float[] Sample(int sampleCount)
{
float[] samples = new float[sampleCount];

int lineIndex = 0;
for (int i = 0; i < sampleCount; i++) { float samplePos = i / (float)sampleCount; while (positions[lineIndex + 1] < samplePos) lineIndex++; samples[i] = valueOnLines[lineIndex]; //Debug.Log("i: " + i + "\t lineIndex: " + lineIndex + "\t samplePos: " + samplePos + "\t samples[i]: " + samples[i]); } return samples; } public static float AverageDifference(Pattern template, Pattern drawn, int samples) { return Difference(template, drawn, samples) / samples; } public static float Difference(Pattern template, Pattern drawn, int samples) { float[] sourceSamples = template.Sample(samples); float[] targetSamples = drawn.Sample(samples); float avg = 0f; for (int i = 0; i < samples; i++) avg += sourceSamples[i] - targetSamples[i]; return Mathf.Abs(avg); } float SignedAngle(Vector2 v1, Vector2 v2) { //var sign = Mathf.Sign(v1.x * v2.y - v1.y * v2.x); float sign = Mathf.Sign(Vector3.Cross(v1, v2).z); return Vector2.Angle(v1, v2) * sign; } }

************************************************************