Laden...
Avatar #avatar-1768.jpg
dr4g0n76 myCSharp.de - Experte
Software-Entwickler, momentan als Software Test Engineer tätig Deutschland Dabei seit 07.07.2005 2.921 Beiträge

Forenbeiträge von dr4g0n76 Ingesamt 2.921 Beiträge

22.03.2010 - 11:32 Uhr

Nein, das ist keine Werbung in eigener Sache, aber da es das hier kostenlos gibt:

Vorlagen für liniertes und kariertes Papier

Hiermit könnt ihr Vorlagen für bestimmte Papierformate herunterladen. Diese sind zum Ausdrucken gedacht.

22.03.2010 - 08:41 Uhr

Es gibt vorerst keine Ankündigungen mehr. Erst wenn das Projekt m.E. für die erste Version fertig ist.

Hier noch die versprochenen Videos:

Image scripting console

Verkehrsschilderkennung:

Verkehrsschilderkennung

Auswirkung Processingmode:

Processing Modes

Vorschaufenster:

Vorschaufenster

Bitte im ersten Post dieses Threads nachsehen, falls sich was geändert hat.
Oder per PM nachfragen.

Danke.

16.03.2010 - 14:01 Uhr

Ich belebe mal diesen Thread ein wenig wieder. @Egrath:

Hab heute dein Programm hier ausgegraben und mir mal erlaubt das mit der LowLevelGraphicsLibrary zu verbinden.

An der Stelle an der Du mit den Schiebereglern den Wert ausliest der eingestellt wurde, wird jetzt der in der ComboBox ausgewählte Filter benutzt, wenn möglich.

Jetzt kann jeder mal ausprobieren was das für Auswirkungen haben kann.

Hinweis:

Da das momentan die aktuellste Library ist können Abstürze auftreten. Ich bin aber momentan daran alle zu beheben.

Ich hoffe das ist ok für Dich Egrath. 😃

Das veränderte Programm von Dir gibt's hier als Anhang

EDIT: Anhang jetzt online, hat vorher nicht mit hochladen geklappt

15.03.2010 - 16:48 Uhr

Hallo,

heute wurde meine Frau von der Nummer oben im Betreff angerufen und es wurde behauptet, sie hätte 330 Euro gewonnen. Von der Ard. Zuerst hatte Sie das Geburtsdatum durchgegeben.

Dann hieß es wohin sollen wir das Geld überweisen? Wir brauchen nur noch ihre Kontodaten.
Da sie sich aber geweigert hatte, die Kontodaten durchzugeben, wurde aufgelegt.

Also falls das jemand demnächst hören sollte von euch, wißt ihr schon, dass das nur Betrug sein kann.

Schleierhaft ist uns allerdings noch woher die unsere Nummer hatten. Denn wir haben unsere Geheimnummer noch nirgends veröffentlicht. Deswegen vermute ich das die mit einer Art War-Dialer arbeiten, einem Programm das Nummern wählt und automatisch feststellen kann, ob ein Signal (Amtston) zurückkommt.

EDIT: Um Weiteren Missbrauch zu vereiteln kann man bei der Bundesnetzagentur die Nummer auf einem Formular melden. Aber momentan komme ich nicht auf die Seiten. Es wird immer von meinem Browser behauptet der Server sei down.

12.03.2010 - 18:36 Uhr

Version noch nicht online

Der Script-Editor der angedacht war, funktioniert endlich so wie er schon immer sollte.
Es gibt aber auch ein paar Erweiterungen

EDIT:

Beschreibung hinzugefügt:
Dies wird vorerst über die Klasse RuntimeInterpreter abgewickelt.
Diese kann Zeilen einzeln abarbeiten. Momentan wird nur eine relativ starre Syntax unterstützt.

  • 27.02 - 12.03 Ausprogrammierung der Scriptsprache:

Integrierte Befehle:

  • Load "PicName" //wird benutzt, um PicName zu laden.
  • Display //zeigt ein Ausgabefenster an
  • Filtername //führt den Filter "FilterName" aus
  • Save "PicName" //speichert das aktuelle Pic unter "PicName" ab.

Noch zu integrieren:

  • Filtername Parameter1 = Wert1, Parameter2 = Wert2, Parameter3 = Wert3 ...

weitere Ideen vorbehalten.

03.03.2010 - 14:34 Uhr

@Jack30Lena:

Ich denke IMHO dass mosspower nicht weiß, wie Du recherchiert hast, wäre bestimmt interessant für die User hier zu posten.

😃

03.03.2010 - 12:05 Uhr

Na super und ich werde ab heute gewzungen bei uns in der Firma folgendes zu schreiben:



bool b = true;
if (b == true) //Warum ver#$@! noch mal darf ich nicht mehr if (b) schreiben!? *KOTZ*


02.03.2010 - 17:49 Uhr

Für alle die wissen wollen, was momentan passiert, Auszug aus dem History-File:

27.02.2010

  • Formel für AdaptiveThreshold Mean korrigiert

25.02.2010

  • UnsafeBitmap bResult = b1 * b1 + b1 / b1; ≤ jetzt können Formeln mit Bitmaps
    dank Operatorüberladung auch in dieser Form geschrieben werden
  • RaiseToPower: Konstruktor ergänzt, so dass jetzt auch die Parameter übergeben werden können
  • PhotoshopFillmodi: UnsafeImage image = new UnsafeImage(bitmap) hat doppelte Sperrung ausgelöst, korrigiert.
  • Konstruktor von Exponential und Radical ergänzt
  • Bresenham nach Drawing verschoben
  • Formel Für PixelFormat erweitert, jetzt müssen aber vorerst alle Filter die nur unsafe Code benutzen,
    nochmals getestet werden,
    Median enthält noch Fehler

24.02.2010

  • Lambda und GreaterLambdaCommand Filter in LowLevelGraphics eingebaut und überflüssigen Code entfernt
    LambdaImageProcessingTools.dll wird deswegen nicht mehr benötigt
    Auch hier wird jetzt sofort UnsafeBitmap verwendet, dadurch konnte die Geschwindigkeit nochmals erhöht werden
  • Monotony benutzt keine Nachbarschaftsoperationen mehr, sondern eine schnellere Implementierung
  • Hartemischung nach Photoshop Fillmodi verschoben
  • ColorPaletteMatching hat zwei neue Konstruktoren bekommen (ColorMap, ColorMatrix)
  • BaseImageFilter um "SupportedPixelFormats" erweitert.
  • Nicht mehr benötigten Code gelöscht

23.02.2010

  • Alle Filter und Interfaces benutzen jetzt soweit möglich UnsafeBitmap
  • Filter "Distance" in "DistanceTransform" umbenannt

11.02.2010

  • Alle Filter klonbar gemacht
  • Alle Variablen die für Einstellungen verantwortlich sind auf Protected gesetzt
  • Ebenso für diese Variablen Properties eingeführt, wenn sinnvoll
  • Skalierungsfaktor für ColorDifference eingeführt, IMHO ist der Filter sonst unbrauchbar

10.02.2010

  • FishEyeFilter ist jetzt vom Typ BaseImageFilter
  • AdaptiveThresholding: WindowSize und Constant werden jetzt berücksichtigt bei allen 3 Modi
  • ColorFunctions.ToIntRGB korrigiert, falsche Berechnungsformel wurde benutzt.
  • RoundColorsUnsafe kann jetzt nicht mehr mit bUnsafe TRUE/FALSE benutzt werden, es wird immer die schnellste Methode benutzt
  • SameColor in SameColorValues umbenannt und implementiert
  • EntropyThreshold: Beginn der Implementierung

08.02.2010
Offset-Filter eingefügt, war zuvor in der Klasse CGraphics vorhanden, jetzt in LowLevelGraphics.filter Namespace

02.02.2010
Optimierungen

  • Test der gesamten Funktionalität
  • Überall lokale Variablen eingeführt,
    so dass diese nicht mehr in der Schleife angelegt werden müssen

30.01.2010
Optimierung und Idealisierung des Konzeptes

  • Segmentation,
    FastSegmentation,
    FastSegmentation2,
    BarcodeFilter,
    CenterPoint,
    SortChannels,
    ExchangeChannels
    benutzen jetzt nur noch UnsafeBitmaps

  • Bearbeitungsroutine von

    ExchangeChannels
    RotateChannels
    RoundColors
    RotateChannels
    korrigiert,

    nicht alle Pixel wurden bearbeitet

  • FilterMuliples benutzt jetzt UnsafeBitmap, vergessen

  • Gray2Color benutzt jetzt UnsafeBitmap, vergessen

15.12.2009
Alle Filter - soweit möglich - in verschiedene Ordner verschoben.
Die Namespaces dazu existieren noch nicht.

01.10.2009
ConnectedComponents.cs

- Invert Methode gelöscht, da es diese schon gibt  

Datei-Download s. 1 Post

Ziel ist alles was momentan enthalten ist, richtig zum Funktionieren zu bringen und zu optimieren.

01.03.2010 - 19:01 Uhr

@mosspower: Ich hatte einmal die gleiche Erfahrung gemacht.
Ich weiß aber nicht mehr was das bei HTTPRequest war. Man muss noch irgendwelche Properties setzen sonst ist es so langsam beim ersten mal.

Alternative:

Webseiten auslesen mit HttpWebRequest

01.03.2010 - 17:30 Uhr

@slide: Ich denke, in diesem Fall solltest Du uns hier den Code zeigen, der dafür verantwortlich ist. Außerdem wäre interessant, welches DB-System und welches OS Du benutzt.

26.02.2010 - 10:30 Uhr

Mit anonymen Typen haltichs für Spielerei, aber die typen mag ich eh nicht, weil man sie nicht an andere Methoden weitergeben kann.

Das ist so nicht richtig, siehe angehängtes Code-Beispiel.


      var blub = new { Item = "Hallo" };
            ProcessAnonymousType(blub);
        }


        public void ProcessAnonymousType(object _var)
        {
            var blub2 = _var  //jetzt ist das Item von oben nicht mehr direkt sichtbar
        }

Wenn Du aber meinst, dass man vorerst jetzt nichts mehr mit dem Objekt der Klasse anfangen kann, weil die Items nicht mehr direkt sichtbar sind, stimme ich Dir zu.

26.02.2010 - 08:14 Uhr

@Golo: InteressanteAnsicht,

aber wie ich oben schon gesagt hatte, ob das in diesem Sinne alles zusammen passt, war vorerst egal. Ich wollte nur wissen, ob es mit dieser Methodik geht.

Aber euere Gedanken dazu gefallen mir, finde ich sehr interessant.

Wer möchte kann das ja ohne den Cast mit Latent mal versuchen.

Dann müsste IMHO eine Exception kommen.

Ducktyping musste ich glatt nochmal nachschlagen.

[...]
Duck-Typing ist ein Konzept der objektorientierten Programmierung, bei dem der Typ eines Objektes nicht durch seine Klasse beschrieben wird, sondern durch das Vorhandensein bestimmter Methoden.
[...]
[...]
Dies führt wie bei allen dynamischen Typsystemen zu einer erhöhten Flexibilität, reduziert aber ebenso die Möglichkeit, statisch zur Übersetzungszeit Fehler im Programm zu finden.
[...]

Natürlich ist es aufjeden Fall ein Kompromiss...

Überlegen wir doch mal was wir damit für einen Gewinn/Verlust erzielen, dann kommen wir sicher darauf ob das Konstrukt sinnvoll oder einfach nur Quatsch.

25.02.2010 - 17:54 Uhr

Ergänzung:

Enthält z.B. DoIt nichts (String.Empty) erhalten wir eine:

Method-Access-Exception:
<>f__AnonymousType0`2.get_Test()

25.02.2010 - 17:32 Uhr

EDIT: "umwandeln" in Überschrift und Text in "casten" geändert

in C# 3.0 ist es möglich anonyme Typen zu erstellen. Wer LINQ, var & Co. benutzt, kennt das womöglich alles schon.

Heute hat mich aber interessiert, kann man einen anonymen Typ in ein Interface casten? Es ging mir nicht darum, ob es grundsätzlich Sinn macht, sondern nur ob es tatsächlich möglich ist.

Ich hatte damals eine Lösung gepostet, um einem Objekt zur Laufzeit ein definiertes Interface hinzuzufügen:
Interface zur Laufzeit zu einer Klasse hinzufügen (Lösung)

Und mit dieser Kombination ist es tatsächlich möglich:


     var blub = new { Test = "hallo", DoIt = "" };

    public interface IBlub    
    {
        string Test { get; }
        string DoIt { get; }
    }


Probieren wir es aus:


            var blub = new { Test = "hallo", DoIt = "2" };

            IBlub iblub = Latent<IBlub>.Cast(blub);
            MessageBox.Show(iblub.Test);
            MessageBox.Show(iblub.DoIt);


Und tatsächlich, nacheinander wird

"hallo"

und

"2" ausgegeben.

Es geht also. 😃

25.02.2010 - 11:57 Uhr

Sind die Farbräume

HSB, HSI, HSV, HSL, HLS, TSL wirklich identisch?

d.h. bezeichnen diese ein und dieselbe Umrechnung?

Was ich dazu rausgefunden habe:

HSL = TSL (TSL ist wohl die französische Bezeichnung Tint, Saturation, Luminance)

Zumindest sind dann wohl schon

HSL, HLS, TSL identisch

bleiben noch HSB, HSI, HSV

24.02.2010 - 15:46 Uhr

@Joetempes: Was soll denn später noch möglich sein?

Ansonsten stimme ich mit Talla überein.

Vorgehensweise ungefähr:

1.) Bild einscannen oder aus dem Internet heraussuchen (anatomische Darstellung wie benötigt)

2.) Regionen auswählen (Polygone), dann kannst Du an diesen Stellen das Bild mit dem Polygon überzeichnen (Halb durchscheinend z.B. indem Du ein

Pseudocode:



new (Solid?)Brush(Color.FromArgb(127,FarbeR, FarbeG, FarbeB) //127 für halbdurchscheinend.


Wenn Du jetzt noch 2 Bilder übereinander legst (Mensch nackt?!) und die anatomische Darstellung darüberprojizierst

Hinweis: dann aber keine PictureBox verwenden bzw. wenn doch, selbst zeichnen (also nicht PictureBox.Image/PictureBox.BackgroundImage verwenden, sondern Graphics.DrawImage o. ä.)

(Beide Bilder mit DrawImage darstellen)

kannst Du schon sehr viel anstellen.

Hilft das weiter?!

24.02.2010 - 15:31 Uhr

@Gorn, dann poste uns hier deinen Deserializable Code oder das ganze Projekt.

Kam der gleiche Fehler, oder hat sich irgendetwas an dem Verhalten verändert?

24.02.2010 - 14:54 Uhr

@Gorn:

Füg ein


stream.Seek(0, SeekOrigin.Begin);

vor dem Deserialisieren ein, klappts jetzt?

EDIT: siehe auch:

Fehler beim MemoryStream

23.02.2010 - 18:29 Uhr

Was bedeutet "Rayleigh" bei einem Histogramm?

Vermutlich ein Histogramm mit Hilfe der

Rayleigh Distribution (Wikipedia)

22.02.2010 - 14:08 Uhr

Danke, diese Implementierung reicht aus, und da dieses Projekt sowieso in VB geschrieben werden muss (leider), kann ich das direkt so übernehmen.

Sehr gut.

Schon eingebaut.

@Golo, benutzt ihr diese Implementierung jetzt 1:1?

22.02.2010 - 12:50 Uhr

Hallo Kollegen,

ist euch schon ein observable Dictionary in .NET begegnet oder muss man sich das selbst bauen?

Eine Suche nach

Dictionary Observable

in Google bringt zwar einige Ergebnisse im .NET-Bereich aber keinen Namespace der diese Implementierung enthalten würde. Auch hier im Forum hab ich nichts dazu gefunden.

Weiß das jemand von euch?

Wenn wir übereinstimmen feststellen werden, dass es das nicht gibt, werde ich eine eigene Implementierung machen und diese hier einstellen.

17.02.2010 - 12:39 Uhr

Inzwischen habe ich diese Implementierungen fertig.
Und möchte eine Energy-Map / Entropy Map erstellen.

Habe aber leider kein Beispiel-Bild im Internet gefunden, um das Ergebnis kontrollieren zu können (Ausgangsbild->Filter->Ergebnisbild).

Für einen Link wäre ich äußerst dankbar.

Die Suche nach Energy Map oder Entropy Map und ähnlichen Kombinationen

mit den Wörtern

Bilderkennung
energy
map
entropy
image processing

EDIT: war leider NICHT erfolgreich.

17.02.2010 - 12:21 Uhr

@SlyFox: Soweit ich Dich verstehe, wenn das nur für den Designer gilt, denke ich Du brauchst ein Addon.

1.) Im Designer
Denn Du möchtest folgendes erreichen (während Du im VS im Designer editierst):

UserControl 1, das Text druckt, wird auf den Druck-Container gezogen.
Also soll Visual Studio an dieser Stelle implementieren, dass gedruckt wird.

UserControl 2, das Text anzeigt, wird auf den bsp. Pdf-Container gezogen.
Also soll Visual Studio an dieser Stelle implementieren, dass PDF angezeigt wird.

2.) Zur Laufzeit

Du möchtest zur Laufzeit Controls hinzufügen, je nachdem wo hin diese gezogen werden, soll etwas spezielles mit dem Container passieren.

Das würde z.B. gehen in dem man die Methode

this.OnControlAdded(...)

entsprechend für die UserControl-Container implementiert.

Gibt natürlich auch vielfältige andere Möglichkeiten, wie z.B. in

Designer Hosting

Frage: Meinst Du 1.) oder 2.)? (Fettgedruckt)

16.02.2010 - 20:38 Uhr

@LuckyGeorge, inzwischen habe ich die Entropy Funktion programmiert. Danke für die Hilfe.

Hier übrigens noch eine Funktion die eher dem entspricht

16.02.2010 - 14:40 Uhr

@Siassei:

Wenn Du das dann doch brauchen solltest für verschiedene Sprachen kannst Du u.a. auch hier nachsehen:

Zahlen umrechnen in anderes Format.

15.02.2010 - 17:06 Uhr

Ab wann kann man mit der neuen Version rechnen?

Hallo Digi333.

das wird noch ein wenig dauern.

Momentan bin ich gerade dabei, alles der Reihe nach durchzuprüfen mit vorrangig zuerst 2 Zielen:

1.) Die Funktionalität zu gewährleisten.
2.) Die Geschwindigkeit zu optimieren.

Insgesamt soll sich die Library möglichst flexibel einsetzen lassen.

Ich hatte mir schon bevor ich diese umgeschrieben habe, einige Funktionen von Matlab, Halcon und OpenCV angesehen.

Ich möchte so weit wie möglich an diese Funktionalitäten herankommen, oder wenn das zuviel des guten ist, sollte zumindest so viel in der Library drinstecken, dass man sich diese Funktionalitäten einfach bauen kann.

Momentan schreibe ich den Test-Editor (ImageRecognition2) um.

Dieser hat jetzt ein MDI-interface bekommen.
Zusätzlich kann eingestellt werden, ob nach jeder Aktion die man ausführt (Filter) ein neues Fenster geöffnet werden soll.

Für Filter die mehrere Sourcen benötigen, wird es dann eine Auswahl geben.

Außerdem entsteht eine neue Komponente namens Scripter (die war schon zuvor angedacht unter Fenster->Script). Diese wurde bisher aber nie von mir richtig ausprogrammiert. Das ändert sich dann mit der neuen Version.

Hier ein
Screenshot als Beispiel:

04.02.2010 - 13:29 Uhr

@JAck30lena:

Ja, dass das auch mit Assembly.<EinenDerLoadBefehle> für eine Assembly aus dem Pfad

C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727

bzw. allgemeiner

<Teilpfad>\Microsoft.NET\Framework\v2.0.50727

auch geht, ist mir klar, ich dachte nur, dass man auch eine Möglichkeit hat, direkt auf Namespaces und Typen zuzugreifen, ohne die Assembly explizit laden zu müssen.

Es geht auch wie in der Code-Lösung beschrieben über die Erstellung eines Types aus dem entsprechenden Namespace und dann über

object.GetType().AssemblyQualifiedName

das PublicKeyToken auslesen.

03.02.2010 - 17:22 Uhr

Danke @koller.

Hier meine bisherige Lösung:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Drawing;

namespace Scripter
{
    public class PublicKeyDummyCreationFactory
    {
        private static PublicKey key = new PublicKey();

        private static List<string> _aAssemblyName = new List<string>() { "System.Windows.Forms", "System.Drawing", "System"};//, "LowLevelGraphics", "LowLevelGraphics.Filter" };
        static PublicKeyDummyCreationFactory()
        {
            foreach(string sAssemblyName in _aAssemblyName)
            {
                key.Add(sAssemblyName, Create(sAssemblyName));
            }
        }

        public static List<string> AssemblyNames
        {
            get { return _aAssemblyName; }
        }

        public static PublicKey PublicKeys
        {
            get { return key; }
        }

        public static string Create(string _sAssemblyName)
        {
            object oObject = null;
            if (_sAssemblyName == "System.Windows.Forms")
            {
                oObject = new System.Windows.Forms.Form();
            }
            else if (_sAssemblyName == "System.Drawing")
            {
                oObject = new SolidBrush(Color.Red);
            }
            else if (_sAssemblyName == "System")
            {
                oObject = new Int32();
            }
            else if (_sAssemblyName == "")
            {
            }
            return GetPublicKeyTokenPart(oObject.GetType().AssemblyQualifiedName);
        }

        private static string GetPublicKeyTokenPart(string _sAssemblyName)
        {
            string[] aPublicKeyTokenElement = Regex.Split(_sAssemblyName,",");
            string sPublicKeyTokenPart = aPublicKeyTokenElement[aPublicKeyTokenElement.Length - 1].Split('=')[1];
            return sPublicKeyTokenPart;
        }
    }

    public class PublicKey : Dictionary<string,string>
    {
        public PublicKey()
        {
        }

        public void Add(string _sAssemblyName)
        {
            this.Add(_sAssemblyName, PublicKeyDummyCreationFactory.Create(_sAssemblyName));
        }
    }

    public class TypeCreationFactory
    {
        //"System.Windows.Forms.Form, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=System.Windows.Forms.Form, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
        public static Type GetType(string _sFullQualifiedTypeName)
        {
            List<string> aElement = new List<string>();
            aElement.AddRange(Regex.Split(_sFullQualifiedTypeName, @"\."));

            string sFullQualifiedAssemblyName = string.Join(".", aElement.ToArray(), 0, aElement.Count - 1).TrimEnd('.');
            return GetType(sFullQualifiedAssemblyName, aElement[aElement.Count - 1]);
        }

        public static Type GetType(string _sFullQualifiedAssemblyName, string _sTypeName)
        {
            Type typeTemp = null;
            string sFullQualifiedTypeName = string.Empty;
            if (PublicKeyDummyCreationFactory.PublicKeys.ContainsKey(_sFullQualifiedAssemblyName))
            {
                string sPublicKeyToken = PublicKeyDummyCreationFactory.PublicKeys[_sFullQualifiedAssemblyName];

                sFullQualifiedTypeName = string.Format("{0}.{1}, {0}, Version=2.0.0.0, Culture=neutral, PublicKeyToken={2}", _sFullQualifiedAssemblyName, _sTypeName, sPublicKeyToken);
                typeTemp = Type.GetType(sFullQualifiedTypeName);
            }
            if (typeTemp == null)
            {
                sFullQualifiedTypeName = string.Empty;
                sFullQualifiedTypeName = string.Format("{0}.{1}", _sFullQualifiedAssemblyName, _sTypeName);
                typeTemp = Type.GetType(sFullQualifiedTypeName);
            }
            return typeTemp;
        }

        public static Type GetType(string _sOnlyTypeName, bool _bExceptionOnAmbiguousTypes)
        {
            Type typeTemp = null;
            foreach (string sAssemblyName in PublicKeyDummyCreationFactory.AssemblyNames)
            {
                typeTemp = GetType(sAssemblyName, _sOnlyTypeName);
                if (typeTemp != null)
                {
                    break;
                }
            }
            return typeTemp;
        }
    }
}

Jetzt kann ich mit PublicKeyDummyCreationFactory.GetType("MessageBox", false)
z.B. den Typ der MessageBox ermitteln.

03.02.2010 - 14:57 Uhr

Wenn ich alle Typen einer Assembly ermitteln will, die ich zuvor mit Assembly.Load o.ä. geladen habe, geht das ganz einfach mit Assembly.GetTypes().

Was mache ich aber wenn ich das ganze zur Laufzeit für eine der .NET Assemblies haben möchte? Sagen wir, ich möchte alle Typen unter

System.Windows.Forms

wie mache ich das?

Außerdem soll hinterher der Typ zur Laufzeit erstellt werden.

Suchen hier im Forum nach

"Zur Laufzeit" Reflection GAC

oder in Google nach ähnlichem, habe mich bisher nicht zur Lösung geführt.

Und dann habe ich das Problem wenn ich einen Typ aus dem GAC zur Laufzeit erstellen will mit Type.GetType dass u.a. das PublicKeyToken benötigt wird.

Zumindest gibt es die ansatzweise Lösung eine Factory zu erstellen für einen Typ aus einer speziellen Assembly und dann über object.GetType().AssemblyFullQualifiedName das PublicKeyToken auszulesen

Oder gehen diese beide Sachenganz einfach und ich steh nur gerade auf dem Schlauch weil ich viel zu kompliziert denke?

EDIT: Ach ja Hintergrund ist der, dass ich eine eigene Intellisense programmieren soll.

03.02.2010 - 12:17 Uhr

Im WPF gibt es bestimmt etwas dafür, in .NET 2.0 sieht es um einiges komplizierter aus, ich denke dass man da die Windows-Api bemühen muss.

Vielleicht hilft Dir das weiter:

How to scin scrollbars for Panels, in C#

03.02.2010 - 12:11 Uhr

zweite.dll zuzugreifen ohne diese nocheinmal explizit einzubinden?

Was meinst du mit "explizit" einbinden?

Die Angabe von

using Dll2VerweisNameSpace.Unternamespace

o.ä.?!

03.02.2010 - 12:00 Uhr

1.) Hier eine andere Seite die die Grundlagen teilweise erklärt:

Beats Per Minute from real-time audio...

2.) Zur BPM Library, diese funktioniert bei mir, allerdings musst du in das Sample1 Bsp. für C-Sharp

die bpmDetect.dll und die fmodex.dll kopieren.

Ansonsten erhältst du eine Exception wie "Der angegebene Typen-Initialisierer Hat eine Ausnahme verursacht", das passiert dann in der Klasse

BPMDetection genau hier:


        public BPMDetection()
        {
            bpm = BPM_Create();
        }

weil BPM_Create in bpmdetect.dll steckt und wenn die nicht da ist...

28.01.2010 - 16:41 Uhr

@Zommi so gesehen ist mein Beispiel falsch.

Aber hier eins für eine 3x3 Konvolution aus der LowLevelGraphicsLibrary:

EDIT: Man beachte wie hier die Nachbarschaft berechnet wird


///This filter is tested and seems to work correctly

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;

namespace LowLevelGraphics.Filter
{
    public class Convolution3x3 : BaseImageFilter
    {
        CConvMatrix m_ConvolutionMatrix = null;

        public Convolution3x3()
            : this(new CConvMatrix())
        {
        }

        public Convolution3x3(CConvMatrix _matrix)
        {
            m_ConvolutionMatrix = _matrix;
        }

        public override void Execute(Bitmap _bitmap)
        {
            Bitmap b = _bitmap;
			// Avoid divide by zero errors
			if (0 == m_ConvolutionMatrix.Factor) return;

			Bitmap bSrc = (Bitmap)b.Clone(); 

			// GDI+ still lies to us - the return format is BGR, NOT RGB.
			BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
			BitmapData bmSrc = bSrc.LockBits(new Rectangle(0, 0, bSrc.Width, bSrc.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

			int stride = bmData.Stride;
			int stride2 = stride * 2;
			IntPtr Scan0 = bmData.Scan0;
			IntPtr SrcScan0 = bmSrc.Scan0;

			unsafe
			{
				byte * p = (byte *)(void *)Scan0;
				byte * pSrc = (byte *)(void *)SrcScan0;

				int nOffset = stride - b.Width*3;
				int nWidth = b.Width - 2;
				int nHeight = b.Height - 2;

				int nPixel;

				for(int y=0;y < nHeight;++y)
				{
					for(int x=0; x < nWidth; ++x )
					{
						nPixel = ( ( ( (pSrc[2] * m_ConvolutionMatrix.TopLeft) + (pSrc[5] * m_ConvolutionMatrix.TopMid) + (pSrc[8] * m_ConvolutionMatrix.TopRight) +
							(pSrc[2 + stride] * m_ConvolutionMatrix.MidLeft) + (pSrc[5 + stride] * m_ConvolutionMatrix.Pixel) + (pSrc[8 + stride] * m_ConvolutionMatrix.MidRight) +
							(pSrc[2 + stride2] * m_ConvolutionMatrix.BottomLeft) + (pSrc[5 + stride2] * m_ConvolutionMatrix.BottomMid) + (pSrc[8 + stride2] * m_ConvolutionMatrix.BottomRight)) / m_ConvolutionMatrix.Factor) + m_ConvolutionMatrix.Offset); 

						if (nPixel < 0) nPixel = 0;
						if (nPixel > 255) nPixel = 255;

						p[5 + stride]= (byte)nPixel;

						nPixel = ( ( ( (pSrc[1] * m_ConvolutionMatrix.TopLeft) + (pSrc[4] * m_ConvolutionMatrix.TopMid) + (pSrc[7] * m_ConvolutionMatrix.TopRight) +
							(pSrc[1 + stride] * m_ConvolutionMatrix.MidLeft) + (pSrc[4 + stride] * m_ConvolutionMatrix.Pixel) + (pSrc[7 + stride] * m_ConvolutionMatrix.MidRight) +
							(pSrc[1 + stride2] * m_ConvolutionMatrix.BottomLeft) + (pSrc[4 + stride2] * m_ConvolutionMatrix.BottomMid) + (pSrc[7 + stride2] * m_ConvolutionMatrix.BottomRight)) / m_ConvolutionMatrix.Factor) + m_ConvolutionMatrix.Offset); 

						if (nPixel < 0) nPixel = 0;
						if (nPixel > 255) nPixel = 255;
							
						p[4 + stride] = (byte)nPixel;

						nPixel = ( ( ( (pSrc[0] * m_ConvolutionMatrix.TopLeft) + (pSrc[3] * m_ConvolutionMatrix.TopMid) + (pSrc[6] * m_ConvolutionMatrix.TopRight) +
							(pSrc[0 + stride] * m_ConvolutionMatrix.MidLeft) + (pSrc[3 + stride] * m_ConvolutionMatrix.Pixel) + (pSrc[6 + stride] * m_ConvolutionMatrix.MidRight) +
							(pSrc[0 + stride2] * m_ConvolutionMatrix.BottomLeft) + (pSrc[3 + stride2] * m_ConvolutionMatrix.BottomMid) + (pSrc[6 + stride2] * m_ConvolutionMatrix.BottomRight)) / m_ConvolutionMatrix.Factor) + m_ConvolutionMatrix.Offset); 

						if (nPixel < 0) nPixel = 0;
						if (nPixel > 255) nPixel = 255;

						p[3 + stride] = (byte)nPixel;

						p += 3;
						pSrc += 3;
					}
					p += nOffset;
					pSrc += nOffset;
				}
			}

			b.UnlockBits(bmData);
			bSrc.UnlockBits(bmSrc);
        }
    }
}

P.S.: Momentan bin ich beim Überarbeiten der Library (soweit ich überhaupt dazu komme), d.h. 1.) Richtigkeit und 2.) Geschwindigkeit überprüfen.

28.01.2010 - 16:06 Uhr

@LuckyGeorge:

Bitte, Bitte, Bitte implementiere den Weichzeichner - bzw. jeden linearen und linear separierbaren Filter - nicht so.

Pixelorientierte Filter wie z.B. die Grauumrechnung sind sowieso in dieser Art implementiert:


    unsafe
            {
                byte* p = (byte*)(void*)Scan0;

                int nOffset = stride - b.Width * 3;

                byte red, green, blue;

                for (int y = 0; y < b.Height; ++y)
                {
                    for (int x = 0; x < b.Width; ++x)
                    {
                        blue = p[0];
                        green = p[1];
                        red = p[2];

                        p[0] = p[1] = p[2] = (byte)(grayScale(red, green, blue));

                        p += 3;
                    }
                    p += nOffset;
                }
            }

Wenn es wirklich eine LowLevelGraphics Library werden soll optimiere die Filterfunktionen. Auch wenn der Code so lesbarer ist - bei so einer Schleifen Konstruktion ist die Rechengeschwindigkeit ob der vielen unnötigen Berechnungen ein graus. Zudem skaliert diese Implementierung nicht linear sondern quadratisch zur Filtergröße.

Dazu muss ich Dir noch etwas in der PM schreiben.

Ich lasse Dir gerne mal eine optimierte Variante eines Mittelwertfilters mit beliebiger Filtergröße zukommen.

Dieses Angebot nehme ich gerne an. Den werde ich mal dann mit meinem median bzw. mean Filter vergleichen.

Dein Neighbour Konzept ist gut fürs Patternmatching - aber wenn Du deine Filter damit realisierst werden sich spätere Anwender nicht freuen. In der Bildverarbeitung muss man einfach jede Filterfunktion einzeln optimiert implementieren und kann eher selten einen generischen Ansatz wählen. Es sei denn Geschwindigkeit ist nicht relevant ...

Viele Filter sind schon realisiert. Das Neighbouring soll ein Zusatz sein mit dem sich jeder selber etwas bauen kann.

PS: Ich werde deine PM erst heute abend beantworten können - muß dazu nochmal was nachlesen.

28.01.2010 - 14:12 Uhr

Hallo dr4g0n76,

die Klassen Pixel und Neighbour finde ich gut, die Klasse Neighbours würde ich nicht von List <Neighbour > ableiten. Erstmal ist List <T> nicht als Oberklasse gemacht und dann finde ich es auch nicht gut, wenn der Benutzer zu Neighbours beliebige Neighbour hinzufügen kann, und das auch noch unkontrolliert.

Ich hing an dem Konzept der Konvolution fest. Das ist auch der Grund für meine ganzen

***
*P*
***

  • Erklärungen. Wie man sieht sind das immer Felder einer Länge von n * n (meist mit n = 3, Konvolutions-Matirx) in den meisten Fällen.

Ich stelle mir es eher so vor, dass man später Unterklassen von Neighbours definiert, die selbst und algorithmisch die Neighbour des Pixel ermitteln.

Wenn natürlich eine Klasse selbst deren Neighbours ermittelt und man deswegen natürlich auch verschiedene Nachbarschaften in ein und dem selben Prozess definieren kann erweitert sich natürlich die Flexibilität enorm.

Ich ging nur von einer Nachbarschaft pro Operation aus.

Intern kann ja die Standardimplementierung ja eine List <Neighbour> enthalten (und diese auch als (readonly) IList<Neighbour> nach außen geben oder selbst IEnumerable<Neighbour> passend implementieren), aber eine Unterklasse sollte selbst entscheiden können, wie die Pixel bestimmt und ob sie überhaupt in einer Liste gespeichert werden.

Ja das mit den Neighbours als IEnumerable<Neighbour> kam mir gestern auch schon in den Sinn. Nachdem ich den obigen Ansatz gemacht hatte.

Dass die Unterklassen die Pixel bestimmen widerspricht zwar dem Gedanken des Ansatzes der Konvolution an sich, aber ich stimme zu dass das eine ganz andere Art der Implementierungsfreiheit bietet.

Was sich mir allerdings noch nicht erschließt ist wie dann das optimale Lesen der Pixel (möglichst ohne Überschneidungen) vor sich geht. Da ja die Neighbour Klassen dann selbst die Pixel bestimmen...

Eine ganz andere Variante wäre nicht das doppelte Lesen auszuschließen sondern sich einfach teilergebnisse für bestimmte Operationen in gewisser Weise zu merken und damit unnötige Rechenoperationen zu vermeiden.

Innen könntest du auch foreach nehmen.

Absolut richtig.

28.01.2010 - 11:55 Uhr

Damit könnte der Weichzeichner vorerst so aussehen:

EDIT: Die Neighbourdefinitione fehlten noch:


       Neighbours neighbours = new Neighbours();
            neighbours.Add(new Neighbour(0, -1));
            neighbours.Add(new Neighbour(-1, 0));
            neighbours.Add(new Neighbour(1, 0));
            neighbours.Add(new Neighbour(0, 1));

            neighbours.Add(new Neighbour(1, 1));
            neighbours.Add(new Neighbour(-1, 1));
            neighbours.Add(new Neighbour(1, -1));
            neighbours.Add(new Neighbour(-1, -1));


   Neighbour currentNeighbour = null;
            int nSumR = 0;
            int nSumG = 0;
            int nSumB = 0;
            foreach (Pixel pixel in aPixel)
            {
                IEnumerator iPixel = pixel.Neighbours;

                nSumR = pixel.Color.R;
                nSumG = pixel.Color.G;
                nSumB = pixel.Color.B;
                while (iPixel.MoveNext())
                {
                    currentNeighbour = (Neighbour)iPixel.Current;
                    nSumR += currentNeighbour.Color.R;
                    nSumG += currentNeighbour.Color.G;
                    nSumB += currentNeighbour.Color.B;
                }
                nSumR /= (neighbours.Count + 1);
                nSumG /= (neighbours.Count + 1);
                nSumB /= (neighbours.Count + 1);
                pixel.Color = Color.FromArgb(nSumR, nSumG, nSumB);
            }

28.01.2010 - 11:45 Uhr

Hmmmm....

wie wäre es vorerst mit folgender Definition:

Klasse Pixel:


using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;

using LowLevelGraphics;

namespace NeighbouringTest
{ 
    public class Pixel : IEnumerator, IEnumerable
    {
        private static UnsafeBitmap bitmap = null;
        private static Neighbours aNeighbours = null;
        private static int nWidth = -1;
        private static int nHeight = -1;
        private int m_nX = -1;
        private int m_nY = -1;
        private int m_nIndex = -1;

        public static UnsafeBitmap Bitmap
        {
            set
            {
                bitmap = value;
                nWidth = bitmap.Width;
                nHeight = bitmap.Height;
            }
            get { return bitmap; }
        }

        public Pixel(int _nX, int _nY)
        {
            m_nX = _nX;
            m_nY = _nY;
        }

        public Color Color
        {
            get 
            {
                if (m_nX > -1 && m_nX < nWidth && m_nY > -1 && m_nY < nHeight)
                    return bitmap.GetPixel(m_nX, m_nY);
                else
                    return Color.Transparent;
            }
            set
            {
                if (m_nX > -1 && m_nX < nWidth && m_nY > -1 && m_nY < nHeight)
                    bitmap.SetPixel(m_nX, m_nY, value);
            }
        }

        public Color this[int _nXOffset, int _nYOffset]
        {
            get {
                int nTempX = m_nX + _nXOffset;
                int nTempY = m_nY + _nYOffset;
                
                if (nTempX > -1 && nTempX< nWidth && nTempY > -1 && nTempY < nHeight)
                    return bitmap.GetPixel(nTempX, nTempY);
                else
                    return Color.Transparent;
            }
            set {
                int nTempX = m_nX + _nXOffset;
                int nTempY = m_nY + _nYOffset;
                if (nTempX > -1 && nTempX < nWidth - 1 && nTempY > -1 && nTempY < nHeight)
                    bitmap.SetPixel(nTempX, nTempY, value);
            }
        }

        public Color this[Neighbour _neighbour]
        {
            get { return this[_neighbour.XOffset, _neighbour.YOffset]; }
            set { this[_neighbour.XOffset, _neighbour.YOffset] = value; }
        }

        public int X
        {
            get { return m_nX; }
            set { m_nX = value; }
        }

        public int y
        {
            get { return m_nY; }
            set { m_nY = value; }
        }

        #region IEnumerator<Neighbours> Members

        public static void SetNeighbours(Neighbours _aNeighbour)
        {
            aNeighbours = _aNeighbour;
        }

        private static Neighbour aNeighbours1 = null;

        public Neighbour Current
        {
            get
            {
                aNeighbours1 = aNeighbours[m_nIndex];
                aNeighbours1.Pixel = this;
                return aNeighbours1;
            }
        }

        #endregion

        #region IDisposable Members

        public void Dispose()
        {
            
        }

        #endregion

        #region IEnumerator Members

        object IEnumerator.Current
        {
            get { return this.Current; }
        }

        public bool MoveNext()
        {
            if (m_nIndex + 1 < aNeighbours.Count)
            {
                m_nIndex++;
                return true;
            }
            else
            {
                return false;
            }
       }

        public void Reset()
        {
            m_nIndex = -1;
        }

        #endregion

        #region IEnumerable Members

        public IEnumerator Neighbours
        {
            get { return this; }
        }

        public IEnumerator GetEnumerator()
        {
            return this;
        }

        #endregion   
    }
}


Klasse Neighbour:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;

namespace NeighbouringTest
{
    public class Neighbour
    {
        private int m_nXOffset = -1;
        private int m_nYOffset = -1;
        private Pixel m_Pixel = null;

        public Neighbour(int _nXOffset, int _nYOffset)
        {
            m_nXOffset = _nXOffset;
            m_nYOffset = _nYOffset;
        }

        public int XOffset
        {
            get { return m_nXOffset; }
            set { m_nXOffset = value; }
        }

        public int YOffset
        {
            get { return m_nYOffset; }
            set { m_nXOffset = value; }
        }

        public Pixel Pixel
        {
            set { m_Pixel = value; }
        }

        public Color Color
        {
            get { return m_Pixel[m_nXOffset, m_nYOffset]; }
            set { m_Pixel[m_nXOffset, m_nYOffset] = value; }
        }
    }
}

Klasse neighbours:


    public class Neighbours : List<Neighbour>
    {
    }

Ob Alle Klassen so benötigt werden, sei noch dahingestellt.

Es kann aber folgendes programmiert werden:


   m_Bitmap = (Bitmap)Image.FromFile(@"D:\Temp\programmieren\Temp\Strassen\_DSC8563_1.jpg");
            UnsafeBitmap bitmap = new UnsafeBitmap(m_Bitmap);

            List<Pixel> aPixel = new List<Pixel>();

            Pixel.Bitmap = bitmap;
            Neighbours neighbours = new Neighbours();
            neighbours.Add(new Neighbour(-3,7));
            neighbours.Add(new Neighbour(7,3));

            Pixel.SetNeighbours(neighbours);

            int nR = 0;

            //Das kommt später aus UnsafeBitmap.GetPixels
            for (int y = 0; y < bitmap.Height; y++)
            {
                for (int x = 0; x < bitmap.Width; x++)
                {
                    aPixel.Add(new Pixel(x, y));
                }
            }

            Color color = Color.Transparent;

            int nGrayValue = 0;

            Neighbour currentNeighbour = null;

            //Berechnungen durchführen
            foreach(Pixel pixel in aPixel)
            {
                IEnumerator iPixel = pixel.Neighbours;

                nGrayValue = 0;
                while (iPixel.MoveNext())
                {
                    currentNeighbour = (Neighbour)iPixel.Current;
                    nGrayValue += ColorFunctions.Gray(currentNeighbour.Color);
                    nGrayValue += Math.Abs(currentNeighbour.Color.R - pixel.Color.R) + Math.Abs(currentNeighbour.Color.G - pixel.Color.G) + Math.Abs(currentNeighbour.Color.B - pixel.Color.B);
                }
                if (nGrayValue > 255) nGrayValue = 255;
                pixel.Color = Color.FromArgb(nGrayValue, nGrayValue, nGrayValue);
            }

            bitmap.Dispose();

            this.BackgroundImage = m_Bitmap;
        }

27.01.2010 - 17:01 Uhr

Bisher komme ich auf 2 Ideen um die Pixel-Nachbarschaften "effizienter" zu lesen:

Es gibt einen Mechanismus der in einem Array(?) LastAccessedPixels zusammenfasst, wird dann das nächste Pixel gelesen (x+1) oder (y+1) oder (x-1) oder (y-1) muss entsprechend über ein offset implizit Zugriff auf eines der LastAccessedPixels geschehen.

Die Matrix enthält Methoden um die in ihr enthaltenen Werte in X Richtung oder in Y Richtung zu verschieben.

ShiftColumn / ShiftLine
d.h. bei einer schon gelesenen Matrix (3x3) die so aussieht:

111
111
111

wird daraus durch ShiftLine:

011
011
011

oder

110
110
110

Eine Verschiebung in beide Richtungen (x+1 und y+1 quasi gleichzeitig) erhält man dann durch jeweilige Verschiebung in einer der beiden Achsen-Richtungen

Zahl = Anzahl Lesezugriffe,
Nachbarschaft = *
P = Pixel

***
*P*
***

000
000
000

Bei normalem Vorgehen (unoptimiert), gelesen in X-Richtung (x = x+1),
P ist die Stelle an der wir uns gerade befinden:

1221
12P1
1221

optimiert:

1111
1111
1111

  • 3 (ungelöst).

es wird vermieden dass überhaupt ein Pixel mehr als 1 mal gelesen werden muss,
d.h. es findet nur ein GetPixel Lesezugriff statt und es gibt beim Lesen der Daten keine Überschneidungen und kein zusätzliches Array für zugegriffene Werte.

Quasi eine Lösung die durch intelligentes Lesen des Bildes auch gleichzeitig die Nachbarschaftsstrukturen ermittelt.

25.01.2010 - 17:06 Uhr

@Schamese: Ist aber von der Firma her nicht erlaubt. Ist ja nicht meine Entscheidung. 😉

25.01.2010 - 17:02 Uhr

@ViperNeo: Falls Du wirklich auf die Bitmap Ebene runter willst bzw. musst kannst Du ja dann wirklich den Code von BobPowell oder von hier benutzen:

(CodeProject) Fast FloodFill ...

25.01.2010 - 16:03 Uhr

Wir exportieren bei uns in der Firma verschiedene Texte mit Visual Localize.
Visual Localize generiert dabei ein TAB(ulator) orientiertes Format. Dieses soll einem externen Geschäftspartner zur Verfügung gestellt werden, deswegen soll zwar der Inhalt der Spalten verändert werden können, nicht aber die Tabulatoren selbst.

Excel scheint dafür ohne Extra ein Sheet programmieren zu müssen nicht geeignet zu sein.

Wenn man es einfach so ausprobiert werden in Excel die Spalten zerschossen, wenn man nicht genauestens auf alles achtet.

Kennt jemand einen Editor der so etwas kann? Kann auch kostenpflichtig sein.

22.01.2010 - 13:56 Uhr

/edit: irgendwie bekomme ich die sourcen von bob powell flood fill nicht zum laufen. gehen die bei euch?

Was heißt irgendwie? Welche Fehlermeldung bekommst Du?!

Denn ich habe die Klasse auch schon mal ausprobiert und sie lief.

22.01.2010 - 10:02 Uhr

@ViperNeo:

s. dazu auch hier:

Bob Powell Flood Fill

EDIT:

Wenn Du uns genauer mitteilst, was Du damit erreichen möchtest, finden wir vielleicht hier schon einen richtigen Verweis im Forum oder können Dir anderweitig weiterhelfen, sprich: Vielleicht brauchst Du gar kein FloodFill!?

Oder Du brauchst vielleicht einen anderen als den Standard-Flood-Fill?!

Der GrundAlgorithmus ist übrigens rekursiv:

21.01.2010 - 18:13 Uhr

@Jack30Lena:
Ja, für das aktuelle Modell passt das sowieso nicht mehr. Auf diesen Gedanken kam ich auch schon, wie gesagt das war nur der erste Prototyp Schnellschuss.

Also, gehen wir davon aus, dass die Indizes an die Bitmap gekoppelt sind.

Was passiert aber mit 3dimensionalen Nachbarschaften oder Polygonen, ist das mit dem Vorschlag von Herbivore und dem Modell von mir (Indizes als Offset in x und in y) vereinbar?!

Brauchen wir optimierte Strukturen wenn wir z.B. einen gefüllten Kreis/Ellipse/Quadrat bzw. Polygon allgemein nehmen?

P.S.: Zu Deiner Anmerkung:

Der Ansatz knallt nicht gegen eine NEGATIV-App-Domain-Schallmauer, weil das Netz zuvor aufgebaut wurde. 😉

21.01.2010 - 17:47 Uhr

Hab den Titel umgeändert. Schien mir passender.

21.01.2010 - 16:50 Uhr

ok, dann schlage ich vor, da ich schon ähnliche Ideen hatte (ich hatte aber bisher nur überlegt, diese auf das bisher von mir vorgestellte Modell zu projizieren)

dass das Thema des Threads umgeändert wird und wir hier über das Modell diskutieren.

Mein bisheriges Modell (Protoytyp-Schnellschuss), sieht bisher so aus:


  public class Pixel
    {
        private Pixel[] m_aNeighbour = new Pixel[8];
        private Point m_ptPoint = Point.Empty;
        private Color m_Color = Color.Transparent;
        private int m_nX = -1;
        private int m_nY = -1;
        private Color[] m_aColor = new Color[8];
        /// <summary>
        /// The position HAS(!) to be given
        /// </summary>
        /// <param name="_color"></param>
        /// <param name="_nX"></param>
        /// <param name="_nY"></param>
        public Pixel(Color _color, int _nX, int _nY)
        {
            m_Color = _color;
            m_nX = _nX;
            m_nY = _nY;
            m_Color = _color;
        }

        public Pixel(Pixel[] _aNeighbour)
        {
            int i = 0;
            for (i = 0; i < 8; i++)
            {
                m_aNeighbour[i] = _aNeighbour[i];
            }
        }

        public Color[] NeighbourColors
        {
            get { return m_aColor; }
        }

        public Pixel this[int _nIndex]
        {
            get { return m_aNeighbour[_nIndex]; }
            set { m_aNeighbour[_nIndex] = value; }
        }

        public int X
        {
            get { return m_nX; }
        }

        public int y
        {
            get { return m_nY; }
        }

        public Point Point
        {
            get { return new Point(m_nX, m_nY); }
        }

        public Color Color
        {
            get { return m_Color; }
            set { m_Color = value; }
        }

        public Pixel LeftTop
        {
            get { return m_aNeighbour[0]; }
            set { m_aNeighbour[0] = value; }
        }

        public Pixel MiddleTop
        {
            get { return m_aNeighbour[1]; }
            set { m_aNeighbour[1] = value; }
        }

        public Pixel RightTop
        {
            get { return m_aNeighbour[2]; }
            set { m_aNeighbour[2] = value; }
        }

        public Pixel LeftMiddle
        {
            get { return m_aNeighbour[3]; }
            set { m_aNeighbour[3] = value; }
        }

        public Pixel MiddleMiddle
        {
            get { return this; }
            //set { m_aNeighbour[4] = value; }
        }

        public Pixel RightMiddle
        {
            get { return m_aNeighbour[4]; }
            set { m_aNeighbour[4] = value; }
        }

        public Pixel LeftBottom
        {
            get { return m_aNeighbour[5]; }
            set { m_aNeighbour[5] = value; }
        }

        public Pixel MiddleBottom
        {
            get { return m_aNeighbour[6]; }
            set { m_aNeighbour[6] = value; }
        }

        public Pixel RightBottom
        {
            get { return m_aNeighbour[7]; }
            set { m_aNeighbour[7] = value; }
        }

        public Pixel[] Neighbours
        {
            get { return m_aNeighbour; }
            set { m_aNeighbour = value; }
        }
    }

@Herbivore:

Für ein Modell in Deinem Sinne schlage ich vorerst vor, dass man die Nachbarschaft mit Offsets angibt á la Indexer:

Pixel an Stelle(1,1)
n[-1,0] wäre dann das Pixel (0,1)

eine Direkte Nachbarschaft wäre dann definiert durch:

Definition: ...von links oben im Uhrzeigersinn herum...:


n[-1,-1]  n[0,-1] n[1,-1]
n[-1,0]   Pixel     n[1,0]
n[-1,1]   n[0,1]   n[1,1]

EDIT:

Ausgehend von einem gewissen Pixel könnte dieser z.B. als Default-Pixel für eine Generierung der Neighbours benutzt werden, d.h.:

Wir zeichnen z.B. in eine leere Bitmap einen grünen Kreis, der den Mittelpunkt p hat.
Jetzt scannen wir alle Punkte die grün sind im Kreisbereich (für den Anfang reicht der Innenkreis für ein Quadrat (Zeile für Zeile). Dann können wir für jeden Pixel das Offset bestimmen. Das ist die Nachbarschaft.

Aber in diesem Sinne, frage ich mich auch, wie performant bekommt man das hin.
Auf jeden Fall gibt es immer (ab einer 3x3 Nachbarschaft) Überschneidungen beim Pixel lesen, wenn man JEDES Pixel bearbeitet aufgrund der Nachbarn.

Das soweit um nur eine Möglichkeit zu nennen.

21.01.2010 - 14:49 Uhr

Konkret ist es so:

012
7P3
654

P ist das Pixel, 0-7 sind die 8 Indizes der direkten Nachbarn.

Das entspricht auch der Benennung (Benennung mit Indizes):

LeftTop = 0, MiddleTop = 1, RightTop =2
LeftMiddle = 3, MiddleMiddle = this, RightMiddle = 4,
LeftBottom = 5, MiddleBottom = 6, RightBottom = 7

21.01.2010 - 13:52 Uhr

@Jack30Lena: 😉 Ok, einverstanden.

@Herbivore:

Momentan ist es so, dass das Objekt den Zugriff auf die direkten Nachbarn bietet.

also so:

()**
*P

***
(Abb.1)

um so etwas zu realisieren:

*****
*****
*P*
*****
*****
(Abb. 2)

muss in die einzelnen Richtungen momentan- ich nenne es mal - gewalkt werden.

d.h. um von p nach p** zu kommen muss man momentan:

p.RightMiddle.RightMiddle oder p[index][index] benutzen (weiß den index nicht mehr auswendig)

d.h. die Umgebung von Abb. 1 ist wenn p vom typ pixel ist, durch die Menge und wir von p ausgehen:

p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8] (im Uhrzeigersinn von Links oben angefangen (*)

gegegeben.

In Abb. 2. brauchen wir entsprechend für die äußersten Pixel mehr indizes:

(*) *
P

* *
die äußeren pixel sind dann z.B. durch p[0][0] (*) usw.

Hoffe ich hab mich nicht vertan und es ist verständlich was ich meine.

Ich denke das performant hinzubekommen ist möglich.

@Jack30Lena: Was denkst du dazu?

@Herbivore: Du würdest also ein Modell mit mehreren möglichen Nachbarn in eine Richtung vorschlagen? Zumindest geht IMHO dein Pseudo-Code-Beispiel davon aus.

Ich bin bisher nur von einem Modell mit den 8 direkt zugänglichen Pixelnachbarn ausgegangen,d.h. für ein Bild an der Stelle(0,0) existiert nur:

P*
**

EDIT (zur klareren Verständlichkeit):
mehr DIREKTE Nachbarn kann es hier ja nicht geben.

für einen Pixel weiter unten am linken Rand gilt:

**
p*
**

EDIT: mir fällt da noch etwas interessantes ein, was ist, wenn man so gesehen, das ganze Bild als Netzwerk, vielleicht sogar als neuronales Netzwerk betrachtet und diesem ein paar Regelen einpflanzt?! (also quasi die Datenstruktur andersrum aufgerollt wie sonst...)