public override void Run() { EtichettaturaComponentiConnesse e1 = new EtichettaturaComponentiConnesse(InputImage, fg, metrica); e1.Execute(); InformazioniComponentiConnesse i1 = new InformazioniComponentiConnesse(); i1.InputImage = InputImage; i1.fg = fg; i1.metrica = metrica; i1.Run(); int[] aree = i1.getAree(); Result = new Image <byte>(InputImage.Width, InputImage.Height, 0); //controllo quali aree sono maggiori ImageCursor cursor = new ImageCursor(InputImage); do { //controllo le etichette, se il pixel fa parte di una componente connessa //con area > areaMinima allora lo mette bianco, altrimenti lo lascia nero if (e1.Result[cursor] != -1) { if (aree[e1.Result[cursor]] > AreaMinima) { Result[cursor] = fg; } } }while(cursor.MoveNext()); }
public override void Run() { Result = new Image <byte>(InputImage.Width, InputImage.Height); //costruisce l'array degli offset dell'elemento strutturante riflesso int[] elementOffsets = MorphologyStructuringElement.CreateOffsets(StructuringElement, InputImage, true); //crea un cursore per scorrerel'immagine escludendo i pixel di bordo var pixelCursor = new ImageCursor(StructuringElement.Width / 2, StructuringElement.Height / 2, InputImage.Width - 1 - StructuringElement.Width / 2, InputImage.Height - 1 - StructuringElement.Height / 2, InputImage); //a differenza della dilatazione controllo se c'è almeno un pixel di background, //se è così il pixel nn fa parte dell'output bool da_canc = false; do { foreach (int offset in elementOffsets) { if (InputImage[pixelCursor + offset] != Foreground) { //un pixel di background trovato da_canc = true; break; } } if (!da_canc) { Result[pixelCursor] = Foreground; } da_canc = false; }while (pixelCursor.MoveNext()); }
public override void Run() { Result = new Image <int>(InputImage.Width, InputImage.Height); var r = Result; var cursor = new ImageCursor(r, 1); if (Metric == MetricType.CityBlock) //d4 { do //scansione diretta { if (InputImage[cursor] == Foreground) { r[cursor] = Min(r[cursor.West], r[cursor.North]) + 1; } }while (cursor.MoveNext()); do //scansione inversa { if (InputImage[cursor] == Foreground) { r[cursor] = Min(r[cursor.East] + 1, r[cursor.South] + 1, r[cursor]); } }while (cursor.MovePrevious()); } else //d8 { do //scansione diretta { if (InputImage[cursor] == Foreground) { r[cursor] = Min(r[cursor.West], r[cursor.North], r[cursor.Northeast], r[cursor.Northwest]) + 1; } }while (cursor.MoveNext()); do //scansione inversa { if (InputImage[cursor] == Foreground) { r[cursor] = Min(r[cursor.East] + 1, r[cursor.Southwest] + 1, r[cursor.South] + 1, r[cursor.Southeast] + 1, r[cursor]); } }while (cursor.MovePrevious()); } }
public override void Run() { Result = new List <CityBlockContour>(); var pixelstart = new ImageCursor(InputImage); var direction = new CityBlockDirection(); bool[] visitato = new bool[InputImage.PixelCount]; do { if (InputImage[pixelstart] == Foreground && !visitato[pixelstart] && InputImage[pixelstart.West] != Foreground) { //??? si fa tutto //aggiungo il primo pixel alla lista dei contorni var c = new CityBlockContour(pixelstart.X, pixelstart.Y); Result.Add(c); visitato[pixelstart] = true; // inseguimento del contorno a partire da (x,y), // aggiungendo le direzioni a c var cursor = new ImageCursor(pixelstart); direction = CityBlockDirection.West; do { for (int j = 1; j <= 4; j++) { direction = CityBlockMetric.GetNextDirection(direction); if (InputImage[cursor.GetAt(direction)] == Foreground) { break; } } cursor.MoveTo(direction); c.Add(direction); visitato[cursor] = true; direction = CityBlockMetric.GetOppositeDirection(direction); }while (cursor != pixelstart); //si ferma quando incontra il pixel iniziale } } while (pixelstart.MoveNext()); }
public override void Run() { Result = new Image <byte>(InputImage.Width, InputImage.Height); //costruisce l'array degli offset dell'elemento strutturante riflesso int[] elementOffsets = MorphologyStructuringElement.CreateOffsets(StructuringElement, InputImage, true); //crea un cursore per scorrerel'immagine escludendo i pixel di bordo var pixelCursor = new ImageCursor(StructuringElement.Width / 2, StructuringElement.Height / 2, InputImage.Width - 1 - StructuringElement.Width / 2, InputImage.Height - 1 - StructuringElement.Height / 2, InputImage); do { foreach (int offset in elementOffsets) { if (InputImage[pixelCursor + offset] == Foreground) { Result[pixelCursor] = Foreground; break; } } }while(pixelCursor.MoveNext()); }
public override void Run() { Result = new ConnectedComponentImage(InputImage.Width, InputImage.Height, -1); var cursor = new ImageCursor(InputImage, 1); // per semplicità ignora i bordi (1 pixel) int[] neighborLabels = new int[Metric == MetricType.CityBlock ? 2 : 4]; int nextLabel = 0; var equivalences = new DisjointSets(InputImage.PixelCount); do { // prima scansione if (InputImage[cursor] == Foreground) { int labelCount = 0; if (Result[cursor.West] >= 0) { neighborLabels[labelCount++] = Result[cursor.West]; } if (Result[cursor.North] >= 0) { neighborLabels[labelCount++] = Result[cursor.North]; } if (Metric == MetricType.Chessboard) { // anche le diagonali if (Result[cursor.Northwest] >= 0) { neighborLabels[labelCount++] = Result[cursor.Northwest]; } if (Result[cursor.Northeast] >= 0) { neighborLabels[labelCount++] = Result[cursor.Northeast]; } } if (labelCount == 0) { equivalences.MakeSet(nextLabel); // crea un nuovo set Result[cursor] = nextLabel++; // le etichette iniziano da 0 } else { int l = Result[cursor] = neighborLabels[0]; // seleziona la prima for (int i = 1; i < labelCount; i++) // equivalenze { if (neighborLabels[i] != l) { equivalences.MakeUnion(neighborLabels[i], l); // le rende equivalenti } } } } } while (cursor.MoveNext()); //rende le etichette numeri consecutivi int totalLabels; int[] corresp = equivalences.Renumber(nextLabel, out totalLabels); //seconda e ultima scansione cursor.Restart(); do { int l = Result[cursor]; if (l >= 0) { Result[cursor] = corresp[l]; } }while(cursor.MoveNext()); Result.ComponentCount = totalLabels; }
public override void Run() { EtichettaturaComponentiConnesse e1 = new EtichettaturaComponentiConnesse(InputImage, fg, metrica); e1.Execute(); //numero totale compponenti connesse numComponentiConnesse = e1.Result.ComponentCount; //trovo l'area delle componenti connesse aree = new int[numComponentiConnesse]; //vettore di aree delle componenti connesse //inizializzo elementi a 0 for (int i = 0; i < numComponentiConnesse; i++) { aree[i] = 0; } //calcolo le aree di tutte le componenti connesse ImageCursor cursor = new ImageCursor(e1.Result); do { if (e1.Result[cursor] != -1) { //incremento l'area di quella componente connessa che è l'indice del //vettore, quindi è molto semplice aree[e1.Result[cursor]]++; } }while(cursor.MoveNext()); //trovo area minima, area massima e area media areaMin = int.MaxValue; areaMax = 0; areaMedia = 0; for (int i = 0; i < numComponentiConnesse; i++) { if (aree[i] < areaMin) //minimo { areaMin = aree[i]; } if (aree[i] > areaMax) //massimo { areaMax = aree[i]; } } //calcolo area media areaMedia = Media(aree); //trovo lunghezza media dei perimetri int[] perimetri = new int[numComponentiConnesse]; for (int i = 0; i < numComponentiConnesse; i++) { perimetri[i] = 0; } //stesso cursore di prima, escludo il pixel di bordo per gli indici cursor = new ImageCursor(e1.Result, 1); do { if (e1.Result[cursor] != -1) { //controllo se è un pixel di contorno, cioè se ha almeno un pixel di background //come vicino. In base alla metrice scelta controllo le direzioni if (e1.Result[cursor.East] == -1 || e1.Result[cursor.West] == -1 || e1.Result[cursor.South] == -1 || e1.Result[cursor.North] == -1) { perimetri[e1.Result[cursor]]++; continue; } //se la metrica è chessboard controllo anche le direzioni diagonali, //per non aumentare 2 volte il perimetro con lo stesso pixel entra qui //se non è entrato nel primo if if (metrica == MetricType.Chessboard) { if (e1.Result[cursor.Northeast] == -1 || e1.Result[cursor.Northwest] == -1 || e1.Result[cursor.Southeast] == -1 || e1.Result[cursor.Southwest] == -1) { perimetri[e1.Result[cursor]]++; } } } }while(cursor.MoveNext()); //calcolo media dei perimetri perimetroMedio = Media(perimetri); }