myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
» Regeln
» Wie poste ich richtig?
» Forum-FAQ

Mitglieder
» Liste / Suche
» Wer ist wo online?

Ressourcen
» openbook: Visual C#
» openbook: OO
» Microsoft Docs

Team
» Kontakt
» Übersicht
» Wir über uns

» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Gemeinschaft » .NET-Komponenten und C#-Snippets » LowLevelGraphicsLibrary
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | Thema zu Favoriten hinzufügen

Seiten (2): [1] 2 nächste » Antwort erstellen
Zum Ende der Seite springen  

LowLevelGraphicsLibrary

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
dr4g0n76
myCSharp.de-Poweruser/ Experte

avatar-1768.jpg


Dabei seit: 07.07.2005
Beiträge: 2.890
Entwicklungsumgebung: SharpDevelop/VS.NET
Herkunft: Deutschland


dr4g0n76 ist offline

LowLevelGraphicsLibrary

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

EDIT: 28.01.2014:

Ich bin jetzt den Schritt gegangen und habe das Projekt auf

 https://imagerecognition2.codeplex.com/

gehostet.


EDIT 26.04.2012:

Lange nicht alle Menüpunkte funktionieren und das Rechteck das man mit der Maus aufziehen kann hat momentan auch keine Funktion... aber alles im entwickeln

Die wichtigsten Funktionen und Kürzel:

[U]Fenster

CTLR-N -> neues Fenster aufmachen
STRG-ALT-C -> Fenster kaskadieren
STRG-ALT-H -> Horizontal anordnen
STRG-ALT-V -> Vertikal anordnen
New Window (open copy) -> vom aktuellen Fenster aus eine Kopie in einem neuen Fenster erstellen
New Window (last loaded) -> neues Fenster mit dem zuletzt geladenen Bild

Filter
CTRL-F -> Filter ausführen

Windows->Script:

Filter ausführen (oberer Execute-button)
hier auch Kanal auswählen, A,R,G,B, Mask (unterer Execute-button)

Oder direkt im Menü entsprechenden Filter auswählen

Lambdaausdrücke:
Oben im Filter eingeben oder aus Combobox auswählen

Menüpunkt Windows->Script: Script ausführen....

Bilder verknüpfen/Contextmenü oder Toolleiste:
Bilder im Fenster aus Childwindowliste auswählen...

EDIT: 17.01.2012

Hier gibt's ab jetzt kleine Tutorials usw. über diese Library:

 http://lowlevelgraphicslibrary.blogspot.com/


[B]EDIT: 22.04.2010
Als Dateianhang am Ende dieses Beitrags verfügbar.

Es wird immer mal wieder von mir ein Testprojekt hochgeladen, aber das wird nicht explizit hier jedesmal vermerkt.


EDIT: Prerelease Versionen gibt es immer - wenn vorhanden - hier:

Anmerkung: Ich behalte mir vor, die Datei umzubenennen oder herauszunehmen.



Der Code kann jetzt hier
heruntergeladen werden (s. Ende dieses Posts).

Achtung: Das Projekt ist noch nicht gegen Fehler getestet.



Zudem hat die Basis Klasse das Interface IFilter bekommen.

Dieses wird beinhalten:

- Steps (Quasi Pixel in X-Richtung und Y-Richtung überspringen)
- Rectangle (Ausschnitt auswählen, auf den der Filter angewendet werden kann)
- einige grundlegende Funktionen wie in der System.Drawing.Bitmaps-Klasse z.B. Height / Width, GetPixel / SetPixel

Was schon drin ist:

Einige Experimentelle Filter:

- Neue Filter, z.B. Background-Estimation
- Farben runden
- Segmentierungen

- Colorspaces, Umrechnungen von RGB in verschiedene Farbräume und zurück u.a.
YUV, YCbCr, HCL, HSV, XYZ, CIELUV, CIELAB usw.

- verschiedene Kantenfilter und ein neuer Konturfilter
- verschiedene rudimentäre Segmentierungsfilter.

- Viele statische RGB-Funktionen unter ColorFunctions wie z.B. Summe der Channels,
MaxChannel, MinChannel, Channels vertauschen per String z.B. mach BGG oder RBG oder BGR aus Original RGB, Channel-Ratio,
usw. alle diese Funktionen sind in ColorFunctions ausprogrammiert.

- BitmapFunctions-Klasse um ein Bild auf verschiedene Arten z.B. in einen Stream oder Byte-Array und wieder zurück umzuwandeln, zu resizen und zu rotieren.

Einen Filter benutzen:

C#-Code:
Bitmap bitmap = (Bitmap)Image.FromFile("blub.jpg");
IFilter filter = new GrayScale();
filter.Execute(bitmap);

Die erste Zeile lädt das Bild,
die 2. Zeile instantiiert den Filter.
Dann wird der Filter angewendet

Zur Ausführung gibt es 3 Möglichkeiten:


1.) void Execute(bitmapSource);
Führt den Filter aus und bitmapSource enthält die neuen - veränderten - Informationen

2.) Bitmap ExecuteCloned(bitmapSource);
Führt den Filter geclont aus, d.h. bitmapSource wird nicht verändert, und die veränderte Bitmap wird zurückgegeben.


3.) void ExecuteMasked(bitmapSource, bitmapMask);
Führt den Filter aus und er wird nur an den Stellen angewendet in dem im Maskenbild weiße Pixel sind.

EDIT:

Als nächstes gibt es dann noch die Möglichkeiten:

4.) ExecuteChannelled

Für jeden Kanal kann angegegeben werden, ob das Ergebnis übernommen wird.

5.) ExecuteMaskedChannelled

Für jeden Kanal kann in Bezug auf die Maske angegeben werden, ob das Ergebnis übernommen wird.

EDIT: 4. und 5 sind jetzt implementiert.


Abkürzung des obigen Codes:

C#-Code:
new GrayScale().Execute(bitmapSource); //Bild in Grau umwandeln.

Es gibt bisher ( mind.) folgende

Filterkategorien:

- Farb-filter
- Konvolutions-Filter
- Morphologie-Filter
- Histogramm-Filter
- Kanten-Filter
- Ecken-Filter
- Frequenz-Filter
- Binarisierungs-Filter (Thresholding)
- Kontur-Filter
- Korrektur-Filter
- Korrelations-Filter
- Deplatzierungs-Filter
- Segmentierungs-Filter
- Makro-Filter
- Textur-Filter
- Mathematische Filter (algebraisch, logisch)

Über ein UnsafeBitmap Objekt kann auf einfache und schnelle Weise auf ein Bitmap zugegriffen und es verändert werden:

C#-Code:
UnsafeBitmap bitmap = new UnsafeBitmap(_bitmapSource);
//hier die Veränderungen durchführen
bitmap.Dispose(); //Und dann unbedingt Dispose aufrufen, um den Lock wieder freizugeben.

UnsafeBitmap bekommt als Eingang die originale Bitmap übergeben.
Dann wird intern alles durchgeführt um Unsafe auf die Bitmap zugreifen zu können.
Von außen sieht es aber aus, als würden wir ganz normal zugreifen.

C#-Code:
            List<Color> m_aColor = new List<Color>();
            m_aColor.Add(Color.FromArgb(255,255,255));

            UnsafeBitmap bitmap = new UnsafeBitmap(_bitmap);
            for (int y = 0; y < bitmap.Height; y++)
            {
                for (int x = 0; x < bitmap.Width; x++)
                {
                    Color color = bitmap.GetPixel(x, y);
                    if (!m_aColor.Contains(color))
                    {
                        bitmap.SetPixel(x, y, m_ColorToReplaceWith);
                    }
                }
            }
            bitmap.Dispose();

ImageRecognition2.rar (3 MB, 42 mal heruntergeladen)


Hinweise:

Was tut sich aktuell?

EDIT: 15.03.2012

Aktuell geht es um alles fürs Vermessen und die Erkennung von Bildern, was eingebaut wird.

- Neuronale Netzwerke
- Snakes / Active Contours

3D:

- Parität / Depthmap
- Stereo: Anaglyph / Interlaced / 3d-Modellschätzung


Dateianhang:
unknown ImageRecognition2.rar (4 MB, 1.442 mal heruntergeladen)

Dieser Beitrag wurde 28 mal editiert, zum letzten Mal von dr4g0n76 am 28.01.2014 11:20.

07.07.2005 14:24 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
maxE maxE ist männlich
myCSharp.de-Mitglied

Dabei seit: 27.04.2004
Beiträge: 456
Entwicklungsumgebung: SharpDevelop
Herkunft: Sachsen


maxE ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Ganz nett, aber man könnte die Lib noch etwas mehr in Richtung OO bringen. Alle Filter sind einfache statische Funktionen. Kann es sein, dass du die aus einer ehemaligen C Library konvertiert hast?
Die Filter könnte man übrigens prima als Plugin in Paint.NET integrieren Augenzwinkern  http://www.eecs.wsu.edu/paint.net/
07.07.2005 20:16 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Quallo
myCSharp.de-Mitglied

Dabei seit: 12.01.2005
Beiträge: 992
Entwicklungsumgebung: VS.NET 2005
Herkunft: Nähe Bremen


Quallo ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Klingt nach einer Menge Arbeit! Super das du das beisteuerst!
08.07.2005 08:53 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
shady shady ist männlich
myCSharp.de-Mitglied

Dabei seit: 31.01.2005
Beiträge: 42
Entwicklungsumgebung: VS.NET 2003


shady ist offline Füge shady Deiner Kontaktliste hinzu

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

irgendwie mekkert #Develop rum, wenn ich versuche den kram zu Kompilieren:

Zitat:
PFAD\cImageFilters.cs(35,4): error CS0227: Nicht gesicherter Code wird nur angezeigt, wenn mit '/unsafe' kompiliert wird

Das kommt überall da vor wo mit unsafe {} gearbeitet wurde.
Beim Kompilieren wird nur die .manifest Datei erstellt.
Wie kann ich das Lösen?

Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von shady am 13.07.2005 13:12.

13.07.2005 13:10 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
S.H.-Teichhof S.H.-Teichhof ist männlich
myCSharp.de-Mitglied

avatar-2460.jpg


Dabei seit: 03.10.2004
Beiträge: 1.549
Entwicklungsumgebung: #Developer
Herkunft: Sindringen


S.H.-Teichhof ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Du musst in den Projekt Einstellungen Unsafe Code zulassen
13.07.2005 13:14 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
shady shady ist männlich
myCSharp.de-Mitglied

Dabei seit: 31.01.2005
Beiträge: 42
Entwicklungsumgebung: VS.NET 2003


shady ist offline Füge shady Deiner Kontaktliste hinzu

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

ok, sorry, da hab ich ja auch schon geguckt, ich hab die Option nur übersehen... großes Grinsen
14.07.2005 09:59 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Zwischen diesen beiden Beiträgen liegt mehr als ein Jahr.
tom-essen tom-essen ist männlich
myCSharp.de-Poweruser/ Experte

avatar-2140.png


Dabei seit: 15.05.2005
Beiträge: 1.815
Entwicklungsumgebung: VS.NET 2013
Herkunft: NRW


tom-essen ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo!

Die Komponente gefällt mir sehr gut, Kompliment!
Kurze Frage von einem Nicht-Experten in Sachen Bildbearbeitung:
Gibt es bzgl. der abgefragten Werte z.B. für Helligkeit, Kontrast, Gamma, ... bestimmte Grenzwerte?

EDIT: OK, lässt sich im Quellcode ablesen (0..255).

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von tom-essen am 18.12.2006 13:48.

18.12.2006 12:23 Beiträge des Benutzers | zu Buddylist hinzufügen
tom-essen tom-essen ist männlich
myCSharp.de-Poweruser/ Experte

avatar-2140.png


Dabei seit: 15.05.2005
Beiträge: 1.815
Entwicklungsumgebung: VS.NET 2013
Herkunft: NRW


tom-essen ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo!

Nächste Frage:
Wo ist der Unterschied zwischen cGraphics.cs und cImageFilters.cs (ist eine davon schneller oder genauer)?
18.12.2006 13:54 Beiträge des Benutzers | zu Buddylist hinzufügen
Zwischen diesen beiden Beiträgen liegen mehr als 2 Jahre.
ErfinderDesRades
myCSharp.de-Poweruser/ Experte

avatar-3151.jpg


Dabei seit: 31.01.2008
Beiträge: 5.298


ErfinderDesRades ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Ist das Beispielprojekt [im neuen Download] iwie flötengegangen?
Bei mir findet sich nur ein Project, und zwar ganz ohne Property-Ordner - wo issn nun niedergelegt, dasses eine Dll ist, weil kommt beim Start schon die Fehlermeldung "Klassenbibliotheks-Projekt kann nicht StartProjekt sein"

Nee, flötengegangen auch nicht, verschiedene Forms sind ja noch vorhanden.
Also iwie ein unvollständiger Upload?
10.08.2009 19:44 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
dr4g0n76
myCSharp.de-Poweruser/ Experte

avatar-1768.jpg


Dabei seit: 07.07.2005
Beiträge: 2.890
Entwicklungsumgebung: SharpDevelop/VS.NET
Herkunft: Deutschland

Themenstarter Thema begonnen von dr4g0n76

dr4g0n76 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

@ErfinderDesRades:

EDIT 18.12.2009: Das komplette Projekt kann im 1. Thread heruntergeladen werden.

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von dr4g0n76 am 18.12.2009 07:41.

10.08.2009 19:55 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
ErfinderDesRades
myCSharp.de-Poweruser/ Experte

avatar-3151.jpg


Dabei seit: 31.01.2008
Beiträge: 5.298


ErfinderDesRades ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Ohne Beispielprojekt findich schade, weil willichmal einen Blick reinwerfen, mussich erstmal iwas programmieren, dassich ühaupt was zu sehen kriege.
Habich jetzt ja gemacht, und noch folgendes gefunden:

CGraphics scheint versehentlich dringeblieben, weil die Arbeit scheint ja CImageFilters zu machen.
Von den Forms ist nur FormMain im Designer darstellbar, allen anderen melden: "Method 'System.Windows.Forms.Form.CenterToParent' not found."
Bei vielen Filtern kommt ein Eingabefenster "Value eingeben", da kann man dann einen Value eingeben - nirgends ein Hinweis, was der Value bewirkt.

Und dass das Projekt keine Properties hat, scheint mir, wie gesagt, an einem fehlerhaften Upload zu liegen, odr?
10.08.2009 20:05 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
dr4g0n76
myCSharp.de-Poweruser/ Experte

avatar-1768.jpg


Dabei seit: 07.07.2005
Beiträge: 2.890
Entwicklungsumgebung: SharpDevelop/VS.NET
Herkunft: Deutschland

Themenstarter Thema begonnen von dr4g0n76

dr4g0n76 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

EDIT 18.12.2009:

Das Projekt wird immer hier im 1. Post dieses Threads hochgeladen.
Es ist aber immer noch kein endgültiges Release angesagt.

Ich stelle einfach hier die Prerelease-Versionen zur Verfügung.

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von dr4g0n76 am 18.12.2009 07:42.

18.08.2009 10:28 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
dr4g0n76
myCSharp.de-Poweruser/ Experte

avatar-1768.jpg


Dabei seit: 07.07.2005
Beiträge: 2.890
Entwicklungsumgebung: SharpDevelop/VS.NET
Herkunft: Deutschland

Themenstarter Thema begonnen von dr4g0n76

dr4g0n76 ist offline

Neuer Mechanismus

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Preview:

Wie im angehängten Bild zu sehen, können beim nächsten Upload auch farbige Blobs anhand der Rechtecke ermittelt werden.

Bildanalyse:

Mit einem "JOIN" können Rechtecke ähnlicher Farben zu größeren Rechtecken verschmolzen werden.

dr4g0n76 hat dieses Bild (verkleinerte Version) angehängt:
Blobs.jpg
Volle Bildgröße

20.08.2009 17:03 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
dr4g0n76
myCSharp.de-Poweruser/ Experte

avatar-1768.jpg


Dabei seit: 07.07.2005
Beiträge: 2.890
Entwicklungsumgebung: SharpDevelop/VS.NET
Herkunft: Deutschland

Themenstarter Thema begonnen von dr4g0n76

dr4g0n76 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hier noch zum Vergleich das Originalbild:

dr4g0n76 hat dieses Bild (verkleinerte Version) angehängt:
blobs1.jpg
Volle Bildgröße

Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von dr4g0n76 am 21.08.2009 11:19.

20.08.2009 17:05 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
dr4g0n76
myCSharp.de-Poweruser/ Experte

avatar-1768.jpg


Dabei seit: 07.07.2005
Beiträge: 2.890
Entwicklungsumgebung: SharpDevelop/VS.NET
Herkunft: Deutschland

Themenstarter Thema begonnen von dr4g0n76

dr4g0n76 ist offline

Preview Applikation

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hier gibt's jetzt die Preview Applikation.

Der Code ist noch nicht gecleant und viele Filter sind noch mit Bitmap.SetPixel GetPixel implementiert und deswegen langsam.

Es ist eben noch ein Entwicklungsprojekt. Aber solange kann jeder ja mal damit rumspielen.

Fehler zu monieren hat momentan keinen Sinn. Die werden erst wichtig, wenn die neue Version komplett veröffentlicht wird.


Z.B. wird die Klasse ImageFilters noch in LowLevelGraphicsLibrary wandern, ebenso wie die Blobs usw.

EDIT: Graue Funktionen sind momentan nicht aktiviert/implementiert...

EDIT: Download s. oberster Post.

Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von dr4g0n76 am 11.09.2009 14:07.

23.08.2009 18:43 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
dr4g0n76
myCSharp.de-Poweruser/ Experte

avatar-1768.jpg


Dabei seit: 07.07.2005
Beiträge: 2.890
Entwicklungsumgebung: SharpDevelop/VS.NET
Herkunft: Deutschland

Themenstarter Thema begonnen von dr4g0n76

dr4g0n76 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hier ein Screenshot dazu:

Screenshot1.jpg

dr4g0n76 hat dieses Bild (verkleinerte Version) angehängt:
Screenshot1.jpg
Volle Bildgröße

23.08.2009 18:47 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
dr4g0n76
myCSharp.de-Poweruser/ Experte

avatar-1768.jpg


Dabei seit: 07.07.2005
Beiträge: 2.890
Entwicklungsumgebung: SharpDevelop/VS.NET
Herkunft: Deutschland

Themenstarter Thema begonnen von dr4g0n76

dr4g0n76 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

[EDIT] 18.12.2009:

- Viele neue Filter, z.B. Segmentierung
- Color-Blob-Extraktor mit neuem Verfahren
- ColorSpaces, Umrechnung von RGB in andere Farbräume...
- RGB-Funktionen (z.B. Abfrage auf RGB-Range, Maxchannel, Minchannel usw.)

Einfach dazu das Projekt im ersten Post dieses Threads herunterladen.

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von dr4g0n76 am 18.12.2009 07:43.

10.09.2009 18:11 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
MagicAndre1981 MagicAndre1981 ist männlich
myCSharp.de-Mitglied

avatar-2623.jpg


Dabei seit: 16.05.2005
Beiträge: 906
Entwicklungsumgebung: Visual Studio 2005 Prof/ #d2.1
Herkunft: Nordhausen


MagicAndre1981 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Ich muss dir ein großes Kompliment machen, die Bibliothek ist einfach genial :)
10.09.2009 23:45 Beiträge des Benutzers | zu Buddylist hinzufügen
dr4g0n76
myCSharp.de-Poweruser/ Experte

avatar-1768.jpg


Dabei seit: 07.07.2005
Beiträge: 2.890
Entwicklungsumgebung: SharpDevelop/VS.NET
Herkunft: Deutschland

Themenstarter Thema begonnen von dr4g0n76

dr4g0n76 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

@MagicAndre1981: Dankeschön. Das ist ein super Kompliment und erfreut mich ungemein. Läuft runter wie Öl. *verneig* :-)
11.09.2009 14:03 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
dr4g0n76
myCSharp.de-Poweruser/ Experte

avatar-1768.jpg


Dabei seit: 07.07.2005
Beiträge: 2.890
Entwicklungsumgebung: SharpDevelop/VS.NET
Herkunft: Deutschland

Themenstarter Thema begonnen von dr4g0n76

dr4g0n76 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

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.
30.09.2009 20:25 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
dr4g0n76
myCSharp.de-Poweruser/ Experte

avatar-1768.jpg


Dabei seit: 07.07.2005
Beiträge: 2.890
Entwicklungsumgebung: SharpDevelop/VS.NET
Herkunft: Deutschland

Themenstarter Thema begonnen von dr4g0n76

dr4g0n76 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Ihr dürft aber gerne schon Rückmeldungen geben, vielleicht fehlt euch noch ein Filter oder ihr habt grundsätzliche Fehler entdeckt, ich werde die Vorschläge aufnehmen, prüfen und falls sinnvoll ggf. berücksichtigen.
02.10.2009 14:46 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
dr4g0n76
myCSharp.de-Poweruser/ Experte

avatar-1768.jpg


Dabei seit: 07.07.2005
Beiträge: 2.890
Entwicklungsumgebung: SharpDevelop/VS.NET
Herkunft: Deutschland

Themenstarter Thema begonnen von dr4g0n76

dr4g0n76 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Die Beschreibung der Filter werde ich heute noch hier online stellen:

[EDIT] die erste Anleitung ließ sich nicht online laden, deshalb bis ich wieder dazu komme wird es noch wohl eine Weile dauern.

Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von dr4g0n76 am 19.10.2009 09:15.

12.10.2009 14:30 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
dr4g0n76
myCSharp.de-Poweruser/ Experte

avatar-1768.jpg


Dabei seit: 07.07.2005
Beiträge: 2.890
Entwicklungsumgebung: SharpDevelop/VS.NET
Herkunft: Deutschland

Themenstarter Thema begonnen von dr4g0n76

dr4g0n76 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Neues Prerelease hochgeladen. s. ganz oben, 1. Post in diesem Thread.
04.11.2009 18:10 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
dr4g0n76
myCSharp.de-Poweruser/ Experte

avatar-1768.jpg


Dabei seit: 07.07.2005
Beiträge: 2.890
Entwicklungsumgebung: SharpDevelop/VS.NET
Herkunft: Deutschland

Themenstarter Thema begonnen von dr4g0n76

dr4g0n76 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Neues Prerelease erstellt.

Unter anderem funktionieren jetzt:

- Houghtransform
- Moravec
- ZeroCrossing
- AdaptiveThresholding

Funtionen in ColorFunctions:

u.a.
- Mul(Color, Color)
- Sub (Color, Color)
- Div(Color, Color)

EDIT: noch nicht hochgeladen

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von dr4g0n76 am 11.11.2009 16:52.

11.11.2009 16:49 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
dr4g0n76
myCSharp.de-Poweruser/ Experte

avatar-1768.jpg


Dabei seit: 07.07.2005
Beiträge: 2.890
Entwicklungsumgebung: SharpDevelop/VS.NET
Herkunft: Deutschland

Themenstarter Thema begonnen von dr4g0n76

dr4g0n76 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Neue Version hochgeladen.
12.11.2009 14:39 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
HeRaider HeRaider ist männlich
myCSharp.de-Mitglied

Dabei seit: 26.06.2008
Beiträge: 81


HeRaider ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hm sieht ganz interessant aus. Muss ich mir mal anschauen.

PS: Ich suche noch nach einer Funktion die weiße Ränder an Grafiken entfernen kann falls dir da was einfallen sollte Augenzwinkern
12.11.2009 16:05 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
dr4g0n76
myCSharp.de-Poweruser/ Experte

avatar-1768.jpg


Dabei seit: 07.07.2005
Beiträge: 2.890
Entwicklungsumgebung: SharpDevelop/VS.NET
Herkunft: Deutschland

Themenstarter Thema begonnen von dr4g0n76

dr4g0n76 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

@HeRaider: So eine Funktion gibt es eigentlich schon. Benutze (ab der nächsten Version) Autocrop. Und übergebe Autocrop die Bedingung.
14.11.2009 10:13 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
dr4g0n76
myCSharp.de-Poweruser/ Experte

avatar-1768.jpg


Dabei seit: 07.07.2005
Beiträge: 2.890
Entwicklungsumgebung: SharpDevelop/VS.NET
Herkunft: Deutschland

Themenstarter Thema begonnen von dr4g0n76

dr4g0n76 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Die Bibliothek ist eigentlich ausgelegt für Stills (Einzelbilder), nicht für Videobearbeitung

- Viele kleine Korrekturen (Fehlende Konstruktoren, Falsche Berechnungen, fehlende Benutzung von UnsafeBitmap und dazugehöriges UnsafeBitmap.Dispose() an manchen Stellen )

- Autocrop ist jetzt rudimentär implementiert, kann benutzt werden.
Funktioniert fürs erste IMHO relativ gut.

- Korrektur von Umrechnungen für Farbmodelle und redundante Farbmodelle entfernt

- Alle vorgesehenen Filter zum Funktionieren gebracht

- Objektextraktor begonnen

Es gibt jetzt im wesentlichen 4 Komponentenarten:

- Extractors (Klassen um bestimmte Features/Objekt usw. zu extrahieren)
- Colorspaces (Farbräume)
- Filter (z.B. Farbfilter-, Morphologie-, Kanten-, Eck-Filter usw.)
- Histogramm und Statistikfunktionen

(- sowie Hilfsfunktionen (BitmapFunctions, ColorFunctions))
07.12.2009 15:18 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
ErfinderDesRades
myCSharp.de-Poweruser/ Experte

avatar-3151.jpg


Dabei seit: 31.01.2008
Beiträge: 5.298


ErfinderDesRades ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hi!

als ich vor längerer Zeit mal reingeguckt hab, fandich das mit den Filtern suboptimal - für jeden Filter eine eigene klasse.
Dabei sind die meisten Filter ja ConvolutionFilter, nur je mit verschiedenen Parametern.
Das kann man wesentlich vereinfachen, indem man einen ConvolutionFilter schreibt, und den mit verschiedenen Parametern aufruft.

Ich hab sowas mal gemacht, da habich die verschiedenen Parameter in einer DataTable zusammengefasst., und User kann wählen.
Das hat den lustigen NebenEffekt, der User kann seine eigenen Filter erfinden, indem er der DataTable weitere Datensätze zufügt.
gugge  Convolution-Filter
07.12.2009 15:45 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
dr4g0n76
myCSharp.de-Poweruser/ Experte

avatar-1768.jpg


Dabei seit: 07.07.2005
Beiträge: 2.890
Entwicklungsumgebung: SharpDevelop/VS.NET
Herkunft: Deutschland

Themenstarter Thema begonnen von dr4g0n76

dr4g0n76 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

@ErfinderDesRades:

Das ist nicht mehr so, dass die meisten Filter Convolution-Filter sind.

Außerdem werde ich einige Filter sowieso zusammenfassen (Es macht z.B. keinen Sinn einen Filter Contours und einen Contours-Filter zu haben.)

Außerdem sind die Filter von BaseImageFilter abgeleitet und haben die eigene Schnittstelle IFilter. So kann also jeder seinen eigenen Filter kreieren und hinzufügen.

Außerdem veröffentliche ich hier einfach die Fortschritte damit jeder damit arbeiten kann.

z.B. gibt es auch noch keine sinnvolle Namespace-Aufteilung, die IMHO aber inzwischen nötig ist. z.B. in Convolution, Morphology, Color usw.

Bis dahin. ;-) Viel Spass damit.

Probiers doch einfach mal aus.
07.12.2009 16:31 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
ViperNeo ViperNeo ist männlich
myCSharp.de-Mitglied

Dabei seit: 22.02.2008
Beiträge: 352
Entwicklungsumgebung: VS05/08/10 Prof.
Herkunft: Darmstadt


ViperNeo ist offline Füge ViperNeo Deiner Kontaktliste hinzu

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

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
17.12.2009 08:43 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
dr4g0n76
myCSharp.de-Poweruser/ Experte

avatar-1768.jpg


Dabei seit: 07.07.2005
Beiträge: 2.890
Entwicklungsumgebung: SharpDevelop/VS.NET
Herkunft: Deutschland

Themenstarter Thema begonnen von dr4g0n76

dr4g0n76 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

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.

dr4g0n76 hat dieses Bild (verkleinerte Version) angehängt:
AfterXMas.jpg
Volle Bildgröße

Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von dr4g0n76 am 18.12.2009 13:11.

18.12.2009 13:06 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
digi333
myCSharp.de-Mitglied

Dabei seit: 17.06.2006
Beiträge: 290


digi333 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

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
22.12.2009 17:51 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
ErfinderDesRades
myCSharp.de-Poweruser/ Experte

avatar-3151.jpg


Dabei seit: 31.01.2008
Beiträge: 5.298


ErfinderDesRades ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

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:

C#-Code:
        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

C#-Code:
        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

C#-Code:
         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?

C#-Code:
    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

C#-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);
            }
        }
    }
}

C#-Code:
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

C#-Code:
        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 02.01.2010 01:48.

02.01.2010 01:09 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
ErfinderDesRades
myCSharp.de-Poweruser/ Experte

avatar-3151.jpg


Dabei seit: 31.01.2008
Beiträge: 5.298


ErfinderDesRades ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

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

Code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
   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

C#-Code:
        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 02.01.2010 09:02.

02.01.2010 09:00 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
ErfinderDesRades
myCSharp.de-Poweruser/ Experte

avatar-3151.jpg


Dabei seit: 31.01.2008
Beiträge: 5.298


ErfinderDesRades ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

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.
08.01.2010 14:08 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
dr4g0n76
myCSharp.de-Poweruser/ Experte

avatar-1768.jpg


Dabei seit: 07.07.2005
Beiträge: 2.890
Entwicklungsumgebung: SharpDevelop/VS.NET
Herkunft: Deutschland

Themenstarter Thema begonnen von dr4g0n76

dr4g0n76 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

@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

C#-Code:
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:

C#-Code:
   /// 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
08.01.2010 14:44 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
dr4g0n76
myCSharp.de-Poweruser/ Experte

avatar-1768.jpg


Dabei seit: 07.07.2005
Beiträge: 2.890
Entwicklungsumgebung: SharpDevelop/VS.NET
Herkunft: Deutschland

Themenstarter Thema begonnen von dr4g0n76

dr4g0n76 ist offline

Angekündigt:

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

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 25.01.2010 17:08.

13.01.2010 17:40 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
-Hades- -Hades- ist männlich
myCSharp.de-Mitglied

Dabei seit: 05.11.2007
Beiträge: 171
Entwicklungsumgebung: VS 2008 Pro.
Herkunft: Deutschland NRW


-Hades- ist offline Füge -Hades- Deiner Kontaktliste hinzu

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

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-
14.01.2010 11:00 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
dr4g0n76
myCSharp.de-Poweruser/ Experte

avatar-1768.jpg


Dabei seit: 07.07.2005
Beiträge: 2.890
Entwicklungsumgebung: SharpDevelop/VS.NET
Herkunft: Deutschland

Themenstarter Thema begonnen von dr4g0n76

dr4g0n76 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

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:

C#-Code:
new GrayScale().Execute(bitmap);
new Brightness(10).Execute(bitmap);
new Contrast(10).Execute(bitmap);

usw.
14.01.2010 12:40 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Seiten (2): [1] 2 nächste » Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum Der Startbeitrag ist älter als 15 Jahre.
Der letzte Beitrag ist älter als 6 Jahre.
Antwort erstellen


© Copyright 2003-2021 myCSharp.de-Team | Impressum | Datenschutz | Alle Rechte vorbehalten. | Dieses Portal verwendet zum korrekten Betrieb Cookies. 20.01.2021 07:36