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

Forenbeiträge von dr4g0n76 Ingesamt 2.921 Beiträge

22.04.2010 - 12:52 Uhr

Dazu habe ich noch eine paar Fragen @Corpsegrinder

Ich stelle die Fragen mal hier öffentlich, weil ich denke dass mehrere Leute hier die gleichen Fragen haben könnten.

Es soll eine möglichst performante Matrix-Klasse erstellt werden.

Heißt möglichst performant elegant mathematisch mit möglichst wenigen Rechenoperationen oder heißt das zusätzlich noch parallele Berechnungen per Threads wenn mehrere benutzt werden?

Es sollen die normalen Matrix-Operationen (+, -, * und ^) implementiert werden.

Heißt hier ^ potenzieren oder meinst Du damit etwas anderes?

Wichtig ist, dass die Matrix absolut Threadsafe und alle Methoden pure sind (d.h. egal wie oft man sie aufruft, es kommt immer das gleiche Ergebnis heraus).

Heißt das wirklich "pure"? Ich kenne das als idempotent (kann mich auch irren). 😉

Achso... eine schicke ToString() ist natürlich auch gerne gesehen 😉

Wie soll ausgegeben werden? Ich meine in welchem Format.

Stellst Du Dir da so was vor:

3 5 2
4 3 1
3 4 2

oder etwas anderes?

Oder meinst Du gar eine Matrix aus der Prädikatenlogik? Das wäre dann etwas ganz anderes IMHO als die mathematische Variante.

21.04.2010 - 12:22 Uhr

Klar. Mehrere.

Nummer 1:

1.) - AddIns von #Develop lassen sich einfach durch andere AddIns erweitern.

2.) - Ein Projekt kann ohne weiteres Zutun verschiedene .NET Quellcodes enthalten,
z.B. 1 Datei VB, 1 Datei C#, 1 Datei J#
Es wird ohne Probleme übersetzt.

3.) Mein pers. Favorit: - Quellcodes können - wenn sie sich denn übersetzen lassen - meist zu 100% in die jeweils andere .NET Sprache übersetzt werden.

4.) Man kann die einzelnen Teile relativ einfach für eigene Projekte benutzen. Zum Beispiel den Texteditor.

s.dazu auch:
[Artikelserie] Den SharpDevelop Kern in eigenen Anwendungen verwenden

Ich benutze 3.) sehr oft. Wir programmieren bei uns in der Firma in VS 2008 mit VB.NET und da ich lieber c# programmiere und da viel schneller bin, schreibe ich öfter mal den Code in C# und lass mir das zugehörige VB Pendant generieren.

21.04.2010 - 11:32 Uhr

Interessant. Ist Leviatan dort Dein Nick? Gefällt mir auch die Idee.

Vor allem Hat #Develop ein paar Features die mir SO im VS 20xy immer noch fehlen.

21.04.2010 - 09:44 Uhr

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.

20.04.2010 - 16:43 Uhr

Zum Hintergrund vielleicht noch:

Nachdem ich in die LowLevelGraphicsLibrary einen BlobExtraktor eingebaut hatte,
der auf Colored Blobs basiert, s. Screenshot im entsprechenden Projekt,
sowie Template Matching,

wollte ich einfach mit einem Contour Tracer NOCH eine Möglichkeit zur Verfügung
stellen um Objekte extrahieren zu können. Und diese "Snake" ist eben dabei herausgekommen.

Jetzt muss ich sie nur noch komplett zum Laufen bekommen.

Hinweis:

Klar ist, dass diese Art der Snakegenerierung momentan auch nur mit Bildern wie dem Testbild funktioniert. Mit richtigen Farbbildern wird sich da so momentan noch nichts machen lassen.

Außerdem ist für die Snake wichtig, dass der Hintergrund und Vordergrund segmentiert sind, die Snake hangelt sich ja momentan nur an EINER Vordergrundfarbe entlang (z.B. Schwarz im Beispiel, wobei davon ausgegangen wird, dass der Hintergrund weiß ist).

Interessant wird das ganze dann später, wenn die Snake auch mit wechselnden Konturfarben für Objekte funktionieren sollte und evtl. auch selbst den Hintergrund mit segmentieren kann.

Ansonsten muss eben vorher segmentiert werden. Auf jeden Fall möchte ich soweit kommen, dass die Kontur verschiedenfarbige Pixel haben kann.

20.04.2010 - 15:26 Uhr

Die Lösung scheint momentan in diesem Algorithmus zu sein, dass das Array umgedreht werden muss, sobald ein erster Fehler auftritt.

Danke @ Jack30Lena. Du hast mir quasi die Lösung aufgezeigt. 😉

oben werde ich die geänderten Stellen farbig markieren.

EDIT: zu früh gefreut, es funktioniert nicht bei allen Objekten im oben gezeigten Bild, aber es ist schon mal besser.

20.04.2010 - 15:03 Uhr

@Jack30Lena:

Danke für den Hinweis. Das hatte ich auch schon untersucht. Aber mir kommt da gerade noch eine Idee, die ich dann untersuchen werde.

19.04.2010 - 20:17 Uhr

Skaliert werden kann entweder in Y-Richtung (durch skalieren eines jeden Wertes, d.h. malnehmen mit einem Faktor) oder in X-Richtung (strecken der Werte).

Wo da jetzt noch Dein Problem ist, verstehe ich momentan nicht.

Zeig mal bitte was Du bisher programmiert hast. Pattern Recognition ist nicht so trivial.

19.04.2010 - 20:13 Uhr

und wenn das alles nichts helfen sollte, dann versuch mal TextRenderingHint auf clearTypeGrid oder Alias zu setzen.

sollte sich zumindest bei

e.Graphics.DrawString( "Text", Font, Brushes.Black, printArea, format );

machen lassen.

19.04.2010 - 20:10 Uhr

Dann nimm von jedem Tupel Min/Max

(kannst Du bekommen in dem du jedes Tupel nach seinen 4 Werten sortierst, 1. Index und letzter Index enthalten jeweils Dein Min und Max je nach dem ob du aufsteigend oder absteigend sortierst ist max hinten und min vorne oder umgekehrt.)

Nächster Schritt ist deine Schablone.

Das müsste ja dann ebenfalls ein Histogramm mit mind. 2er Tupeln sein.

Und dann kannst Du Tupel für Tupel vergleichen. Danach kannst Du auswerten wie ähnlich sie sich sind.

Dann hast Du Deinen Mustervergleich.

19.04.2010 - 20:03 Uhr

Hab das Projekt mal mit angehängt.

19.04.2010 - 19:57 Uhr

@Zommi:

Definitions.EnvironmentPointerClockwise hat folgenden Inhalt:

  •   m_aPoint	Count = 8	System.Collections.Generic.List<System.Drawing.Point>  
    
  •   [0]	{X = -1 Y = -1}	System.Drawing.Point  
    
  •   [1]	{X = 0 Y = -1}	System.Drawing.Point  
    
  •   [2]	{X = 1 Y = -1}	System.Drawing.Point  
    
  •   [3]	{X = 1 Y = 0}	System.Drawing.Point  
    
  •   [4]	{X = 1 Y = 1}	System.Drawing.Point  
    
  •   [5]	{X = 0 Y = 1}	System.Drawing.Point  
    
  •   [6]	{X = -1 Y = 1}	System.Drawing.Point  
    
  •   [7]	{X = -1 Y = 0}	System.Drawing.Point  
    
  •   Raw View		  
    

Danke für den Hinweis.

Sieht m.E. richtig aus. [5] hat X=0 Y=1, das ist doch dann der senkrecht nach unten zeigende Vektor?!

Was meinst Du dazu Zommi?

19.04.2010 - 19:52 Uhr

@Numpsy.

Es geht dort nicht an sich um die LowLevelGraphicsLibrary sondern um das Neighbouring-Modell.

Oder möchtest Du nur über die Werte im Diagramm eine Schablone legen?

Wie erhältst Du denn Deine Werte?

EDIT: Schablone darüber legen könnte heißen Du kommst mit Histogramm Template Matching weiter.

d.h.

mach Dir ein Template Histogramm. Histogramm mit mehreren Werten. Das ist Deine Schablone. Vergleich diese Wert für Wert mit denen die Dein Diagramm bilden.

Das Diagramm oder der Abschnitt mit dem kleinsten SOD (Sum Of Differences)
ist wahrscheinlich das was Du suchst.

Ansonsten mußt Du viel genauer erklären was Du machen möchtest.

So habe ich Dich jetzt zumindest mal vage verstanden.

19.04.2010 - 19:47 Uhr

Das passiert wenn ich mehrmals ausführen lasse:

Die Snakes werden dann so wie hier gezeigt chronologisch von oben bis unten gezeichnet.

P.S.: Diese Snakes sind übrigens keine Snakes im Sinne der Bildverarbeitung eigentlich ist es mehr ein Boundary/Conturtracer.

19.04.2010 - 19:45 Uhr

@numpsy: Selbe Frage. Was möchtest Du genau wissen?! Wie bist Du bisher vorgegangen?

Hilft Dir

LowLevelGraphicsLibrary: Neighbouring Modell

eventuell weiter?

Bitte poste hier.
Und eine genauere Fragestellung wäre auch toll. Danke.

19.04.2010 - 19:42 Uhr

Für eine Grafikfunktion möchte ich eine Snake programmieren,
d.h. eine Funktion die eine bestimmte Kontur umschließt.

Es sieht aber so aus, als ob beim Richtungswechsel ein Fehler auftritt, denn dann steigt die Funktion aus, weil sie wieder beim Originalpixel angekommen ist.

Was mache ich falsch?

Es sollte (momentan) folgendermaßen funktionieren (wenn kein Fehler im Algorithmus wäre):

1.) Zuerst wird von oben ein Pixel quasi fallen gelassen, bis er auf ein schwarzes Pixel trifft. Das ist der Startpunkt (s. FindStartPoint).

2.) Dann wird mit GetNextConnectedPixel ausgehend vom Startpunkt der nächste verbundene schwarze Pixel gesucht.

3.) Dadurch erhält man eine Direction (int) und einen nächsten Punkt.
Mit diesen wird dann wieder wie bei 2. weiterverfahren.

  1. und 3. bilden also eine Schleife.

Die Richtungen in denen ausgehend vom momentanen Pixel weiter gesucht wird, sind in einem Dictionary gespeichert. Gezählt wird der Index ausgehend vom linken oberen Pixel mit Index 0 (-1,-1) entsprechend Index 7 im Uhrzeigersinn um den aktuellen Pixel herum (8er Nachbarschaft).

Die Indizes sind so für das jeweils aktuelle Pixel:

0 1 2  
7 x 3  
6 5 4  

im Dictionary sind immer 5 mögliche neue Richtungen für eine Ausgangsrichtung gegeben.


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

namespace ExtractorTest
{
    /// <summary>
    /// 
    /// </summary>
    public class DirectionVectorSnake
    {
        protected UnsafeBitmap m_Bitmap = null;
        protected bool[,] m_aMark = null;
        protected Color m_Color = Color.Transparent;
        protected Point m_NoPoint = new Point(-1, -1);
        protected int m_nHeight = -1;
        protected int m_nWidth = -1;
        Dictionary<int, int[]> m_aInt = new Dictionary<int, int[]>();
        //List<Point> m_aPoint = Definitions.EnvironmentPointListClockwise;

Point[] m_aPoint = Definitions.EnvironmentPointListClockwise.ToArray();


        /// <summary>
        /// Initializes a new instance of the <see cref="Snake"/> class.
        /// </summary>
        /// <param name="_bitmap">The _bitmap.</param>
        public DirectionVectorSnake(UnsafeBitmap _bitmap, Color _color)
        {
            m_nHeight = _bitmap.Height;
            m_nWidth = _bitmap.Width;
            m_Bitmap = _bitmap;
            m_Color = _color;
            m_aMark = new bool[m_nWidth, m_nHeight];

            m_aInt.Add(0, new int[] { 0, 1, 2, 6, 7 });
            m_aInt.Add(1, new int[] { 1, 2, 3, 0, 7 });
            m_aInt.Add(2, new int[] { 0, 1, 2, 3, 4 });
            m_aInt.Add(3, new int[] { 1, 2, 3, 4, 5 });
            m_aInt.Add(4, new int[] { 2, 3, 4, 5, 6 });
            m_aInt.Add(5, new int[] { 3, 4, 5, 6, 7 });
            m_aInt.Add(6, new int[] { 4, 5, 6, 7, 0 });
            m_aInt.Add(7, new int[] { 7, 0, 1, 5, 6 });
        }

        /// <summary>
        /// Creates this instance.
        /// </summary>
        /// <returns></returns>
        public List<Point> Create()
        {
            List<Point> aSnake = new List<Point>();

            Point ptStart = FindStartPoint(180);

            int nDirection = 0;
            int nXStart = ptStart.X;
            int nYStart = ptStart.Y;
            Point point = new Point(nXStart, nYStart);
            point = GetNextConnectedPixel(ptStart, ref nDirection); 

            if (ptStart == m_NoPoint)
                return null;

            Point ptLast = new Point(nXStart, nYStart);

            bool bNeedToStop = false;

            int nIterations = 0;
            while (!bNeedToStop)
            {
                if (aSnake.Count > 89) //hier passiert der Fehler, dient nur zum Debuggen
                {
                }

                point = GetNextConnectedPixel(point, ref nDirection);
                if (point == ptStart || point == m_NoPoint)
                {
                    bNeedToStop = true;
                    break;
                }

                if (!aSnake.Contains(point) && point != m_NoPoint)
                {
                    aSnake.Add(point);
                }             
                else
                {
            
                (  Array.Reverse(m_aPoint, 0, m_aPoint.Length);

                }
                nIterations++;
            }
            return aSnake;
        }

        /// <summary>
        /// Finds the start point.
        /// </summary>
        /// <returns></returns>
        private Point FindStartPoint(int _nXStart)
        {
            bool bFound = false;
            Color color = Color.Transparent;
            int nYStart = 0;
            //Find start point
            for (int y = 0; y < m_nHeight; y++)
            {
                color = m_Bitmap.GetPixel(_nXStart, y);
                if (color == m_Color)
                {
                    nYStart = y;
                    bFound = true;
                    break;
                }
            }
            if (bFound)
            {
                return new Point(_nXStart, nYStart);
            }
            else
            {
                return m_NoPoint;
            }
        }

        /// <summary>
        /// Gets the next connected pixel.
        /// </summary>
        /// <param name="_bitmap">The _bitmap.</param>
        /// <param name="_ptActualPixel">The _PT actual pixel.</param>
        /// <param name="_ptLast">The _PT last.</param>
        /// <param name="_color">The _color.</param>
        /// <returns></returns>
        public Point GetNextConnectedPixel(Point _point, ref int _nStartDirection)
        {
            int nX = _point.X;
            int nY = _point.Y;

            int nXTemp = -1;
            int nYTemp = -1;

            Point pointTemp = m_NoPoint;

            IEnumerable<int> aInt = m_aInt[_nStartDirection];
            foreach(int i in aInt)
            {
                pointTemp = m_aPoint[i];
                nXTemp = nX + pointTemp.X;
                nYTemp = nY + pointTemp.Y;

                if (nXTemp < 0 || nYTemp < 0 || nYTemp > m_nHeight - 1 || nXTemp > m_nWidth - 1) continue;

                if (m_Bitmap.GetPixel(nXTemp, nYTemp) == m_Color)
                {
                    _nStartDirection = i;
                    Debug.WriteLine(new Point(nXTemp, nYTemp).ToString() + " " + _nStartDirection);
                    return new Point(nXTemp, nYTemp);
                }
            }
            return new Point(-1, -1);
        }
    }
}


19.04.2010 - 14:49 Uhr

Konturverfolger / contour finder / contour tracer / boundary tracing

Wenn von einem Konturverfolger = contour finder = tracer = boundary tracing die Rede ist, dann ist heutzutage meist der Chain Code Algorithmus gemeint.

19.04.2010 - 14:48 Uhr

@Th69: Danke für den Hinweis. Wikipedia schaue ich mir meist zuerst an. Nur in speziellen Bereichen kommt es vor, dass Wikipedia auch nicht immer passt oder dass einfach die Dokumente verschiedene Transformationsformeln benutzen. Wenn aber quasi FAST exakt die gleiche Formel benutzt wird (1 Wert ist anders) dann wird es oft etwas schwierig.

Mir geht es also dann nicht um die Umsetzung an sich anhand der Dokumentation, sondern um die Validierung. (Hab ich die richtige Formel gefunden?)

Schließlich hab ja in diesem Fall nicht ich die Dokumentation gemacht.

Ich hoffe ich habe mich verständlich ausgedrückt. Mir ist es einfach wichtig, dass zumindest die Ausgangsformeln für das was ich programmiere richtig sind. 😉

Aber da sind hier ja jede Menge Leute die einen normalerweise daruf hinweisen. 😃))

16.04.2010 - 19:59 Uhr

Ebenen wechseln: Bild auf/Bild ab

14.04.2010 - 14:24 Uhr

Was hast Du bisher im Internet, s. Google gefunden?

Was möchtest Du erreichen? Vielleicht brauchst Du das gar nicht? Oder willst Du ein Programm schreiben das genau das kann?

12.04.2010 - 15:06 Uhr

@Jack30Lena und alle anderen. 😃:

Ich muss/möchte nicht unbedingt ein Programm schreiben, dass das kann. Mich hatte nur jemand neutlich danach gefragt und ich mußte gestehen, dass ich keine
großartig andere Antwort als:

theoretisch wäre es möglich, wenn du dich durch de nkompletten stacktrace hangelst und die instanzen mitverfolgst, welche gerufen wurden, das ist jedoch aufgrund der doch recht frequenten native-code übergängen in den allermeisten fällen nciht möglich.

deine hatte.

Außerdem hatte ich ja Profiler Code schon durch

Ist so etwas ohne Profiler Code möglich? Und wenn ja, wie?

Und aspektorientierte Lösungen meine ich in dem Fall ausnahmsweise auch nicht.

😉

12.04.2010 - 11:24 Uhr

Sehr interessant was ihr so alles kostenlos macht. Ich habe schon ein paarmal Programme für Freunde geschrieben, da das dann aber alles ziemlich zeitaufwendig wurde ("Könntest Du noch schnell [...] da reinmachen")
hab ich das inzwischen gelassen.

Was ich aber immer gerne mache sind Beratungen/Gespräche betreffs Software-Entwicklung. Das hat bisher auch noch nie was gekostet.

12.04.2010 - 11:18 Uhr

Jetzt mal eine Frage, bei der es nicht um den Sinn geht, sondern um die Machbarkeit an sich:

Es soll während wir uns in Klasse B befinden ein Objekt von Klasse A geholt werden dass auch dort als Field erstellt wurde,
ohne dass A und B sich kennen.
Es gibt keine EventHandler und kein Singleton.

Dabei darf nur Code in DoSomething geändert bzw. ausprogrammiert werden.

D.h. der Mechanismus muss zur Laufzeit alle Objekte von Klasse A ermitteln.

Ist so etwas ohne Profiler Code möglich? Und wenn ja, wie?

Da Code mehr sagt als 1000 Worte:


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace ObjectCoding
{
    public partial class Form1 : Form
    {
        private int m_nValue = 42;
        
        public Form1()
        {
            InitializeComponent();

            //Sollte, wenn alles funktioniert m_nValue und 42 ausgeben
            new ClassWhereWeAreNow().DoSomething();
        }
    }
}


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

namespace ObjectCoding
{
    public class ClassWhereWeAreNow
    {
        /// <summary>
        ///hier die Methode integrieren um die Objekte aus A (Form1) zu lesen.
        /// </summary>
        public void DoSomething()
        {
            //hier sollten dann die Namen der gelesenen Objekte ausgegeben werden.
        }

    }
}


Wie vorhin schon gesagt, es geht nicht um den Sinn. Sondern nur darum: Ist es machbar?

EDIT: Mein Versuch bisher: zu versuchen über StackTrace/StackFrame an die entsprechende Stelle zu kommen.

07.04.2010 - 10:51 Uhr

@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.

06.04.2010 - 19:01 Uhr

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

05.04.2010 - 14:15 Uhr

Hier noch der versprochene Code (s. mein Post weiter oben):

03.04.2010 - 10:23 Uhr

@UbuntuPro wie Herbivore schon sagte:

bei einem Kamerabild, wird sich der genaue Farbwert je nach Beleuchtung und Blickwinkel ändern.

Dann mußt Du entweder einen Farbraum nehmen, bei dem die Helligkeit bzw. Intensität mehr oder weniger keine Rolle spielt oder Du normalisierst den RGB Wert und fragst auf diesen ab.

Normalisieren eines RGB-Farbwerts funktioniert so:

int nRGBSUm = r+b+n
double dr = r / nRGBSum;
double dg = g / nRGBSum;
double db = b / nRGBSum;

Wenn Du das wieder auf einen normalisieren RGB Wert haben möchtest kannst Du zusätzlich noch wieder mit einem Faktor malnehmen. Ansonsten musst Du bei den Double Werten nachsehen, welcher Wert für Dein Pinkes Pixel der richtige ist.

Dann wird die Spanne die Du überprüfen musst relativ klein, denn Du nimmst quasi die Intensität durch die Normalisierung aus den Pixeln raus.

Man muss also mit einer gewissen Spannbreite suchen. Außerdem wird nicht nur exakt ein Pixel die gesuchte Farbe haben sondern mehrere.

Dann nach Blobs filtern.

02.04.2010 - 16:00 Uhr

Ich frage mich nun, warum es bei IPv6 kaum Bewegung gibt? Und warum die Standardisierung nicht weiter voranschreitet, obwohl das Problem immer drängender wird? An sich denke ich, dass es die Aufgabe der Provider ist, die Einführung von IPv6 zu forcieren. Aber das scheinen sie nicht zu tun. Daher frage ich mich, was ich und jeder von uns tun kann, um das drohende Schicksal des Internets abzuwenden?

Es ist immer das gleiche, solange es nicht wirklich knallt, wird nichts gemacht, d.h. spätestens dann wenn man nicht mehr ins Internet kommt, wird darüber nachgedacht werden. In der C't war dazu ein Bericht, der auch aussagte, man sollte lieber die Chance nutzen, vor allem wenn es einem wichtig ist, neben her quasi zu migrieren.

Die Kosten, die später entstehen wenn man IPv6 verschlafen hat, wenn es dann wirklich zum Standard geworden sein sollte, können immens sein.

IMHO sind Deine Bedenken mehr als gerechtfertigt, aber es nutzt nichts, ist wie in gewissen Themen mit Ideen der Mitarbeiter und der Nichtumsetzung.

Zitat: Der Prophet gilt meist nichts im eigenen Land.

02.04.2010 - 10:13 Uhr

Also ich hab das jetzt mal ausprobiert. Die Ergebnisse sind gleich deutlich besser. Mit einer Größe von 7x7 erreiche ich in 2 Durchläufen einen schönen Schatten für kleine Fenster. Nach einem Durchlauf sieht es noch nicht so schön aus, was aber an meiner Matrix liegen kann: Ich hab einfach überall eine 1 gesetzt.

Ein größeres Fenster (nennt sich so) mit 7x7 sollte auf jeden Fall eine Besserung bringen.

Für mehrere Durchläufe braucht man die n-fache Zeit, größere Matrizen erfordern dagegen deutlich mehr Zeit, da für jeden Punkt im Zielbitmap quadratisch viel mehr Punkte im Ursprungsbild gelesen werden müssen.

Nicht unbedingt, die Antwort(en) darauf lautet(-en):

Wenn man eine größere Matrix hat, sollte man im Idealfall jedes Pixel trotzdem nur einmal lesen, am besten so, dass wenn man die entsprechenden Pixel gelesen hat, schon das richtige Ergebnis für das gewählte quadratische Fenster (z.B. 7x7)
erhält.

Außerdem ist folgendes interessant, wenn die Matrix auf eine Weise symmetrisch ist, kann man sich durch das Wissen von:

212 2
212 *x = 2 * 212 * x
212 2

Zeit sparen.

Das bedeutet nur für symmetrische Matrizen kann man zuerst mit dem horizontalen Vektor (ich weiß den richtigen mathematischen Begriff nicht mehr) dann mit dem vertikalen multiplizieren.

Du solltest z.B. dann auf jeden Fall OHNE KOMPLETTE OPTIMIERUNG bei einem Fenster von 7x7 nicht auf das 49fache an Laufzeit kommen, sondern maximal auf das 7-fache.
Also bei WindowDimension = n auf n. Mit Optimierung natürlich deutlich drunter. Irgendetwas im Sinne von ≤2n MUSS drin sein.

Wenn man nur bestimmte Bereiche des Bilds unschärfen will, kann man den
Arbeitsbereich aber auch durch eine Region eingrenzen, was Zeit spart.

Das nennt sich dann ROI (region of interest)

02.04.2010 - 10:05 Uhr

@PaulBreitner: Warum benötigst Du genau dieses Verhalten, worum geht es in Deinem Programm? Dann können wir Dir evtl. sagen, ob eine andere Lösung evtl. besser wäre.

02.04.2010 - 10:04 Uhr

@All:

Ich finde, um das Verhältnis und die Art Code/Kommentierung zu sehen, sind auch größere Projekte für die ein immerwährendes Verständnis wichtig sein sollte,

kann sich ja mal den Source-Code und die Kommentare von PostSharp / AForge.net oder SharpDevelop ansehen.

02.04.2010 - 09:56 Uhr

Was für ein Panzer!? Wenn das ein Militärprojekt ist, bin ich nicht autorisiert. 😉

Und hat Dir das momentan weitergeholfen.

02.04.2010 - 09:54 Uhr

@Gwar

Hallo zusammen,

[...]anders aussieht (bspw. sollen die Ecken abgerundet dargestellt werden, ähnlich wie manche Eingabefelder bei Apple).[...]

s. dazu u. a. Skins oder suche nach "runde controls" oder "Form mit runden Ecken" u. ä.

Da die Standardtextbox ja nur ein Wrapper des Standard-Windows-Controls ist, klappt das Überladen der OnPaint() Methode ja nur bedingt. Ich vermute , dass es in meinem Fall auch nicht sinnvoll ist, da der Text (per Anforderungsdefinition) "Anti-Aliased" dargestellt werden soll.

In gewisser Weise stimmt das und wenn Du die Funktionalität von OnPaint komplett abschaltest mußt Du natürlich auch das ganze Verhalten integrieren.

Ich bin daher dazu übergegangen direkt von Control zu erben und die Funktionalität von Hand nachzubilden - auch, wenn das viel Arbeit bedeutet.

Ok, Du hast also diesen Weg gewählt. Es gäbe aber auch noch eine ganz andere Alternative mit einer unsichtbaren Richtextbox.
s. dazu:

[gelöst] Richtextbox Inhalt ohne Control auf Canvas darstellen/zeichnen

Dann kannst Du die Richtextbox komplett den Text zeichnen lassen, gibst aber nur das was Du sehen möchtest in deinem eigenen abgeleiteten Control aus, d.h. die Richtextbox ist nicht wirklich sichtbar.

Komposition:


public class CustomTextBox: Control
{
   RichTextBox m_richTextBox = new RichTextBox();
   [...]
    //sonstiger Code.
   [...]
}

Nun bin ich aber an einem Punkt angelangt, wo ich nicht ganz weiter komme: beim Vertikalen Scrollen von Text. Jeder kennt das Verhalten: bei der Texteingabe scrollt der Text an der Position des Cursors mit, sobald die Breite des Textes die Breite der TextBox überschreitet. Auch mit den Pfeiltasten kann man den dargestellten Text so scrollen. Analog gilt dies auch für das Horizontale Scrollen bei mehrzeiligen Eingabefeldern. Denkbar ist ähnliches Verhalten auch mit Scrollbalken.

Dazu gibts mind. 2 mögliche Antworten: Bei der Variante mit der RichTextBox ist das Problem quasi gar nicht vorhanden, bei Deinem Ansatz würde ich mir die TextEditor Komponente von SharpDevelop ansehen. Und den Ansatz herausziehen oder vielleicht nimmst Du die Komponente komplett um das Aussehen zu verändern.

Ich habe im .Net Fragewort leider keine Möglichkeit gefunden, dies zu realisieren, zumal Buchstaben ja auch "teilweise" gezeichnet werden müssten, sobald der Text (begrenzt durch die Größe der TextBox) nur teilweise dargestellt wird.

Ich könnte auch noch eine Komponente hier reinschicken in der ich ansatzweise versucht habe einen Texteditor komplett nachzubilden. Das entspräche dann Deinem momentanen Ansatz. Ok, ich werd sie hier posten.

Ich wäre äußerst dankbar, falls mir jemand einen Tipp geben könnte, wie ich dies realisieren kann. Alternativ bin ich dankbar für Tipps, die mir helfen, den hohen Aufwand des kompletten Tastaturhandlings zu umgehen.

Klar, wenn Du ALLES selbst machst....

Jetzt hast Du zumindest ein paar Anregungen. Implementieren musst Du selbst. 😉
Viel Erfolg.

02.04.2010 - 09:45 Uhr

@realpk:

Um konkret auf Deine Fragen einzugehen:

Hallo, danke für die Antworten. Aber ich bin etwas verwirrt. Ich habe doch geschrieben, dass ich keinen SVG -> XAML Konverter suche Baby

Das hatte ich verstanden. Deshalb habe ich Dir das Projekt von CodeProject vorgeschlagen.

Mir geht es darum ein SVG in einem Control anzuzeigen. Dieses Control möchte ich in einem WPF UserControl nutzen.

Das kannst Du ja mit diesem Projekt.

Gibt es sowas nicht von Haus aus?
Ich habe gehoft, dass ich es nur einfach übersehe.

Nein, das gibt es nicht. Da ich viel mit Grafikprogrammierung usw. mache wäre das mir sonst ganz sicher in den letzten 5 Jahren über den Weg gelaufen.

Wichtig noch:

Willst Du später auch selbst zur Laufzeit an den angezeigten Daten etwas verändern?
Wenn das irgendwann später in Deinem Programm vorkommt, solltest Du nämlich selbst gleich nach einer Komponente suchen, die so etwas auch bietet.

Viele Grüße dr4g0n76

01.04.2010 - 14:47 Uhr

@UbuntoPro:

"Dazu muss das ist das dann ein Pixel mit Pinker Farbe."

Erstens: Dieser Satz ist unvollständig. Könntest Du denn bitte nochmal ausschreiben? Aber ich glaube ich weiß was Du möchtest.

Du möchtest wissen, wo Pink im Bild ist. Wenn es wirklich nur jeweils ein Pixel ist, der Pink ist reicht es so in der Art (Pseudocode):


hier x definieren
hier y definieren
für alle pixel in y richtung
   for alle pixel in x richtung
        hole farbe pixel(x,y)
        wenn pixel farbe = pink Break;
   nächstes x
nächstes y

Point pinkesPixel = new Point(x,y);

Wie soll das ganze Programm genau funktionieren? Dann können wir Dir hier besser weiterhelfen. Bitte genauere Infos. Was soll der Autopilot machen? Wie funktioniert er? Wird er im Auto eingesetzt oder ist das nur eine Simulation usw.!?

01.04.2010 - 09:49 Uhr

@techno_prog:

"Steam verbindung" soll das insgesamt wirklich noch eine Steam-Verbindung mit "Steam" von Valve aufbauen oder hast Du dich da nur vertippt und es geht nur um die Webcam und das hier im Thread im ersten Post von Dir geschriebene?

01.04.2010 - 09:47 Uhr

s. auch hier:

Farbe von TabControl ändern?

Und ab jetzt:

Suche mal bitte selber im Forum und poste die besten Treffer hier, danke.

31.03.2010 - 14:05 Uhr

Dieser Link zeigt wie man manche Farbeigenschaften verändern kann:

BackColor TabControl

s. auch:

[Artikel] Custom Window Border für Form's

Möglicherweise reicht es auch schon die Border des TabPages auf "Flat" zu setzen.
bzw. dies zu setzen:


            Dim t As TabPage
            t.BorderStyle = BorderStyle.FixedSingle 

Sind nur verweise, wo die wirkliche Lösung gefunden werden könnte.

Weitere Idee, mittels von Control-Render-Funktionen?

Vielleicht findest Du so ja was.

30.03.2010 - 15:05 Uhr

Erzeuge doch ein Thumbnail von den gefundenen Bildern, wenn es eh nicht in der realen Größe angezeigt werden muss.

Offtopic:
Außerdem sollte das Application.DoEvents raus und falls Du einen Thread benötigen solltest, der entsprechende Code in den Threa ausgelagert werden.

30.03.2010 - 10:31 Uhr

Frage vorweg:
Gibt es eine Möglichkeit Graphics.FromImage auf ein Bild zu verwenden, während man die Bitmap im Unsafe-Mode bearbeitet, ohne das Bild dann wieder zuvor mit Unlock freigeben zu müssen?
**
Grund:**

Momentan mache ich umfangreiche Änderungen in der LowLevelGraphicsLibrary.

Dabei kam immer wieder auf, dass Objekte auf ein Bild gezeichnet werden sollten. Z.B. gefüllte Rechtecke, um das Bild zu vergröbern.

Problem:

Wenn man jetzt versucht - ohne Unlock - über Graphics.FromImage auf das Bild zu zeichnen, kommt immer ein Fehler in der Art:

Der Bitmapbereich/Das Bitmap ist schon gesperrt.
**
Vermutung:**

Das lässt vermuten, dass die einzelnen GDI bzw. GDI+-Befehle die Bitmap ebenfalls sperren, um ihre Operationen durchzuführen und diese dann wieder freigeben.

z.B. wird


public void DrawRectangle(Pen pen, int x, int y, int width, int height)

in


    int status = SafeNativeMethods.Gdip.GdipDrawRectangleI(new HandleRef(this, this.NativeGraphics), new HandleRef(pen, pen.NativePen), x, y, width, height);
    this.CheckErrorStatus(status);

übersetzt.
**

Mein Kenntnisstand:**

ist bisher, dass es nicht möglich ist, beides zu kombinieren ohne
vorher ein Unlock zu machen.

Normalerweise geht das meines Erachtens so:


lock
unsafe operation 1...
unlock
GDI operation 1
lock
unsafe operation 2
unlock
GDI operation 2
lock unsafe operation 3
...

usw.

Habe aber an 2 oder 3 Stellen im Internet gelesen, dass das angeblich gehen soll, wenn man für Lock das richtige angibt...!?

Auf jeden Fall hat mich für das erste nachsehen im Reflector bei den GDI-Operationen diesbezüglich noch nicht wirklich weitergebracht.

EDIT: hinzugefügt:

Meine Momentane(n) Lösung(en):

Meine Lösung für dieses Problem ist momentan folgendes:

  1. Lösung) Das Bild wird ab der Stelle an der eine GDI-Funktion benutzt werden soll
    durch Unlock ENTsperrt, dann gezeichnet und falls dann weitere Operationen
    folgen sollen wieder GEsperrt.

  2. Lösung) Das Bild bleibt gesperrt, die Routinen werden durch eine weitere Klasse
    die die zu zeichnenden Punkte ermittelt (z.B. über Bresenham Algorithmen)
    übernommen. Deswegen muss das Bild auch nicht entsperrt werden an dieser
    Stelle.

27.03.2010 - 17:10 Uhr

@Gfoidl:

Hab erst heute diese Frage von Dir wiederentdeckt.

Ich hatte damals die Idee, ausgehend von der aktuellen Pixelposition (Im ROI linke obere Ecke) pixel nach unten/oben und links/rechts zu suchen, die ungefähr die gleiche Eigenschaft haben (z.B. ähnliche Farbe oder gleicher oder ähnlicher Grauwert).

Hab ich was gefunden wird mit

                n1DX = Math.Abs(x - nXLeft);  
                n2DX = Math.Abs(x - nXRight);  
                n1DY = Math.Abs(y - nYBottom);  
                n2DY = Math.Abs(y - nYTop);  

                int nDX = Math.Abs(n1DX - n2DX);  
                int nDY = Math.Abs(n1DY - n2DY);  

eine Zuordnung von new Point(x, y), n1DX durchgeführt. Das heißt der Kreis am Punkt x,y hätte den Radius n1DX.

Diese Punkte werden bei der weiteren Bearbeitung des Bildes jetzt ignoriert.

Dann geht der Ansatz von vorn los.

Und das war damals, als Du hier fragtest der erste Ansatz. 😃

EDIT: es entspricht ungefähr dem angehängten Bild.
Bestimme das Rechteck, dann den dazugehörigen Kreis.

_Abkürzung:

ROI = Region of Interest_

26.03.2010 - 12:32 Uhr

Wenn Du uns mitteilst, warum Du zuerst eine Suche machst und dann die Ersetzung oder was Du eigentlich genau vorhast, gibt es bestimmt eine performante Lösung.

26.03.2010 - 10:59 Uhr

@Herbivore:

in der Kürze liegt die Würze! Da die durchschnittliche Aufmerksamkeitsspanne im Netz ohnehin deutlich kürzer als 10min sein dürfte, wärst du gut beraten, wenn du den Inhalt der Videos so kompakt gestaltest, dass sie (deutlich) kürzer als 10 Minuten sind ... und dann stellt sich dein Problem gar nicht mehr.

Es sind momentan ja 3 Videos und das Problem ist auch nur, dass diese 11 Minuten dauern und nicht 10.

Wenn dass parout nicht geht, solltest du die Videos splitten, aber nicht nur wegen bzw. stur bei der 10-Minuten-Grenze, sondern inhaltlich nach Themengebieten. Das hat auch den Vorteil, dass sich die Zugänglichkeit erhöht, indem der Benutzer sich nur die Teile ansehen muss, für deren Themen er sich interessiert.

Deswegen sind es 3 Videos. WEIL sie eben verschiedene Themenbereiche abdecken.

Auch diese Vorgehensweise trägt der kurzen Aufmerksamkeitsspanne im Netz auf ihre Weise Rechnung.

Deine Antwort ist aber insofern nützlich, dass ich anders vorgehen werde.

Die Videos part 1 und part 2 behandeln mehrere Themenbereiche, zwar nicht grob unterschiedlich, aber ca. 5,5 Minuten 1. Thema, dann das 2. Thema. Und im 2. Video genau so.

Ich werde diese nochmal machen und dann nur jeweils einen Themenbereich pro Video anbieten.

Ok, das hilft mir soweit auch, dann bleibt Video 1 (Image scripting console vorerst so wie es ist)

Und die anderen werden anders gegliedert.

Danke.

Und @all:

Danke für die Vorschläge mit den Plattformen einige davon kannte ich noch nicht und werde diese trotzdem ausprobieren.

25.03.2010 - 19:08 Uhr

@talla: Ja direkt ansehen ist am besten. IMHO. 😃

25.03.2010 - 17:45 Uhr

**Frage vorweg:

Wo kann ich meine Videos kostenlos hochladen, auch wenn diese länger als 10 Minuten laufen!?**

Grund:

Jemand war so freundlich mich darauf hinzuweisen, dass die Videos die ich hier

LowLevelGraphicsLibrary
(momentan letzter Post in diesem Thread)

gepostet hatte, nicht funktionieren.

Der Grund dafür ist, dass keine Videos mehr in youtube von mir hochgestellt werden dürfen die länger als 10 min. sind.

Ich hab dann myvideo.de und videolicious.com und noch ein paar weitere ausprobiert.

Aber immer das gleiche Problem, entweder erhalte ich die "10-Minuten-Beschränkung-Fehlermeldung" oder mein Video wird einfach nicht hochgeladen.

23.03.2010 - 17:56 Uhr

@Dawamaha: Was willst Du denn genau damit anstellen, mit den MIDI-Werten der Noten?
Vielleicht ist der Enum ja nicht das richtige.

23.03.2010 - 11:50 Uhr

Hier gibt's inzwischen ebenfalls eine Prolog Implementierung für .NET:
[URL=http://prolog.hodroj.net/[/url]Prolog.NET[/url]

Und genau das was hier in diesem Thread erreicht werden sollte, ist wohl inzwischen auch mit diesem Projekt möglich.


using System;
using Prolog.Assembly;
using Axiom.Runtime; // required only for AbstractTerm
namespace PrologAndMath
{
class Program
{
static void Main(string[] args)
{
MyMath math = new MyMath();
// Calculate the factorial
AbstractTerm a = new AbstractTerm();
math.factorial(3, a);
Console.WriteLine("Factorial of 3 is: " + a);
// calculate the fifth fibonacci (should be 8)
AbstractTerm fibValue = new AbstractTerm();
math.fib(5, fibValue); // this is like fib(5, X) in Prolog
Console.WriteLine("Fibonacci of 3 is: " + fibValue);
}
}
}