Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
LowLevelGraphicsLibrary
ViperNeo
myCSharp.de - Member



Dabei seit:
Beiträge: 370
Herkunft: Darmstadt

beantworten | zitieren | melden

du hast geschrieben das du eine gekürzte version hier online gestellt hast. gibt es eine möglichkeit die volle version der library zu bekommen? ich finde das projekt super und würde die lib gerne in mein projekt einbetten.

grüße viperneo
private Nachricht | Beiträge des Benutzers
dr4g0n76
myCSharp.de - Experte

Avatar #avatar-1768.jpg


Dabei seit:
Beiträge: 3047
Herkunft: Deutschland

Themenstarter:

beantworten | zitieren | melden

Nach Weihnachten, werde ich diese Version veröffentlichen:


Dann können einige dieser Extraktoren benutzt werden.

- Impainter: kann benutzt werden, um ein Bild zu restaurieren
- Freistellungstool: kann benutzt werden, um Bereiche eines Bildes über eine Maske freizustellen

- AutoCrop: Wird benutzt, um ein Bild vollautomisch auszuschneiden (unwichtige Bereiche werden abgeschnitten)

Bei Vorschau wird ein rotes Rechteck in das Bild eingeblendet.

- Color-Blob-Extraktor: Schon bekannt von dem Knopf links unten. ;-)

- Objekt-Extraktor: Das Herzstück des Projekts (deswegen hab ich eigentlich mal das ganze angefangen in dieser Dimension auszuarbeiten)

Wenn der Objekt-Extraktor RICHTIG(!) funktioniert können in einem beliebigen Bild,
mittels des angewendeten von mir entwickelten One-Pass-Verfahrens, Objekte vollautomatisch extrahiert werden.
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von dr4g0n76 am .
Attachments
Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.
private Nachricht | Beiträge des Benutzers
digi333
myCSharp.de - Member



Dabei seit:
Beiträge: 302

beantworten | zitieren | melden

Tolle Funktionen... einige sind ja so auch in der AForge drinne von CodeProject.

Du solltest vielleicht auch ein SVN anlegen für neue Versionen. Wenn zum Beispiel die Funktionen geupdated werden mit und die SetPixel und GetPixel weg sind.

Gruß,
Digi333
private Nachricht | Beiträge des Benutzers
ErfinderDesRades
myCSharp.de - Experte

Avatar #avatar-3151.jpg


Dabei seit:
Beiträge: 5409

beantworten | zitieren | melden

ich krittel mal ein bischen herum.
zunächst die Test-Anwendung: ich finde, man bräuchte was, wo man vorher und nachher nebeneinander vergleichen kann, vlt sogar Tabpages, wo man verschiedene Filter-Ausgaben durchblättern kann.
Und das bei der Ausgabe angegeben ist, was man eingegeben hat, am liebsten was mit Abspeichern.
also ich jedenfalls hab nach 3 Sekunden vergessen, welches MenuItem ich geklickst hatte, und was in die EingabeMaske eingegeben.

Ich hab grad angemacht, ein Bild geladen, und dann mal bei den Filtern Binarisierung-BarCode geklickst, was immer das sein mag, darüber hoffte ich ja was zu erfahren.
Da geht ein Dialog auf, da soll ich einen Grenzwert eingeben, und checken (oder nicht), ob "nur diesen grenzwert".

Damit kann ich überhaupt nichts anfangen, was denn für ein Grenzwert?
habich 142 eingegeben.
Dann steht die Anwendung, und nach ca. 10s kommt ein schwarzweiß-Bild, bei dem scheinbar die Graustufen entfernt sind.
Vermutlich ist das die Binarisierung, dasses nurnoch schwarz-weiß gibt, aber warum Barcode? - na, so heißt es eben.

Nächster Test: Binarisierung-treshold MinMax - da muß man keinen Grenzwert angeben, aber die Anwendung steht für 20s.

Dafür gibts dann aber eine Ausgabe, bei der das Bild viel besser wieder zu erkennen ist - ein wirklich interessanter Filter. Blos wie gesagt - ich kann die Ausgabe nicht mit der Eingabe vergleichen, das ist schade.

Guck ich mal in den Code, da sehe ich gleich, warum das immer so lange steht: ist voll mit GetPixel und SetPixel. Wo ich denken täte, in etwas, was sich "LowLevel..." nennt, haben die nix verloren.
Man kann doch sicherlich alle Bildformate nach 24RGB umwandeln (bei Transparenz-Unterstützung 32ARGB), die Bitmap locken, und auf einem Array mit den Farbwerten arbeiten. Für 24RGB habich das mal selbst gemacht, und habe den Scan-Pointer in ein 2-dim ArbeitsArray kopiert, da kann man dann direkt mit x und y auf jeden Farbwert jedes Pixels zugreifen. Ich müsste mal probieren, ob mans nicht sogar in ein 3-dim Array bekommt, dann könnte man RGB quasi als Z-Achse auffassen.
Etwas, was danach aussieht, ist ja enthalten "UnsafeBitmap", nur wird es scheinbar nicht verwendet.

Als nächstes hab ich in die Convolutions geguckt, und scheint doch immer noch so, dass für jeden Filter eine eigene Klasse gebaut ist, dabei ist es immer derselbe Filter, nur mit verschieden beschickter 3*3-Matrix.
Sowas kann man doch variabel programmieren, dass im Button-Handler dann die Matrix beschickt wird, nicht für jeden filter eine extra-Klasse.

Einige Convolutions gehen dann auch wieder andere Wege, "SimpleConvolution" zB. wendet Bitmap-Locking an, und greift auf die Farbwerte direkt zu, aber eben ohne die "UnsafeBitmap" zu verwenden, wozu ist die denn nun eiglich da?

Oder im Ordner "Edges" guck ich den ersten an, da ist der Code komplett auskommentiert.
Und im 2. Edges-Filter, namens "Compass" findet sich wieder etwas, was sehr nach Convolution-Filter aussieht, allerdings sind es 688 Zeilen, die sich endlos wiederholen, und Get/SetPixel ist wieder dabei.
Zu Get/SetPixel habich mich schon geäußert, nun, solche "Compass"-Code-Wiederholungs-Wüsten sollte man aber auch unbedingt parametrisieren, also dass am Ende ein Algo mit geeigneten Parametern beschickt wird, anstatt für jede Variante den gleichen Algo re-implementieren.

In Corners.Moravec fund ich diese Minimum-Funktion:



        private int Min(int x, int y, int[,,] aSum)
        {
            int[] aInt = new int[8];
            for (int i = 0; i < 8;i++ )
            {
                aInt[i] = aSum[x,y,i];
            }
            Array.Sort(aInt);
            return aInt[0];
        }
Verstehe ich das richtig, dass alle 8 Werte in ein int-Array geschrieben werden, dieses sortiert, und dann das oberste Element zurückgegeben? - isnichdeinErnst, odr?

Das mit den BarCodes habichjetzt auch nochmal nachgeguckt



        public override void Execute(Bitmap _bitmap) {
           Bitmap bitmap = _bitmap;
           List<Color> aColor = new List<Color>();
           int y = 0;
           int x = 0;

           int nCount = 0;
           aColor.Add(bitmap.GetPixel(x, y));
           aColor.Add(bitmap.GetPixel(x, y));
           nCount++;

           Color colorToSet = Color.Transparent;
           for(y = 0; y < bitmap.Height; y++) {
              for(x = 0; x < bitmap.Width; x++) {
                 List<Color> aColorLine = new List<Color>();
                 Color color = bitmap.GetPixel(x, y);
                 aColor.Add(color);
                 aColorLine.Add(color);
                 Color colorPrev = aColor[nCount - 1];
                 Color colorCurrent = aColor[nCount];

                 Color colorAvg = ColorFunctions.AverageColor(aColorLine);
                 int nRGBSum = ColorFunctions.RGBChannelSum(colorAvg);
                 if(bOnlyThreshold) {
                    if(nRGBSum == nThreshold) {
                       colorToSet = Color.White;
                       aColorLine.Clear();
                    } else {
                       colorToSet = Color.Black;
                    }
                 } else {
                    if(nRGBSum > nThreshold) {
                       colorToSet = Color.White;
                       aColorLine.Clear();
                    } else {
                       colorToSet = Color.Black;
                    }
                 }
                 bitmap.SetPixel(x, y, colorToSet);
                 nCount++;
              }
           }
        }
Interessant.
Da wird von den bisher durchlaufenen Pixeln ein Durchschnittspixel gebildet, und wenn die Summe der Farbwerte des Durchschnittspixels den Schwellwert (Threshold) überschreitet, wird weiß gesetzt, und die Liste der durchlaufenen Pixel gelöscht. (Ich hoffe, richtig verstanden zu haben, bischen Kommentation wäre nicht schlecht).
Welche Funktion hat aber die zweite Liste, "aColor"?

Forms.FormConvolution kann unnötigerweise im Designer nicht geöffnet werden. Das liegt am Aufruf von

         this.CenterToParent();
innerhalb von InitializeComponent(), wohl weil der Designer .CenterToParent() nicht ausführen kann.
Jedenfalls eine Verlegung des Aufrufes in den Konstruktor, nach InitializeComponent() schafft Abhilfe.

Was hat es mit diesem Interface auf sich?


    public interface ICommand
    {
        string Description { get; set; }
        object Owner { get; set; }
        void Run(object sender, EventArgs e);
    }
Description: wird im ganzen Code nirgends gesetzt
Owner: desgleichen
Run: Was sollen die Argumente sender und e? Die werden zwar übergeben, aber nirgends dann auch verwendet - ich wüsste auch nicht, was ein filter mit einem toolstripMenuItem anfangen sollte, und e ist immer empty.

Auch die vielen Actions verstehe ich nicht. ist auch immer wieder ganz ähnlicher Code


namespace ImageRecognition2.Action
{
    class ActionEdge : AbstractCommand
    {
        protected PictureBox m_PictureBox = null;
        private short m_shType = -1;

        public ActionEdge(PictureBox _pictureBox, short _shType)
        {
            m_PictureBox = _pictureBox;
            m_shType = _shType;
        }

        public override void Run(object sender, EventArgs e)
        {
            FormParameter parameter = new FormParameter();
            if (parameter.ShowDialog() == DialogResult.OK)
            {
                Bitmap bitmap = (Bitmap)m_PictureBox.BackgroundImage;
                new EdgeDetectConvolution(m_shType, (byte)parameter.nValue).Execute(bitmap);
            }
        }    
    }
}


namespace ImageRecognition2.Action
{
    public class ActionDither : AbstractCommand
    {
        private PictureBox m_PictureBox = null;

        public ActionDither(PictureBox _pictureBox)
        {
            m_PictureBox = _pictureBox;
        }

        public override void Run(object sender, EventArgs e)
        {
            Bitmap bitmap = (Bitmap)m_PictureBox.BackgroundImage;
            BaseImageFilter filter = new Dither();
            filter.Execute(bitmap);
            Bitmap bitmapDithered = filter.Bitmap;
            m_PictureBox.BackgroundImage = bitmapDithered;
        }
    }
}
Ist zwar ähnlich, aber nicht gleich - warum nicht? beide Filter erben von einer gemeinsamen BasisFilterKlasse - trotzdem wird der EdgeFilter nur executet, beim Dither aber noch zusätzlich filter.Bitmap abgerufen.?.

Die Run-Methode hat dieselbe Signatur wie ein üblicher Eventhandler, und ich fänds glaub einfacher, den Code auch tatsächlich in einen echten Eventhandler reinzuschreiben, statt des in Form1 gegangenen Umwegs über eine Methode SetEventHandler


        public void SetEventHandler(ToolStripMenuItem _item, ICommand _icommand)
        {
            _item.Tag = _icommand;
            _item.Enabled = true;
            _item.Click += delegate(object sender, EventArgs e)
            {
                ExecuteAction(_item.Tag,EventArgs.Empty);
                this.pictureBox1.Invalidate();
                Debug.WriteLine(_icommand.Description);
            };
        }
Also, ich mach Schluß für heut, hofflich habich dich nicht zu sehr geärgert.
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von ErfinderDesRades am .
Der frühe Apfel fängt den Wurm.
private Nachricht | Beiträge des Benutzers
ErfinderDesRades
myCSharp.de - Experte

Avatar #avatar-3151.jpg


Dabei seit:
Beiträge: 5409

beantworten | zitieren | melden

ja, geht tatsächlich, die BitmapScan als 3-dim - Pointer aufzufassen. Wenn man dann die Matrix als 2-dim Array auffasst, ergibt sich z.B. ein sehr übersichtlicher Convolution-Filter, ich habs leider nur in VB


   Private Sub ApplyCurrentFilter()
      'Über jedes Pixel wird eine 3*3-Gewichtungs-Matrix gelegt, die darunter liegenden Werte
      '! gewichtet aufsummiert. Die Gesamtsumme wird durch den Divisor geteilt, um den
      '! Durchschnitts-Wert wieder herzustellen. 
      'Heben sich positive und negative Gewichtungen auf (Summe der Matrix = 0) so wird die
      '! Durchschnitts-Helligkeit des Bildes gewährleistet durch Addition eines Offsets von 127.
      If FilterBindingSource.Position < 0 Then Return
      Dim Filter As FilterRow = GetRow(Of FilterRow)(Me.FilterBindingSource.Current)
      Dim Img As Image = DirectCast(cmbSourcePic.SelectedValue, Image)
      Dim Helper As New PixelHelper(Img, PixelFormat.Format24bppRgb, ckGray.Checked)
      'Filter-Daten
      Dim Matrix As SByte(,) = Me.UclMatrixGrid1.GetMatrix
      Dim Offset As Short = Filter.Offset
      Dim Divisor As Single = Filter.Divisor
      '3-dim Pixel-Arrays
      Dim ReadPixels As Byte(,,) = Helper.ReadPixels
      Dim WritePixels As Byte(,,) = Helper.CreateWritePixels(PixelFormat.Format24bppRgb)
      Dim YUbound As Integer = Img.Height - 1
      Dim XUbound As Integer = Img.Width - 1
      'die Hauptschleife läßt die Ränder aus, da die Anwendung der Matrix auf Randpixel
      '! zu Array-Überschreitungen führt (s. Start- und End-Werte von Y, X).
      For Y As Integer = 1 To YUbound - 1
         For X As Integer = 1 To XUbound - 1
            For Z As Integer = 0 To 2 'auf der "Z-Achse" liegen die 3 Farbwerte 
               Dim WeightedSum As Double = 0
               For mtrY As Integer = 0 To 2
                  For mtrX As Integer = 0 To 2
                     Dim rpY As Integer = Y + mtrY - 1
                     Dim rpX As Integer = X + mtrX - 1
                     ' rpY, rpX, die Indizees der ReadPixel, beinhalten den Offset des Matrix-Punktes,
                     '°der grad abgefragt wird
                     WeightedSum += ReadPixels(rpY, rpX, Z) * Matrix(mtrY, mtrX)
                  Next
               Next
               WeightedSum = ClipBetween(0.0, WeightedSum / Divisor + Offset, 255.0)
               WritePixels(Y, X, Z) = CByte(WeightedSum)
            Next
         Next
      Next
      'BackgroundImage austauschen - der PixelHelper erstellt aus den WritePixels die Bitmap
      ExchangeDisposable(Me.SplitContainer1.Panel2.BackgroundImage, Helper.GetResultBitmap)
   End Sub
- aus LowLevelGraphics.Filter.Convolution3x3



        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);
        }
dabei sollte es in c# noch viel cooler sein, weil da muß man nicht in ein Array umkopieren, sondern kann Scan0 gleich als (byte ***) auffassen.
Dreimal dieselbe sehr lange Zeile zur Berechnung jedes der 3 Farbwerte ist jedenfalls nicht nötig, und wiederspricht dem DRY-Grundsatz (don't repeat yourself) von Clean Code Developer (CCD)

Und ich denke eben, so ein 3-D-Pointer ließe sich für fast alle Filter einheitlich verwenden - Get/Set-Pixel muß weg.
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von ErfinderDesRades am .
Der frühe Apfel fängt den Wurm.
private Nachricht | Beiträge des Benutzers
ErfinderDesRades
myCSharp.de - Experte

Avatar #avatar-3151.jpg


Dabei seit:
Beiträge: 5409

beantworten | zitieren | melden

Habe jetzt fleißig dran rumgeforscht, und (als erstes) gemerkt, dass das mit mehrdim Pointern nicht geht.
Und die superlangen Additionen eignen sich hervorragend als Optimierung. Elegant wäre gewesen, die Matrix in einer geschachtelten Schleife zu durchlaufen (wie im VBCode gezeigt), aber das ist 5 mal langsamer, als alle 9 Durchgänge in einer einzigen Addition aneinander zu hängen.
Ich find, Optimierungen sollte man kommentieren, weil der Code sieht üblicherweise grauenhaft und umständlich aus, und wenn man nicht weiß, dasses eine Optimierung ist, will man das natürlich gleich vereinfachen.
Ist auch ein Bug drin, nämlich vor und nach der X-Schleife musstenoch die Pointer um 3 hochsetzen, da du die Randpunkte ja nicht bearbeitest.
Der Bug führt zu falsch addressierten Pixeln, die sich im Filter-Ergebnis als Diagonale Linie zeigen, von obere rechte Ecke an.
Sieht man zB. beim Laplace-Filter.
Der frühe Apfel fängt den Wurm.
private Nachricht | Beiträge des Benutzers
dr4g0n76
myCSharp.de - Experte

Avatar #avatar-1768.jpg


Dabei seit:
Beiträge: 3047
Herkunft: Deutschland

Themenstarter:

beantworten | zitieren | melden

@ErfinderDesRades:

ich krittel mal ein bischen herum.
Zitat
zunächst die Test-Anwendung: ich finde, man bräuchte was, wo man vorher und nachher nebeneinander vergleichen kann, vlt sogar Tabpages, wo man verschiedene Filter-Ausgaben durchblättern kann.
Und das bei der Ausgabe angegeben ist, was man eingegeben hat, am liebsten was mit Abspeichern.
also ich jedenfalls hab nach 3 Sekunden vergessen, welches MenuItem ich geklickst hatte, und was in die EingabeMaske eingegeben.

Mdi Anwendung mit mehreren Fenstern ist jedenfalls wirklich eine gute Idee.
Intern wird durch die Actions sowieso gemerkt, welche Aktion zuletzt ausgeführt werde, muss ich noch überlegen ob und wenn ja, wie ich das mache.
Zitat
Ich hab grad angemacht, ein Bild geladen, und dann mal bei den Filtern Binarisierung-BarCode geklickst, was immer das sein mag, darüber hoffte ich ja was zu erfahren.
Da geht ein Dialog auf, da soll ich einen Grenzwert eingeben, und checken (oder nicht), ob "nur diesen grenzwert".

Damit kann ich überhaupt nichts anfangen, was denn für ein Grenzwert?
habich 142 eingegeben.
Dann steht die Anwendung, und nach ca. 10s kommt ein schwarzweiß-Bild, bei dem scheinbar die Graustufen entfernt sind.
Vermutlich ist das die Binarisierung, dasses nurnoch schwarz-weiß gibt, aber warum Barcode? - na, so heißt es eben.

Vielleicht weil es helfen könnte einen Barcode zu erkennen!? Also willkürlich sind die Namen für die Filter jedenfalls nicht gewählt.
Zitat
Nächster Test: Binarisierung-treshold MinMax - da muß man keinen Grenzwert angeben, aber die Anwendung steht für 20s.

Erstens: Die Filter sind noch nicht alle optimiert,
deswegen, lies bitte auch alles was hier steht:
Zitat

EDIT: Vorabversion mit neuen Filtern hochgeladen. Bisher ungetestet.
Code an vielen Stellen jetzt gecleant(er).

Als Dateianhang am Ende dieses Beitrags verfügbar:



Habe heute ein erstes Prerelease veröffentlicht. Damit man sich den Code schon mal anschauen kann. Und nein, der Code bleibt nicht so. An vielen Stellen wird es noch Änderungen und Optimierungen geben.

Die Syntax der Filter bleibt so.

Es wird noch ein ExecuteCloned hinzukommen, bei dem man das bearbeitete Bitmap als Ergebnis erhalten wird und das Original-Bild bleibt dabei wie es ist.
Zitat
Dafür gibts dann aber eine Ausgabe, bei der das Bild viel besser wieder zu erkennen ist - ein wirklich interessanter Filter. Blos wie gesagt - ich kann die Ausgabe nicht mit der Eingabe vergleichen, das ist schade.

Das wird sich ändern.
Zitat
Guck ich mal in den Code, da sehe ich gleich, warum das immer so lange steht: ist voll mit GetPixel und SetPixel. Wo ich denken täte, in etwas, was sich "LowLevel..." nennt, haben die nix verloren.
Man kann doch sicherlich alle Bildformate nach 24RGB umwandeln (bei Transparenz-Unterstützung 32ARGB), die Bitmap locken, und auf einem Array mit den Farbwerten arbeiten. Für 24RGB habich das mal selbst gemacht, und habe den Scan-Pointer in ein 2-dim ArbeitsArray kopiert, da kann man dann direkt mit x und y auf jeden Farbwert jedes Pixels zugreifen. Ich müsste mal probieren, ob mans nicht sogar in ein 3-dim Array bekommt, dann könnte man RGB quasi als Z-Achse auffassen.
Etwas, was danach aussieht, ist ja enthalten "UnsafeBitmap", nur wird es scheinbar nicht verwendet.

Bitte? Natürlich wird das verwendet aber noch nicht überall...
Zitat
Als nächstes hab ich in die Convolutions geguckt, und scheint doch immer noch so, dass für jeden Filter eine eigene Klasse gebaut ist, dabei ist es immer derselbe Filter, nur mit verschieden beschickter 3*3-Matrix.
Sowas kann man doch variabel programmieren, dass im Button-Handler dann die Matrix beschickt wird, nicht für jeden filter eine extra-Klasse.

Die 3x3 Convolution ist ein Relikt von der ursprünglichen LowLevelGraphicsLibrary die am 07.07.2005 verwendet wurde, den Filter möchte ich denen die vielleicht schon Code mit der Lib aufgebaut haben nicht unbedingt wegnehmen, möglich ist aber das
er intern die anderen Convolutions benutzt, da hier ja mehrere Klassen inzwischen existieren.
Zitat
Einige Convolutions gehen dann auch wieder andere Wege, "SimpleConvolution" zB. wendet Bitmap-Locking an, und greift auf die Farbwerte direkt zu, aber eben ohne die "UnsafeBitmap" zu verwenden, wozu ist die denn nun eiglich da?

Erstens: Sowohl UnsafeBitmap als auch SimpleConvolution wenden BitmapLocking an, nur dass bei SimpleConvolution die Pixel der Reihe nach iteriert werden (hintereinander), wobei es mit UnsafeBitmap möglich ist eine 2dimensionale Schleife
á la


UnsafeBitmap bitmap = new UnsafeBitmap(_bitmap);
for y...
{
   for x... 
   {
        Color color = bitmap.GetPixel(x,y);
   }
}
Zitat
Oder im Ordner "Edges" guck ich den ersten an, da ist der Code komplett auskommentiert.
Und im 2. Edges-Filter, namens "Compass" findet sich wieder etwas, was sehr nach Convolution-Filter aussieht, allerdings sind es 688 Zeilen, die sich endlos wiederholen, und Get/SetPixel ist wieder dabei.

Dann sieh Dir bitte mal an, warum Crimmins Speckle Removal so funktioniert und warum es so heißt. Außerdem: Lies Dir bitte die Kommentare im Code durch:

 
   /// This is crimmins speckle removal. Momentarily totally unoptimized.
    /// Crimmins is an operator that applies the Crimmins Speckle Reduction 
    /// Algorithm.
Zitat
Zu Get/SetPixel habich mich schon geäußert, nun, solche "Compass"-Code-Wiederholungs-Wüsten sollte man aber auch unbedingt parametrisieren, also dass am Ende ein Algo mit geeigneten Parametern beschickt wird, anstatt für jede Variante den gleichen Algo re-implementieren.

Und nochmals: es ist IMMER NOCH eine Vorabversion.
Zitat
Habe jetzt fleißig dran rumgeforscht, und (als erstes) gemerkt, dass das mit mehrdim Pointern nicht geht.
Und die superlangen Additionen eignen sich hervorragend als Optimierung. Elegant wäre gewesen, die Matrix in einer geschachtelten Schleife zu durchlaufen (wie im VBCode gezeigt), aber das ist 5 mal langsamer, als alle 9 Durchgänge in einer einzigen Addition aneinander zu hängen.
Ich find, Optimierungen sollte man kommentieren, weil der Code sieht üblicherweise grauenhaft und umständlich aus, und wenn man nicht weiß, dasses eine Optimierung ist, will man das natürlich gleich vereinfachen.

Na fein, schön dass DU es selbst herausgefunden hast.
Die Fehler sind mir übrigens bekannt. Aber danke für den Hinweis. Es sind auch noch viel mehr Fehler in der Library. Deshalb wird es auch von nun ab ne Weile dauern bis wieder eine neue Version rauskommt.
Zitat
Ist auch ein Bug drin, nämlich vor und nach der X-Schleife musstenoch die Pointer um 3 hochsetzen, da du die Randpunkte ja nicht bearbeitest.
Der Bug führt zu falsch addressierten Pixeln, die sich im Filter-Ergebnis als Diagonale Linie zeigen, von obere rechte Ecke an.
Sieht man zB. beim Laplace-Filter.

Dass es ab und zu zu der berühmt-berüchtigten Diagonale kommt, ist mir schon längst bekannt, es ist nicht nur beim Laplace Filter ab und zu der Fall.
Wenn Du jetzt noch weiter rausfindest, siehst Du dass GetPixel und SetPixel an fast allen Stellen von einer Klasse namens UnsafeBitmap benutzt wird.

Und auch dass es einige Klassen ibt, die gar nicht benutzt werden usw.

Aber um jetzt mal langer Rede langen Sinn einfach sich selbst zu überlassen:

Was möchtest Du denn programmieren oder ausprobieren? Bin einfach neugierig für was Du die Lib momentan verwendest.

Gruß, dr4g0n76
Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.
private Nachricht | Beiträge des Benutzers
dr4g0n76
myCSharp.de - Experte

Avatar #avatar-1768.jpg


Dabei seit:
Beiträge: 3047
Herkunft: Deutschland

Themenstarter:

Angekündigt:

beantworten | zitieren | melden

Diese Features werden mit dem nächsten Upload veröffentlicht:

- Kuwahara Filter hinzugefügt (Rauschverringerungsfilter der Kanten erhält)
- Photoshopmodus-Filter (Farbig abwedeln, Multiplizieren, Weiches Licht, Hartes Licht, Umgekehrt Multiplizieren usw...)
- Bernsen Operator
- Lipschitz Filter
- Windowed Sinc Filter
- Non Maximum Suppression
- ChannelDifference Filter hinzugefügt (Unterschiede in Kanälen
- EntropyThreshold
- EnergyMap
- EntropyMap

- Lambda-Erweiterung LambdaPixel (Bitmap, x,y, Color, Rectangle Area)
Damit können auch auf ganz einfache Weise Flips u.ä. realisiert werden

- Bitmap 2 LINQ (Bitmap kann aufgrund Neighbouringsfunktionen als LINQ Objekt zurückgegeben werden)


Die neue Version gibt's diesmal erst, wenn alles andere auch durchgetestet sind.
Außerdem werden einige Filter wesentlich verschnellert werden.

- Einführung von Neighbouring zur eigenen Benutzung.
Durch ein GetNeighbour kann ein Window mit Größe s direkt erhalten werden:

Bsp. für die Neighbour von P für Window mit s = 3:
***
*
P*
***


Bsp. für die Neighbours von P für Window mit s = 5:

*****
*****
**
P**
*****
*****
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von dr4g0n76 am .
Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.
private Nachricht | Beiträge des Benutzers
-Hades-
myCSharp.de - Member



Dabei seit:
Beiträge: 173
Herkunft: Deutschland NRW

beantworten | zitieren | melden

Hi,

bin gerade auf diesen Post gestoßen. Hast du schon (neben Grayscale) einen Brightness- und Contrastfilter implementiert? Das ist nämlich gerade genau das was ich suche. Wenn ja, arbeitet der schon mit Scan0 ? Das ganze muss so schnell wie möglich laufen damit es für mich ineteressant ist.

In jedem Fall aber ein großes Lob an dich, das ganze sieht doch sehr vielversprechend aus!

Gruß -Hades-
private Nachricht | Beiträge des Benutzers
dr4g0n76
myCSharp.de - Experte

Avatar #avatar-1768.jpg


Dabei seit:
Beiträge: 3047
Herkunft: Deutschland

Themenstarter:

beantworten | zitieren | melden

Zitat
Hast du schon (neben Grayscale) einen Brightness- und Contrastfilter implementiert?
Das ist nämlich gerade genau das was ich suche. Wenn ja, arbeitet der schon mit Scan0 ? Das ganze muss so schnell wie möglich laufen damit es für mich ineteressant ist.

Die Filter befinden sich in dem Namespace LowLevelGraphics.Filter und heißen:

und heißen:

GrayScale,
Brightness,
Contrast

Alle benutzen Scan0.

Anwendungsbeispiele:


new GrayScale().Execute(bitmap);
new Brightness(10).Execute(bitmap);
new Contrast(10).Execute(bitmap);

usw.
Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.
private Nachricht | Beiträge des Benutzers
dr4g0n76
myCSharp.de - Experte

Avatar #avatar-1768.jpg


Dabei seit:
Beiträge: 3047
Herkunft: Deutschland

Themenstarter:

Ausblick für neue Version:

beantworten | zitieren | melden

Diese Features werden mit dem nächsten Upload veröffentlicht:

- Kuwahara Filter hinzugefügt (Rauschverringerungsfilter der Kanten erhält)
- Photoshopmodus-Filter (Farbig abwedeln, Multiplizieren, Weiches Licht, Hartes Licht, Umgekehrt Multiplizieren usw...)
- Bernsen Operator
- Lipschitz Filter
- Windowed Sinc Filter
- Non Maximum Suppression
- ChannelDifference Filter hinzugefügt (Unterschiede in Kanälen z.B. als Graustufenbilddarstellen)
- EntropyThreshold
- EnergyMap
- EntropyMap

Die neue Version gibt's diesmal erst, wenn alles andere auch durchgetestet sind.
Außerdem werden einige Filter wesentlich verschnellert werden.

- Einführung von Neighbouring zur eigenen Benutzung.
Durch ein GetNeighbour kann ein Window mit Größe s direkt erhalten werden:

Bsp. für die Neighbour von P für Window mit s = 3:
***
*
P*
***


Bsp. für die Neighbours von P für Window mit s = 5:

*****
*****
**
P**
*****
*****
Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.
private Nachricht | Beiträge des Benutzers
digi333
myCSharp.de - Member



Dabei seit:
Beiträge: 302

beantworten | zitieren | melden

Das mit den Neighbouring und deine zukünftigen Filter finde ich gut... das brauch man häufig. Ich würde mich freuen, wenn du deine GUI etwas besser benennst, da ich manchmal probiere und dann nicht weiß was "Test 1" oder "2" machen soll. Dennoch ein schönes Projekt. Vielleicht solltest du ein SVN starten indem Leute deinen SourceCode optimieren.
private Nachricht | Beiträge des Benutzers
dr4g0n76
myCSharp.de - Experte

Avatar #avatar-1768.jpg


Dabei seit:
Beiträge: 3047
Herkunft: Deutschland

Themenstarter:

beantworten | zitieren | melden

Hallo digi333,

danke für deine Anregungen.
Es wird diesmal etwas dauern bis die neue Library verfügbar sein wird, da ich mir jetzt zum Ziel gesetzt habe, alles noch einmal durchzutesten, im Hinblick auf Benutzbarkeit und Geschwindigkeit sowie auf Funktion, denn was bringt einem z.B. ein

Canny-Edge-Filter

wenn er nicht richtig funktioniert?

Danke für Deine Anregungen. Ich werde diese auf jeden Fall teilweise mit aufnehmen und ins Projekt einbringen.

Das Interface wird so bald ich Zeit habe (aber erst nach den o.g. Tests und Änderungen) in ein MDI Interface umgewandelt werden.

Außerdem folgt, wenn alles funktioniert, eine Beschreibung. Die benötige ich sowieso auch für mich selbst.
Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.
private Nachricht | Beiträge des Benutzers
digi333
myCSharp.de - Member



Dabei seit:
Beiträge: 302

beantworten | zitieren | melden

Du machst ja viel mit Segmentierung und Farbräume. Es gibt einige sehr schöne Segmentierungsalgorithmen in Java die es in C# noch nicht gibt. Ich fand die folgende Segmentierung sehr interessant. Der Nutzer markiert mit der rechten Maustaste den Vordergrund und mit der linken Taste den Hintergrund und aufbauend auf Lab segmantiert er dann. Das würde ich gerne noch sehen von dir. Die Funktionen und Tools hast du. Schau es dir mal in Java an. openSource auf link.

Hab schon viele Fragen und Wünsche in C# nach dem Algorithmus gefunden.
private Nachricht | Beiträge des Benutzers
digi333
myCSharp.de - Member



Dabei seit:
Beiträge: 302

beantworten | zitieren | melden

Ab wann kann man mit der neuen Version rechnen?
private Nachricht | Beiträge des Benutzers
dr4g0n76
myCSharp.de - Experte

Avatar #avatar-1768.jpg


Dabei seit:
Beiträge: 3047
Herkunft: Deutschland

Themenstarter:

beantworten | zitieren | melden

Zitat
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:
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von dr4g0n76 am .
Attachments
Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.
private Nachricht | Beiträge des Benutzers
dr4g0n76
myCSharp.de - Experte

Avatar #avatar-1768.jpg


Dabei seit:
Beiträge: 3047
Herkunft: Deutschland

Themenstarter:

beantworten | zitieren | melden

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.
Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.
private Nachricht | Beiträge des Benutzers
dr4g0n76
myCSharp.de - Experte

Avatar #avatar-1768.jpg


Dabei seit:
Beiträge: 3047
Herkunft: Deutschland

Themenstarter:

beantworten | zitieren | melden

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.
Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.
private Nachricht | Beiträge des Benutzers
dr4g0n76
myCSharp.de - Experte

Avatar #avatar-1768.jpg


Dabei seit:
Beiträge: 3047
Herkunft: Deutschland

Themenstarter:

beantworten | zitieren | melden

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.
Dieser Beitrag wurde 8 mal editiert, zum letzten Mal von dr4g0n76 am .
Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.
private Nachricht | Beiträge des Benutzers
dr4g0n76
myCSharp.de - Experte

Avatar #avatar-1768.jpg


Dabei seit:
Beiträge: 3047
Herkunft: Deutschland

Themenstarter:

beantworten | zitieren | melden

Neue Version heute hochgeladen.

Alles von den Videos sollte nachvollzogen werden können.

Viele kleine Änderungen.
Viele Filter korrigiert.

In einige Filter einige Processing_Modes eingebaut u.a. Invert.

s. auch erster Post. die URL mit Party-Crackers
http://www.the-party-crackers.de/Imagerecognition2.rar
Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.
private Nachricht | Beiträge des Benutzers
steffen_dec
myCSharp.de - Member



Dabei seit:
Beiträge: 325

beantworten | zitieren | melden

Hi,

kann deine Lib auch bilder mit mehr als 8bpp verarbeiten?
oder ist alles fix auf 8bpp?

ansonsten tolle arbeit machst du da!

Gruß
Steffen
private Nachricht | Beiträge des Benutzers
dr4g0n76
myCSharp.de - Experte

Avatar #avatar-1768.jpg


Dabei seit:
Beiträge: 3047
Herkunft: Deutschland

Themenstarter:

beantworten | zitieren | melden

@steffen_dec:

So gesehen ist man nicht eingeschränkt. Die Bilder werden intern auf 32 Bit ARGB umgerechnet.

Oder meinst Du das mit den 8 Bit pro channel? mit 8bpp?

Die Farben reichen von 0x000000 bis 0xFFFFFF um ganz genau zu sein.

Da die meisten Filter den Offset count (IncreasePointerOffset und BytesPerPixelCount in Unsafebitmap) berechnen, sollte die Lib so gesehen eigentlich nicht eingeschränkt sein. Ist aber ungetestet.
Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.
private Nachricht | Beiträge des Benutzers
dr4g0n76
myCSharp.de - Experte

Avatar #avatar-1768.jpg


Dabei seit:
Beiträge: 3047
Herkunft: Deutschland

Themenstarter:

beantworten | zitieren | melden

Kleine Nachfrage, was macht ihr mit der Bibliothek?

- Was gefällt euch?

- Was gefällt euch nicht?

- Was fehlt euch noch ganz?


Gebt mir bitte Rückmeldungen für das Projekt, gerne auch per PM.
Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.
private Nachricht | Beiträge des Benutzers
dr4g0n76
myCSharp.de - Experte

Avatar #avatar-1768.jpg


Dabei seit:
Beiträge: 3047
Herkunft: Deutschland

Themenstarter:

beantworten | zitieren | melden

Neue Version auf

Work-In-Progress

(oder siehe Link 1. Post in diesem Thread)

Ich habe mich dazu entschieden hier mal wieder eine Version online zu laden.

Es gibt (schon seit Anfang an) einen grundlegenden Konzeptunterschied zu anderen Frameworks im Programm "ImageRecognition2":

Alle Filter können immer benutzt werden, diese liefern dann aber nicht unbedingt ein Ergebnis, d.h. es kann z.B. BinaryDilation für ein Farbbild aufgerufen werden, ohne dieses vorher binarisiert zu haben. Deswegen erhält man aber keine Exception.
Grund: Es wäre ja möglich, dass wir ein teilbinarisiertes Bild haben. Dann funktioniert der Filter normalerweise an den binarisierten Stellen.
IMHO hat man so mehr Freiheit.

Zitat
Es gibt folgende Änderungen:

Einzelbildbearbeitungsfilter

- Es wurden wieder einige Filter korrigiert (u.a. MorphologieFilter)
- Binarisierungsfilter können jetzt mit verschiedenen Farben betrachtet werden
(z.B. kann bei Close Weiß als Hintergrundfarbe und Schwarz als Vordergrundfarbe betrachtet werden, obwohl das Bild vorher mit Weiß als Vordergrundfarbe
- Einige kleine Änderungen an den Objektextraktorn
- Es gibt jetzt einen frei definierbaren Konvolutionsfilter der auch funktioniert
- SkinningFilter sollte jetzt besser funktionieren
- ColorBlobExtractor benutzt jetzt "UnsafeBitmap" (schneller)
- ContourExtractionTwoSteps benutzt keinen Lambda-Filter mehr, viel schneller, da keine Vor-Kompilierung mehr benötigt wird.
- AnaglyphExtract hinzugefügt
- AnaglyphFilter aktiviert (funktioniert jetzt)
- Depthmapcreation für Stereobilder hinzugefügt
- PerPixelFilter mit Delegate hinzugefügt, dieser kann mit beliebigen einfachen
delegates initialisiert werden, die Delegate Funktion wird dann auf jedes Pixel angewendet
- Lipschitz Filter weiter ausprogrammiert
- SimpleBlobExtractor hinzugefügt (Labelling noch fehlerhaft)
- WindowedSinc Filter weiter ausprogrammiert
- Mehr Filter in der Frequenzdomäne vorgesehen
- ChainCode Filter hinzugefügt
- Color Filter für jeden Farbraum hinzugefügt
- Mit UnsafeBitmap.FromImage können jetzt sowohl PGM, PBM als auch PPM, PCX und TIF geladen werden (noch weitestgehend ungetestet)

- Mit UnsafeBitmap[x,y,channel] kann jetzt ein Pixel gesetzt oder geholt werden (kanalweise)

- Funktion für den Graudurchschnitt gleichgroßer Bilder in einem Ordner

- PixelDivision, Addition, Subtraktion, Modulo usw. funktionieren jetzt (auch vom Testinterface Imagerecognition2 aus) ebenso Bool'sche Operatoren wie NAND, NOR, XOR, OR, AND, NOT usw.

Videofilter

- Videofilter vorgesehen: MotionDetection hinzugefügt
Zitat
In ImageRecognition2:
- Im Interface unter dem Menüpunkt Script sind jetzt alle Filter vorhanden
- Ein paar Funktionen haben eine Maske bekommen á la Photoshop, mit Preview-Funktion
(Es sind zwar schon für fast alle Filter Masken vorprogrammiert, aber diese sind noch längst nicht alle eingebaut.)
- Settings werden gespeichert (Open new window after action usw.)

Viele kleine programmatische Änderungen, wie z.B. private Variablen in protected umgeändert und falls gefehlt, Public Properties hinzugefügt wo benötigt

Was ist geplant?

Funktionalität:

- Bessere Objekterkennungen
- Backprojections
- Histogrammfunktionen
- Bildstatistikfunktionen
- Klassifizierungsfunktionen
- Merkmalsdeskriptoren

- Ein paar komplexe Filter:
Segmentieren von Menschen in einem Bild (voll gekleidet)

Allgemein:

- Natürlich weitere Verbesserungen vorhandener Filter gemacht
- Geschwindigkeitsverbesserungen
- Erweiterung des Interfaces mit allen Masken für ImageRecognition2

Was ist das allgemeine langfristige Ziel dieses Frameworks:

Es soll sich dem Funktionsumfang von MATLAB Image Processing Toolbox, sowie Halcon immer mehr annähern

Was ist das allgemeine kurzfristige Ziel dieses Frameworks:

Einzelne Probleme die hier gestellt werden beantworten und lösen zu können, im Idealfall ohne Extraprogrammieraufwand, d.h. ausprobieren der Filtersequenz und evtl. Objekt-Extraktor soll ausreichen, um die Informationen zu bekommen die man will.

Und warum gibt es ImageRecognition2, die Oberfläche mit den vielen Menüpunkten?

Manchmal ist es ziemlich schwierig die richtigen Filter und vor allem die richtige Sequenz herauszufinden. ImageRecognition2 soll helfen die Sequenzen herausfinden zu können. Dazu werden viele Masken mit Einstellungen benötigt.

Solange die Masken noch nicht alle existieren können über den Menüpunkt "Window->Script" und den Button "Propertygrid" alle Einstellungen getestet und ausprobiert werden.

Auch für Echtzeitvideobearbeitung gibt es einen Menüpunkt:

Wird der entsprechende Menüpunkt eingeschaltet, wird - falls vorhanden - eine Liste der verfügbaren Devices angezeigt. Dieses kann dann ausgewählt werden. Es erscheint ein Dialog mit 2 Live-Bildern (links original, rechts das Bild auf das der Filter angewendet wird). In der Combobox kann dann der entsprechende Filter ausgewählt werden.

Weiterhin gibt es die Möglichkeiten einstellbare Verzeichnisse zu überwachen, online Flickr, Google pics und weitere Plattformen zu durchsuchen, sowie Screenshots von offenen Fenstern oder Controls über eine Auswahlliste vorzunehmen usw.

In einer späteren Version werden wahrscheinlich auch einzelne Frames von Videos ausgelesen werden können... wir wollen ja schließlich alle Bildquellen nutzen? ;-)
Dieser Beitrag wurde 3 mal editiert, zum letzten Mal von dr4g0n76 am .
Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.
private Nachricht | Beiträge des Benutzers
gfoidl
myCSharp.de - Team

Avatar #avatar-2894.jpg


Dabei seit:
Beiträge: 7533
Herkunft: Waidring

beantworten | zitieren | melden

Hallo,

hab zufällig einen interessanten Link gefuden und ich denke der passt hier ganz gut dazu.

dr4g0n76 liefert mit seinem Framework die "Anwendung" und Computer Vision: Algorithms and Applications liefert auf 979 Seiten die Theorie in Form einer Vorabfassung für ein Buch das Ende 2010 erscheinen soll.


mfG Gü
Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"
private Nachricht | Beiträge des Benutzers
dr4g0n76
myCSharp.de - Experte

Avatar #avatar-1768.jpg


Dabei seit:
Beiträge: 3047
Herkunft: Deutschland

Themenstarter:

beantworten | zitieren | melden

@gfoidl: Sehr gut. DIESEN kannte ich ausnahmsweise noch nicht. :-) Super.
Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.
private Nachricht | Beiträge des Benutzers
Mansur
myCSharp.de - Member



Dabei seit:
Beiträge: 2

beantworten | zitieren | melden

Das Thema finde ich sehr spannend und hab die meisten Postings angesehen.
Ich würde mir die Librarys gerne ansehen, kriege aber keine komplette Solution runter geladen.
Zum einen kriege ich immer einen Extrahierungsfehler
(blub.png sei fehlerhaft - was ja kein drama sein soll)
(Unerwartetes Archivende - Beim runterladen von den angeblichen 20MB springt er plötzlich zum Downloadende....)
Beim öffnen der Solution dann:
- Fehlende Projekte: AVICapWrapper, ImageScriptConsole, ScripterLibrary, LowLevelGraphics
- Im ImageRecognition2 fehlen dann entsprechend die Verweise

Gibt es das noch wo anders zum downloaden? Ich denke eher, daß es am Server liegt ....

Viele Grüße,
Mansur
private Nachricht | Beiträge des Benutzers
dr4g0n76
myCSharp.de - Experte

Avatar #avatar-1768.jpg


Dabei seit:
Beiträge: 3047
Herkunft: Deutschland

Themenstarter:

beantworten | zitieren | melden

@Mansur: Danke. Dann werde ich das Archiv nochmals hochladen. Vermutlich ist mir beim letzten Hochladen ein Fehler passiert (FTP lädt noch im Hintergrund hoch und ich habe den Computer in Standby versetzt...)

@Mansur:

So, habe das Archiv nochmals hochgeladen.

Außerdem habe ich jetzt hier die Binaries angehängt.

Für das hier angehängte Archiv gilt:

Leider musste ich die PDBs löschen und ein anderer Dateidialog darf nicht ausgewählt werden.

Es kann also hiermit weder Debugged noch ein Dateidialog mit Vorschau ausgewählt werden.
Aber das Programm sollte ausprobiert werden können.

Ich habs ausprobiert bei mir auf dem Rechner lässt sich die Exe aus dem Binary Verzeichnis starten.

EDIT: Ergänzungen für Änderungen:

- In die Child-Windows kann jetzt per Drag&Drop eine Bild-Datei hereingeladen werden.

- Mehrere Bilder auf einmal laden ist möglich durch Drag&Drop mehrerer Bilder auf den Client-Bereich

- Die Menüpunkte Same Size / Same Width / Same Height sind im Kontext-Menü für die Child Windows hinzugekommen

- Einige Fehler in manchen Filtern beseitigt

- Interpolation Filter (Für 2 Bilder) hinzugefügt

- Neuer Video-Detektions-Filter hinzugefügt

-Copy Paste Fehler in "Add" korrigiert: "Add" hatte gleiche Auswirkung wie "Sub"
Außerdem unterstützen jetzt beide Filter "ClipColor"

- Außerdem haben jetzt alle Comboboxen und andere Steuerelemente in denen Filter aufgerufen werden können AutoComplete aktiviert.

- Shortcut CTRL-F (F wie Filter) öffnet eine Textbox in der einfach durch eintippen des Namens und anschließendes Return ein Filter ausprobiert werden kann.
Attachments
Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.
private Nachricht | Beiträge des Benutzers
Mansur
myCSharp.de - Member



Dabei seit:
Beiträge: 2

beantworten | zitieren | melden

Hallo dr4g0n76,

Das Compillieren klappt bei mir leider immer noch nicht.
Ich konnte zwar die Verweise zu AVI... und LowLevel auf Deine Dlls umstellen,
Mir fehlt aber seltsamer weise die folgenden Klassen:
BaseColorSegmentation3
BaseColorSegmentation4
OwnOptimizedConvolution
... um kompillieren zu können (Wenn danach nicht noch etwas raus kommt).
Wenn ich einen Einstieg finden sollte, dann interessieren mich eher die Basisklassen.
Soweit ich die Beiträge gelesen habe ist ja das Projekt ImageRecignition2 nur die Frontend Anwendung, um die (komplexen) Filter entsprechend anzusprechen / zu konfigurieren.
Soweit ich das ganze (leider ohne Codeerklärung) mir bisher vorstellen kann ist es wohl die LowLevelGraphics Library die den Kern bildet.
Ich würde gerne mal probieren, ob sich Imageprocessing für GIS Anwendungen eignet ... so als Übungsprojekt.

Vielleicht kann man ja doch noch die LowLevelGraphics Library im Sourcecode sehen? oder war das nie so vorgesehen?

Viele Grüße,
Mansur
private Nachricht | Beiträge des Benutzers
dr4g0n76
myCSharp.de - Experte

Avatar #avatar-1768.jpg


Dabei seit:
Beiträge: 3047
Herkunft: Deutschland

Themenstarter:

beantworten | zitieren | melden

@Mansur: Die Klassen BaseColorSegmentation2, BaseColorSegmentation3 usw. habe ich rausgeworfen, da diese jetzt in BaseColorSegmentation vereint sind und mit einem Parameter der Modus eingestellt werden kann.
Zitat
Das Compillieren klappt bei mir leider immer noch nicht.
Ich konnte zwar die Verweise zu AVI... und LowLevel auf Deine Dlls umstellen,
Mir fehlt aber seltsamer weise die folgenden Klassen:
BaseColorSegmentation3
BaseColorSegmentation4
OwnOptimizedConvolution

... um kompillieren zu können (Wenn danach nicht noch etwas raus kommt).

Hmmm... das werde ich nochmal kontrollieren, auf jeden Fall solltest Du im VS 2008
auf die Projekte die "unavailable/nicht verfügbar" sind, einen "Reload Project/Projekt neu laden"-Befehl per Kontext-Menü ausführen.
Zitat
Wenn ich einen Einstieg finden sollte, dann interessieren mich eher die Basisklassen.
Soweit ich die Beiträge gelesen habe ist ja das Projekt ImageRecognition2 nur die Frontend Anwendung, um die (komplexen) Filter entsprechend anzusprechen / zu konfigurieren.

Das ImageRecognition2 Projekt ist die Oberfläche um die Filter, Extraktoren und weiteres auszuprobieren, richtig.
Zitat
Soweit ich das ganze (leider ohne Codeerklärung) mir bisher vorstellen kann ist es wohl die LowLevelGraphics Library die den Kern bildet.

LowLevelGraphicsLibrary Genau, diese Library bildet den Kern.

AcquiringLibrary
Die Acquiring Library ist dafür gedacht, um von verschiedenen Devices (z.B. Webcam) oder Online oder per Screenshot Bilder abzurufen.

ScripterLibrary
Die ScripterLibrary wird von der ImageProcessingConsole.exe benutzt.
Mit der ImageProcessingConsole können die Filter in der Console ausprobiert werden.
Zitat
Ich würde gerne mal probieren, ob sich Imageprocessing für GIS Anwendungen eignet ... so als Übungsprojekt.

Dann wäre es interessant die Ergebnisse zu veröffentlichen.
Zitat
Vielleicht kann man ja doch noch die LowLevelGraphics Library im Sourcecode sehen? oder war das nie so vorgesehen?

Doch die wird mit dem Projekt heruntergeladen vom Link im ersten Post,

hier nochmal der Link:

ImageRecognition2
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von dr4g0n76 am .
Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.
private Nachricht | Beiträge des Benutzers