public double[] detectionGlyph(bool CalculTailleTerrain)
{
bool Trouve = false;
double[] ratio = new double[2] { 0, 0 };
SimpleShapeChecker shapeChecker = new SimpleShapeChecker();
BlobCounter blobCounter = new BlobCounter();
blobCounter.MinHeight = 23;
blobCounter.MinWidth = 23;
blobCounter.FilterBlobs = true;
blobCounter.ObjectsOrder = ObjectsOrder.Size;
// 4 - find all stand alone blobs
blobCounter.ProcessImage(imgContour);
Blob[] blobs = blobCounter.GetObjectsInformation();
// 5 - check each blob
for (int i = 0, n = blobs.Length; i < n; i++)
{
List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]);
List<IntPoint> corners = null;
// Test de la forme selectionnée
if (shapeChecker.IsQuadrilateral(edgePoints, out corners))
{
// Détection des points de coutour
List<IntPoint> leftEdgePoints, rightEdgePoints, topEdgePoints, bottomEdgePoints;
Line Horizontale = Line.FromPoints(new IntPoint(0,0),new IntPoint(10,0));
blobCounter.GetBlobsLeftAndRightEdges(blobs[i], out leftEdgePoints, out rightEdgePoints);
blobCounter.GetBlobsTopAndBottomEdges(blobs[i], out topEdgePoints, out bottomEdgePoints);
// calculate average difference between pixel values from outside of the
// shape and from inside
float diff = CalculateAverageEdgesBrightnessDifference(leftEdgePoints, rightEdgePoints, imgNB);
// check average difference, which tells how much outside is lighter than
// inside on the average
if (diff > 20)
{
// Transformation de l'image reçu en un carré pour la reconnaissance
QuadrilateralTransformation quadrilateralTransformation = new QuadrilateralTransformation(corners, 60, 60);
UnmanagedImage glyphImage = quadrilateralTransformation.Apply(imgNB);
// Filtre de contraste
OtsuThreshold otsuThresholdFilter = new OtsuThreshold();
otsuThresholdFilter.ApplyInPlace(glyphImage);
imgContour = glyphImage;
// Reconnaissance du Glyph
Glyph Gl = new Glyph(glyphImage, GlyphSize);
Gl.ReconnaissanceGlyph(corners, imgNB);
// Si le Glyph est valide
if (Gl.getIdentifiant() > 0)
{
if (AutAffichage[0])
{
// Coloration des contours des zones détectées
UnImgReel.SetPixels(leftEdgePoints, Color.Red);
UnImgReel.SetPixels(rightEdgePoints, Color.Red);
UnImgReel.SetPixels(topEdgePoints, Color.Red);
UnImgReel.SetPixels(bottomEdgePoints, Color.Red);
}
// Détection du milieu
Line line = Line.FromPoints(corners[0], corners[2]);
Line line2 = Line.FromPoints(corners[1], corners[3]);
IntPoint intersection = (IntPoint)line.GetIntersectionWith(line2);
if (AutAffichage[1])
{
dessinePoint(intersection, UnImgReel, 4, Color.Yellow);
}
// Calcul de la rotation
Line ComparasionAngle = Line.FromPoints(corners[0], corners[1]);
Double rotation = (int) ComparasionAngle.GetAngleBetweenLines(Horizontale);
rotation += 90 * Gl.getNbRotation();
Gl.rotation = 360 - rotation;
rotation *= (Math.PI / 180.0);
// Calcul d'un point en bout de pince
float Taille = corners[0].DistanceTo(corners[1]);
float taille = (Taille / BibliotequeGlyph.Biblioteque[Gl.getPosition()].taille) * BibliotequeGlyph.Biblioteque[Gl.getPosition()].DistancePince;
int x = -(int)(System.Math.Sin(rotation) * taille);
int y = -(int)(System.Math.Cos(rotation) * taille);
x += (int)intersection.X;
y += (int)intersection.Y;
Gl.Position = new int[2]{x,y};
if (AutAffichage[2])
{
dessinePoint(new IntPoint(x, y), UnImgReel, 4, Color.Cyan);
}
imgContour = Gl.getImage();
addGlyph(Gl);
if (CalculTailleTerrain == true && Trouve == false)
{
Trouve = true;
int tailleglyph = BibliotequeGlyph.Biblioteque[Gl.getPosition()].taille;
// Pythagore pour detection taille
Rectangle a = blobs[i].Rectangle;
double angle = - Gl.rotation + 180;
List<IntPoint> coins = new List<IntPoint>();
coins.Add(new IntPoint(100,100));
coins.Add(new IntPoint(100, 100 + tailleglyph));
coins.Add(new IntPoint(100 + tailleglyph , 100 + tailleglyph));
coins.Add(new IntPoint(100 + tailleglyph, 100));
IntPoint Centre = new IntPoint((coins[2].X + coins[0].X)/2, (coins[2].Y + coins[0].Y) / 2);
int radius = (int)(0.5 * Math.Sqrt(coins[0].DistanceTo(coins[1]) * coins[0].DistanceTo(coins[1]) + coins[1].DistanceTo(coins[2]) * coins[1].DistanceTo(coins[2])));
double alpha = Math.Atan2(coins[0].DistanceTo(coins[1]), coins[1].DistanceTo(coins[2])) * (180 / Math.PI);
double ang = 0;
for(i = 0; i < 4; i++)
{
IntPoint tmp = coins[i];
switch (i)
{
case 0:
ang = alpha - 180 + angle;
break;
case 1:
ang = + angle - alpha;
break;
case 2:
ang = + angle + alpha;
break;
case 3:
ang = - alpha + 180 + angle;
break;
}
ang *= (Math.PI / 180);
tmp.X = (int)(Centre.X + radius * Math.Cos(ang));
tmp.Y = (int)(Centre.Y + radius * Math.Sin(ang));
coins[i] = tmp;
}
Rectangle r = new Rectangle(min(coins[0].X, coins[1].X, coins[2].X, coins[3].X), min(coins[0].Y, coins[1].Y, coins[2].Y, coins[3].Y),
max(coins[0].X, coins[1].X, coins[2].X, coins[3].X) - min(coins[0].X, coins[1].X, coins[2].X, coins[3].X),
max(coins[0].Y, coins[1].Y, coins[2].Y, coins[3].Y) - min(coins[0].Y, coins[1].Y, coins[2].Y, coins[3].Y));
ratio[0] = ((double)r.Width / (double)a.Width) * 1.48;
ratio[1] = ((double)r.Height / (double)a.Height) * 1.48;
}
}
}
}
}
if (Trouve == false || ratio[0] == 0 || ratio[0] == 1 || ratio[1] == 0 || ratio[1] == 1)
{
return null;
}
ratio[0] *= 0.7;
ratio[1] *= 0.7;
return ratio;
}