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