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

26.07.2010 - 15:33 Uhr

Hallo Kollegen,

ich hatte 2007 einen Client für einen bestimmten Chat entwickelt. Er funktioniert aber inzwischen nicht mehr, da sich der Chat natürlich auch weiterentwickelt hat.

Da ich immer noch viele kontakte darüber herstelle und inzwischen wieder viel in diesem Chat drin bin, würde ich diesen gerne wieder zum Laufen bringen.

Inzwischen ist die Situation so:

1.)
Über ein Java-Applet in dem die Texte dargestellt werden, wird alles angezeigt. Hier laufen die Nachrichten nach unten die aus dem Channel kommen, in dem man sich befindet. Jede Nachricht eines Users verschiebt diesen Text nach unten.

2.)
Zusätzlich gibt es noch eine Textbox für die eigenen Eingaben.

Jetzt mein Problem:

Ich möchte das bei 1.) beschriebene Fenster mit dem Text auslesen.
Ich hab das aber noch nie auf diese Art im Browser ausprobiert. Versucht habe ich es in IE und im FireFox. Ich finde zwar das Fenster (Hab ich zuerst per Spy++) ausprobiert, aber wenn ich mir über ein WM_GETTEXT den Inhalt des textfensters holen möchte ist der String leer.

Jetzt hab ich schon öfter gelesen, dass Firefox und andere Browser alles selbst zeichnen. (Den Inhalt). Ist das der Grund warum ich keinen text bekomme?

Oder ermittle ich das Fenster falsch?

Das Fenster das ich erhalte ist vom Typ MozillaWindowClass wenn ich den FireFox benutze.

Momentan habe ich auch probiert, direkt die ID des Handles anzugeben, dass mir Spy++ ermittelt. Denn das sollte ja das richtige Fenster sein, oder evtl. ein Untercontrol davon. Beides funktioniert bisher nicht.

21.07.2010 - 14:38 Uhr

Für alle die es noch nicht kennen, weil ich vor kurzem darauf aufmerksam wurde:

Elevate

Auszug der Beschreibung:

Let’s face it, no library has it all, and the BCL is no exception. If you’re anything like me, then you occasionally find yourself re-writing some utility methods over and over again for each project that you work on. Even though you know it’s wrong, you probably re-invent the wheel from time to time for “simple” things. Maybe you carry around your own “MyUtilities.cs” file from project to project. Either way, in the back of your mind, you know that there has to be a better way.

For C++ programmers, this void is filled with Boost. Boost contains a lot of functionality that is missing from the C++ STL for one reason or another. It’s a great library for C++ development. But what about us poor C# developers?

That’s where Elevate comes in. Elevate is a Boost-like library for .NET. Our goal at SRT Solutions is to capture the things that we think are missing from the BCL and put them in Elevate so that we can share them between our project groups and the rest of the world. By devoting some of our weekly learning time to add these common bits of code to Elevate, we can save ourselves, our clients, and hopefully other .NET developers time and money.

Kurz in eigenen Worten ein paar konkrete Beispiele:

Wenn ein paar Werte und eine "Sequenz" von Werten in eine neue "Sequenz" kopiert werden sollen, dann kann das mit Elevate folgendermaßen geschehen:


 //if you have a couple sequences of values
 var first = Seq.Build("alpha", "beta");
 var second = Seq.Build("delta", "epsilon");

 //you can combine them along with some other values to create a new sequence
 var result = Seq.Build(first, "gamma", second, "zeta");

Schön ist das man ein IEnumerable des generischen Typs erhält, dann man durchiterieren kann.

Komfortabel sind auch die Option Types, mit denen man einen Programmieraspekt von F# bezüglich des Patternmatchings für C# verfügbar gemacht hat.


var values = 0.Through(10); 
Option<int> result = values.TryFind(x => x == 5);

Zeile 1 im obenstehenden Code generiert eine aufsteigende Zeichenfolge.
(0,1,2,3,4,5,6,7,8,9,10)

Zeile 2 findet in dieser Sequenz den Wert 5.

Option Types nochmal kurz zur Erklärung Auszug aus einem Artikel über F#:

Simply put, an option type wraps a value with information indicating whether or not the value exists. For C# or VB programmers, it may be convenient to think of option types as a mutant cross between .NET 2.0 nullable types and the null object design pattern.

Und der Link dazu, falls jemand bei F# nachlesen möchte, was Option Types sind:

Why I love option types (F#)

Ein weiteres interessantes Konstrukt bilden dabei die LINQ-Erweiterungen.

//we can apply a selector function to each element based
//on the element's value and it's index
var result = values.SelectWithIndex((index, value) =>
value / (index + 1));

20.07.2010 - 15:52 Uhr

@Fzelle: Genau auf diese Lösung bin ich inzwischen auch gekommen.

Und zwar mache ich das per Script.
Am Anfang wird jetzt:


use master

benutzt.

Ich werde es hier als Lösung, wenn ich die kürzeste richtige Version gefunden habe, hier posten.

20.07.2010 - 15:50 Uhr

Alternativ dazu kannst Du auch noch hier:

[gelöst] Lambda Funktionen in einem Script bzw. zur Laufzeit kompilierten Code.
(Stichwort: ScriptCompiler2)

und hier:

LowLevelGraphicsLibrary (ebenfalls nach Stichwort ScriptCompiler2 suchen oder den Code herunterladen und darin suchen)

s. für das Prinzip auch:

Objekte an Laufzeit kompilierten Code übergeben oder auslesen (allgemeine Kommunikation)

20.07.2010 - 13:16 Uhr

verwendetes Datenbanksystem: MSSQL 2000

Hallo Kollegen.

Ich verwende momentan untenstehenden Code, um eine Datenbank auszuhängen:
(ausnahmsweise in VB gepostet)

Dazu benutze ich den Befehl sp_detach_db, Microsoft schreibt dazu folgendes:

Außerdem steht ja bei Microsoft:

sp_detach_db (Transact-SQL)

Detaches a database that is currently not in use from a server instance and, optionally, runs UPDATE STATISTICS on all tables before detaching.

Der Befehl funktioniert an sich, aber ich bekomme folgende Meldung:

Cannot detach DB 'xxx' that is currently in use.

Und im Microsoft Zitat steht ja auch, dass das nur geht, wenn die Datenbank momentan nicht in Benutzung ist.

Seh ich alles ein, nur da ich gerade selber nicht direkt auf die DB zugreife, wie bekomme ich es hin, dass diese DB nicht in Benutzung ist?

  
 Public Function DetachDatabase(ByVal _sDatabaseName As String) As Integer  
            Dim sQuery As New StringBuilder(string.Format("EXEC sp_detach_db @DBName = N'{0}'",_sDatabaseName))  
            Dim command As New SqlCommand(sQuery.ToString(), CreateSQLConnection())  
            Dim nResult As Integer = command.ExecuteNonQuery()  
            Return nResult  
        End Function  
  
20.07.2010 - 13:12 Uhr

Alternative ist:

sp_helpdb

Ausgabe, s. Screenshot

19.07.2010 - 17:56 Uhr

Announcing Postsharp 2.0 RTW

Interessant dürfte für viele zu Lesen sein, dass Postsharp inzwischen als Version 2.0 zur Verfügung steht

hier ein Auszug der interessantesten Features:

New features of PostSharp 2.0 over 1.5 include:

* Visual Studio Extension – for easier code reading  
* Composite Aspects (Advices and Pointcuts) – for more powerful aspects  
* Adaptive Code Generation – for better runtime performance  
* Aspect Dependencies – to prevent conflicts between aspects in large projects  
* Interception Aspects for Fields, Properties, and Events  
* Instance-Scoped Aspects  
* Build-Time Performance Improvements  

For a detailed list of these features, see What’s New in PostSharp 2.0.
How To Upgrade from 1.5?

PostSharp 2.0 contains a library called PostSharp.Laos.dll. This is an emulation layer, and is meant to be used during the migration of 1.5 to 2.0. When you’ll build your project, you’ll get a lot of obsolescence warnings. When all these warnings are gone, you can remove the PostSharp.Laos.dll reference from your project. It’s only after complete migration that you will see improvements in runtime performance.
What’s New Since RC2?

The following issues were fixed:

* Invalid code generation when two MethodInterceptionAspects are applied on a method containing an anonymous method.  
* Invalid code generation for pointer types (&#39;valuetype&#39; or &#39;class&#39; keyword missing)  
* Invalid code generation when an interception aspect is applied to a method containing a &#39;.constrained&#39; prefix  
* Invalid code generation when multiple MethodInterceptionAspects are applied to a generic method  
* When a method-level aspect is applied to an interface, it is not multicast to interface methods  
* ILASM failure with symbol sequence points with a document but without a column  
* KeyNotFoundException from MulticastAttributeTask.ImportCustomAttribute
16.07.2010 - 19:04 Uhr

Ich würde eine Perimeteroperation benutzen. Den Code kann er sich aus der Library extrahieren.

15.07.2010 - 14:44 Uhr

Hatte den falschen Link. Jetzt müsstest Du drauf klicken können. Versuchs nochmal.

15.07.2010 - 14:35 Uhr

@Dennisspohr du kannst auch hier nachsehen:

LowLevelGraphicsLibrary

falls Du vielleicht einige Filter verwenden möchtest, die so nicht so einfach zu realisieren sind. Allerdings verwendet diese Library an vielen Stellen eine Per-Pixel-Methode im unsafecontext.

Also als wirklich langsam würde ich das nicht gerade bezeichnen bei konkret diesen Filtern.

EDIT: Link korrigiert.

15.07.2010 - 14:29 Uhr

@Blackhawk5000: Danke für das Kompliment. Falls Du versuchst das mit der Lib zu lösen kannst Du auch gerne PMs schicken und wir veröffentlichen dann die Antwort hier im Forum.

05.07.2010 - 13:32 Uhr

An der Stelle an der Deine neue Grafik generiert wird, also wenn der User etwas verändert, wird da

InvalidateRect aufgerufen?

Über ein Applikationsfenster "schreiben"

01.07.2010 - 17:47 Uhr

Mache regelmäßig Kraftsport im Fitness-Studio. Bis zu 5 Einheiten die Woche, die letzten Monate nur 2 mal pro Woche, zu viel Zeit am Projekt in der Firma verbracht.

28.06.2010 - 23:17 Uhr

verwendetes Datenbanksystem:MS SQL 2000

Wir benutzen in der Firma leider immer noch MS SQL 2000.

Ich möchte gerne per Notification Services Events einrichten in meiner Applikation.
Der Code existiert quasi schon.

Die Frage ist nur, wie bekomme ich die Notification Services FÜR SQL 2000 installiert?
Mir fehlen die Dateien, um es nachzuinstallieren.

Was ich bei Microsoft gelesen habe, bringt mich momentan nicht weiter, angeblich gibt es auch die Downloads noch online, aber alle Links auf die Microsoft für SQL 2000 verweise funktionieren nicht.

Habe folgende Suchbegriffe in Google benutzt:

MS SQL 2000 "Notification Services"
Microsoft SQL 200 NS
Microsoft SQL 200 "Notification Services"

u. ähnliche Varianten

P.S.: der Namespace

using Microsoft.SqlServer.NotificationServices;

ist deswegen auch noch nicht vorhanden....

26.06.2010 - 18:39 Uhr

Normalerweise sollte das so funktionieren, ohne zusätzliches zutun. Es reicht im Designer in ContextMenuStrip ein Hintergrundbild einzufügen.

Das Bild verschwindet normalerweise auch nicht.

26.06.2010 - 18:32 Uhr

unter WPF:

s. auch hier:

ToolTip Placement

Unter windows forms:

hier kann in ToolTip Rectangle u anderen Properties angegeben werden, was benötigt wird:


using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
//using System.Windows.Forms;
using System.Collections;
using System.Text;
using System.Drawing;
using System.Windows.Forms;

namespace Library.Controls
{
	public class CAbstractToolTip: System.ComponentModel.Component,Interfaces.IToolTip, IExtenderProvider
	{
		[DllImport("user32.dll")]
		protected static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
		
		[DllImport("user32.dll")]
		protected static extern IntPtr GetWindowDC(IntPtr hWnd);

		[DllImport("user32.dll")]
		protected static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);

		[DllImport("user32.dll")]
		protected static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);

		[DllImport("gdi32.dll")]
		protected static extern int ExcludeClipRect(IntPtr hdc, 
			int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);
		[DllImport("user32.dll")]
		protected static extern IntPtr CreateWindowEx(int exstyle, string classname, string windowtitle, int style, int x, int y, int width, int height, IntPtr parent, int menu,
			int nullvalue, int nullptr);

		[DllImport("user32.dll")]
		protected static extern int DestroyWindow(IntPtr hwnd);

		[DllImport("User32.dll")]
		protected static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags);

		[DllImport("User32.dll")]
		protected static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, IntPtr lParam);

		[Serializable, StructLayout(LayoutKind.Sequential)]
		public struct RECT 
		{
			public int Left;
			public int Top;
			public int Right;
			public int Bottom;

			public RECT(int left_, int top_, int right_, int bottom_) 
			{
				Left = left_;
				Top = top_;
				Right = right_;
				Bottom = bottom_;
			}

			public int Height { get { return Bottom - Top; } }
			public int Width { get { return Right - Left; } }
			public Size Size { get { return new Size(Width, Height); } }

			public Point Location { get { return new Point(Left, Top); } }

			// Handy method for converting to a System.Drawing.Rectangle
			public Rectangle ToRectangle()
			{ return Rectangle.FromLTRB(Left, Top, Right, Bottom); }

			public static RECT FromRectangle(Rectangle rectangle) 
			{
				return new RECT(rectangle.Left, rectangle.Top, rectangle.Right, rectangle.Bottom);
			}

			public override int GetHashCode() 
			{
				return Left ^ ((Top << 13) | (Top >> 0x13))
					^ ((Width << 0x1a) | (Width >> 6))
					^ ((Height << 7) | (Height >> 0x19));
			}

			#region Operator overloads

			public static implicit operator Rectangle( RECT rect )
			{
				return Rectangle.FromLTRB(rect.Left, rect.Top, rect.Right, rect.Bottom);
			}

			public static implicit operator RECT( Rectangle rect )
			{
				return new RECT(rect.Left, rect.Top, rect.Right, rect.Bottom);
			}

			#endregion
		}
		
		protected struct Toolinfo
		{
			public int size;
			public int flag;
			public IntPtr parent;
			public int id;
			public Rectangle rect;
			public int nullvalue;
			[MarshalAs(UnmanagedType.LPTStr)]
			public string text;
			public int param;
		}
		
		// Used by some constants values, not by the code.
		protected const int WM_USER = 0x0400;
		
		protected const int TTM_ADDTOOL				= WM_USER + 50;		
		protected const int TTM_DELTOOL				= WM_USER + 51;		
		protected const int TTM_ACTIVATE				= WM_USER + 1;		
		protected const int TTM_SETMAXTIPWIDTH		= WM_USER + 24;	
		protected const int TTM_SETTITLE				= WM_USER + 33;
		protected const int TTM_SETDELAYTIME			= WM_USER + 3;
		protected const int TTM_UPDATETIPTEXT			= WM_USER + 57;
		protected const int TTM_SETTIPBKCOLOR			= WM_USER + 19;
		protected const int TTM_SETTIPTEXTCOLOR		= WM_USER + 20;
		protected const int TTM_GETTOOLINFO			= WM_USER + 53;
		protected const int TTM_SETTOOLINFO			= WM_USER + 54;

		protected const int TTS_ALWAYSTIP				= 0x01;
		protected const int TTS_NOPREFIX				= 0x02;
		protected const int TTS_BALLOON				= 0x40;

		protected const int TTF_SUBCLASS				= 0x0010;
		protected const int TTF_TRANSPARENT			= 0x0100;

		protected const int SWP_NOSIZE				= 0x0001;
		protected const int SWP_NOMOVE				= 0x0002;
		protected const int SWP_NOACTIVATE			= 0x0010;
		
		protected const int TTDT_AUTOPOP		       = 2;
		protected const int TTDT_INITIAL		       = 3;
		
		protected const int WS_POPUP					= unchecked((int)0x80000000);
		protected const int CW_USEDEFAULT				= unchecked((int)0x80000000);
		
		protected IntPtr TOPMOST						= new IntPtr(-1);
		
		private Image m_Image = null;
		private int m_nWidth = 0;
		private int m_nHeight = 0;
		private bool m_bOwnerDraw = false;
		private bool m_bShowAlways = false;
		private Color m_clFore = Color.Black;
		private Color m_clBack = Color.Transparent;
        private int m_nReshowDelay = 500;
        public event EventHandler Draw;                 //don't delete this, needed from the caller, not in need to use it here
		
		private System.ComponentModel.Container components = null;  //this has also be here, will be called from the infrastructure of the il
		
		private CControls m_ControlCollection = null;

		public CAbstractToolTip():base()
		{
			//this.Draw += new DrawExtToolTipEventHandler(ExtToolTip_Draw);
		}

		public CControls Controls
		{
			get
			{
				if (m_ControlCollection == null)
				{
					m_ControlCollection = new CControls();
				}
				 return m_ControlCollection;
			}			
		}
		
		public virtual IntPtr Handle
		{
			get{ return IntPtr.Zero;}
		}
		
		public virtual int Height
		{
			get { return m_nHeight; }
		}

		public virtual int Width
		{
			get { return m_nWidth; }
		}

		public Image Image
		{
			get { return m_Image; }
			set { m_Image = value; }//m_Image = new Bitmap(value, Height, Width); }
		}

		public void ExtToolTip_Draw(object sender,DrawExtToolTipEventArgs e)
		{
		}

		#region IToolTip Member

		public virtual bool Active
		{
			get
			{
				// TODO:  Getter-Implementierung für ExtToolTip.Active hinzufügen
				return false;
			}
			set
			{
				// TODO:  Getter-Implementierung für ExtToolTip.Active hinzufügen
			}
		}

		public virtual int AutomaticDelay
		{
			get
			{
				// TODO:  Getter-Implementierung für ExtToolTip.AutomaticDelay hinzufügen
				return 0;
			}
			set
			{
				// TODO:  Getter-Implementierung für ExtToolTip.AutomaticDelay hinzufügen
			}
		}

		public virtual int AutoPopDelay
		{
			get
			{
				// TODO:  Getter-Implementierung für ExtToolTip.AutoPopDelay hinzufügen
				return 0;
			}
			set
			{
				// TODO:  Getter-Implementierung für ExtToolTip.AutoPopDelay hinzufügen
			}
		}

		public virtual bool CanExtend(object oTarget)
		{
			// TODO:  Implementierung von ExtToolTip.CanExtend hinzufügen
			return false;
		}

		public object GetLifeTimeServer()
		{
			// TODO:  Implementierung von ExtToolTip.GetLifeTimeServer hinzufügen
			return null;
		}

		public string GetToolTip(Control control)
		{
			// TODO:  Implementierung von ExtToolTip.GetToolTip hinzufügen
			return null;
		}

		public virtual int InitialDelay
		{
			get{ return 0;}
			set{}
		}

		public void RemoveAll()
		{
			// TODO:  Implementierung von ExtToolTip.RemoveAll hinzufügen
		}

		public int ReshowDelay
		{
			get { return m_nReshowDelay; }
            set { m_nReshowDelay = value; }
		}

		public virtual void SetToolTip(Control control, string sCaption)
		{
			// TODO:  Implementierung von ExtToolTip.SetToolTip hinzufügen
		}

		public bool ShowAlways
		{
			get{ return m_bShowAlways; }
			set{ m_bShowAlways = value;}
		}

		public bool OwnerDraw
		{
			get{ return m_bOwnerDraw;}
			set{ m_bOwnerDraw = value;}
		}
		
		public virtual Color ForeColor
		{
			get{ return m_clFore;}
			set{ m_clFore = value;}
		}

		public virtual Color BackColor
		{
			get{ return m_clBack;}
			set{ m_clBack = value;}
		}
		#endregion

		public virtual Rectangle ClientRectangle
		{
			get{ return Rectangle.Empty;}
		}
		
		protected virtual void InitializeComponent()
		{
		}
		#region IDisposable Member

		#endregion
	}
}

26.06.2010 - 18:28 Uhr

Ich vermute, dass die extern angebundene Anwendung Dateien benötigt, die nicht im Projekt Verzeichnis von Dir liegen. (Initialisierungsdateien, DLL, sonstiges)...

Probier mal dein Projekt in das Verzeichnis der Anwendung zu kopieren,
kann jetzt ohne Probleme gehostet werden?

26.06.2010 - 18:25 Uhr

Hast Du mal versucht das GIF beim ImageAnimator anzumelden? (System.Drawing)

24.06.2010 - 12:18 Uhr

@Ralfw:

Betriebswirtschaftliche Sicht, volkswirtschaftliche Auswirkung, eindeutiges Umfrageergebnis... das ist alles richtig... aber es wird Rainbird und anderen wenig helfen. Es geht einfach nicht um "Objektivität" oder "harte Fakten".

Es wird ihm vielleicht nicht direkt helfen, aber die Nachfrage Rainbirds nach einer Studie - mit Ergebnis - würde ich doch als in diese Richtung gehend werten.

Das macht das Thema so nervig. Andererseits macht es das Thema aber auch interessant. Denn ich würde gern eruieren, was das Wurzelproblem bei den heutigen "Unit Test Verweigerern" ist. Ist natürlich schwer rauszufinden. Die selbst sind ja quasi per definitionem nicht in der Lage das zu reflektieren.

Hier ein paar Aussagen, die ich bisher aus mehreren Firmen gehört habe:

"Automatische Tests? Unit-Tests? Die muss man selber schreiben? Das kostet zu viel Zeit und verzögert das Projekt"

"Bis ich das alles eingerichtet habe...Puh! Was das Zeit kostet..."

"Was bringt das?"

Wie schon erwähnt wurde: Ablehnung neuem Gegenüber, Angst vor neuem, vielleicht auch ein wenig Zurückhaltung, um es mal nicht Faulheit zu nennen.

Naja... sei´s drum. Beim Testen sehe ich zu meiner Freude, dass es auf die Branche gerechnet eigentlich kein großes Thema ist. Es tun noch nicht alle, aber das liegt eher nicht an Unverständnis oder Unwille, sondern am Umfeld.

Wir können uns daher darauf konzentieren zu überlegen, wie das Umfeld für diejenigen noch verändert werden kann, dass sie es tun können. Die anderen, die Unwilligen, sind eine schrumpfende Randgruppe.

Damit stimme ich überein. Oder anders formuliert: Immer mehr widmen sich dem Thema UnitTests und es wird geprüft, was bringt es mir und dem Projekt und damit letztendlich der Firma.

22.06.2010 - 13:35 Uhr

@Rainbird: Um nochmal auf Deine Fragen zu Beginn zurückzukommen:

wenn man der Fachpresse glaubt, dann gehören Unit-Tests zum Guten Ton in der Branche und sollten quasi eine Selbstverständlichkeit sein. Ist das wirklich so?

Ja, es ist so dass diese eine Selbstverständlichkeit SEIN SOLLTEN. (Aber nicht SIND).

Ich selbst habe Zeifel am Nutzen von Unit-Tests, wenn man den Aufand ins Verhältnis setzt...

Ich nenn mal ein Beispiel. Stell Dir vor Du hast ein GUI geschrieben. Es hat ein paar Methoden und macht was Du willst.

Jetzt willst Du es per Unit-Tests testen. Mußt Du etwas umschreiben, damit es testbar wird, weil vielleicht die benötigte Granularität fehlt?
Oder läßt es sich so gar nicht testen?

z.B. sind Methoden direkt abrufbar oder ist vielleicht mancher Code einfach nur direkt in den EventHandler programmiert?

Ich glaube anhand einiger solcher Fragen sieht man ob etwas umgeschrieben werden muss.

So und jetzt nochmal zurück:

Führt der sachgemäße Einsatz von Unit-Tests tatsächlich zu qualitativ hochwertiger Software?

Was geht wohl schneller, Code a little test a little and then test a little more (Bugfixes)
oder gleich "aufs Knöpfchen drücken" und sich vom Unittest aussagen lassen, wo etwas fehlgeschlagen ist?

So gesehen kann man zumindest behaupten:

Es führt zu weniger Fehler in derselben Zeit und das auf jeden Fall bei längerfristigen Projekten. Und weniger Fehler machen zumindest einen Teil der Qualität aus. Weniger Zeit heißt doch dass die Produktivität gesteigert wird.

Aber wie Du auch schon erwähntest:

Dir fehlt eben immer noch eine empirische Studie.

22.06.2010 - 07:53 Uhr

Zitat:

Versteht mich bitte nicht falsch...

Unit Testing - Wikipedia

Ich verstehe Dich schon richtig, denke ich. Du möchtest einfach einen stichhaltigen Beweis WAS BRINGEN UNITTESTS?

Im Abschnitt "Overview" auf der im Link genannten Seite heißt es:

A study conducted by NIST in 2002 reports that software bugs cost the U.S. economy $59.5 billion annually. More than a third of this cost could be avoided if better software testing was performed.[3]

Ich denke das könnte interessant sein:

Nist Report

und auch dieser Link:

Economical Analysis

EDIT: @Rainbird: Wir könnten auch selber eine Studie starten, mit 2 unabhängigen Gruppen (Das können auch einzelne Entwickler sein)

Eine Gruppe benutzt Unit Tests mit allen möglichen Vorteilen. Die andere nicht.

Was passiert?

21.06.2010 - 15:35 Uhr

(Unten gibts ein Bild...)

Diese Version kann benutzt werden, um von der aktuellen System.Windows.Forms.PictureBox loszukommen.

Wird der ImageLayout / BackgroundImageLayout auf None gesetzt, hat das Zoomen mit dem Zoomfaktor ebenfalls eine Auswirkung.

1.0f = Vergrößerungsfaktor 1

d.h. also alles was ScaleFactor>1 ist vergrößert, alles was ScaleFactor<1 ist verkleinert.

d.h. diese PictureBox kann sowohl gescrollt werden als auch den Fokus erhalten.
Die Fokusfarbe ist auswählbar.

Es können also auch mit dem Designer mehrere dieser PictureBoxen auf ein Form gesetzt werden und diese können dann mit TAB durchgtabbed werden.


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

using System.Drawing;

namespace LowLevelGraphics.CustomControls
{
    /// <summary>
    /// 
    /// </summary>
    public class SelectablePictureBox : ScrollableControl, ISupportInitialize
    {
        protected Image m_Image = null;
        protected float m_Zoom = 1.0f;
        protected InterpolationMode m_InterpolationMode = InterpolationMode.High;
        protected Color m_FocusColor = Color.White;

        public SelectablePictureBox()
        {
            this.DoubleBuffered = true;
            this.AutoScroll = true;
            SetStyle(ControlStyles.Selectable, true);
            this.TabStop = true;
        }

        [Category("Appearance")]
        [Description("The interpolation mode used to smooth the drawing")]
        public InterpolationMode InterpolationMode
        {
            get { return m_InterpolationMode; }
            set { m_InterpolationMode = value; }
        }

        [Category("Appearance")]
        [Description("The image to be displayed")]
        public Image Image
        {
            get { return m_Image; }
            set
            {
                m_Image = value;
                UpdateScaleFactor();
                Invalidate();
            }
        }

        [Category("Appearance")]
        [Description("The color of the focus rectangle if focused")]
        public Color FocusColor
        {
            get { return m_FocusColor; }
            set { m_FocusColor = value; }
        }

        [Category("Appearance")]
        [Description("The zoom factor. Less than 1 to reduce, more than 1 to magnify")]
        public float Zoom
        {
            get { return m_Zoom; }
            set
            {
                if ((value < 0) || (value < 1E-05))
                {
                    value = 1E-05F;
                }
                m_Zoom = value;
                UpdateScaleFactor();
                Invalidate();
            }
        }

        public override Image BackgroundImage
        {
            get
            {
                return m_Image;
            }
            set
            {
                this.m_Image = value;
                Invalidate();
            }
        }

        protected void UpdateScaleFactor()
        {
            if (m_Image == null)
            {
                AutoScrollMargin = this.Size;
            }
            else
            {
                AutoScrollMinSize = new Size((int)(m_Image.Width * m_Zoom + 0.5f), (int)(m_Image.Height * Zoom + 0.5f));
            }
        }

        protected override void OnPaintBackground(PaintEventArgs e)
        {
            //clear implementation: normally there would be a draw routine this overridance clears it
        }

        protected override void OnMouseDown(MouseEventArgs args)
        {
            base.OnMouseDown(args);
            this.Focus();
        }

        protected override void OnKeyPress(KeyPressEventArgs args)
        {
            if (args.KeyChar == '\r')
            {
                OnClick(EventArgs.Empty);
            }
            else
            {
                base.OnKeyPress(args);
            }
        }

        protected override void OnEnter(EventArgs args)
        {
            base.OnEnter(args);
            this.Invalidate();
        }

        protected override void OnLeave(EventArgs e)
        {
            base.OnLeave(e);
            this.Invalidate();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            if (m_Image == null)
            {
                OnPaintBackground(e);
                return;
            }

            switch (this.BackgroundImageLayout)
            {
                case ImageLayout.Center:
                    Size sizeCenter = m_Image.Size;
                    Point ptCenter = Center(sizeCenter);
                    g.DrawImage(m_Image, ptCenter.X, ptCenter.Y, sizeCenter.Width, sizeCenter.Height);
                    break;

                case ImageLayout.Stretch:
                    g.DrawImage(m_Image, new Rectangle(0, 0, this.ClientRectangle.Width, this.ClientRectangle.Height), 0, 0, m_Image.Width, m_Image.Height, GraphicsUnit.Pixel);
                    break;

                case ImageLayout.Tile:
                    TextureBrush texture = new TextureBrush(m_Image);
                    texture.WrapMode = WrapMode.Tile;
                    g.FillRectangle(texture,
                        new RectangleF(0, 0, this.ClientRectangle.Width, this.ClientRectangle.Height));

                    break;

                case ImageLayout.Zoom:
                    Size sizeAspectRatio = AspectRatio();
                    Point ptCenterZoom = Center(sizeAspectRatio);
                    g.DrawImage(m_Image, ptCenterZoom.X, ptCenterZoom.Y, sizeAspectRatio.Width, sizeAspectRatio.Height);
                    break;

                case ImageLayout.None:
                    ApplyZoom(e);
                    g.DrawImage(m_Image, new Rectangle(0, 0, m_Image.Width, m_Image.Height), 0, 0, m_Image.Width, m_Image.Height, GraphicsUnit.Pixel);
                    break;
            }
            base.OnPaint(e);

            if (this.Focused
                && this.CanFocus)
            {
                DrawFocusRectangle(g);
            }
        }

        private void DrawFocusRectangle(Graphics g)
        {
            Brush focusBrush = new SolidBrush(m_FocusColor);
            Pen focusPen = new Pen(focusBrush, g.DpiX / 12);
            g.DrawRectangle(focusPen,
            this.ClientRectangle);
            focusPen.Dispose();
            focusBrush.Dispose();
        }

        private Point Center(Size size)
        {
            int x = this.ClientRectangle.Width / 2 - size.Width / 2;
            int y = this.ClientRectangle.Height / 2 - size.Height / 2;
            return new Point(x, y);
        }

        /// <summary>
        /// Ensure aspect ratio.
        /// </summary>
        /// <param name="size">The size.</param>
        /// <returns></returns>
        private Size AspectRatio()
        {
            float nPercent = 0;
            float nPercentW = 0;
            float nPercentH = 0;

            int nSourceWidth = m_Image.Width;
            int nSourceHeight = m_Image.Height;

            nPercentW = ((float)Width / (float)nSourceWidth);
            nPercentH = ((float)Height / (float)nSourceHeight);
            int nDestinationX = 0;
            int nDestinationY = 0;
            if (nPercentH < nPercentW)
            {
                nPercent = nPercentH;
                nDestinationX = System.Convert.ToInt16((Width -
                              (nSourceWidth * nPercent)) / 2);
            }
            else
            {
                nPercent = nPercentW;
                nDestinationY = System.Convert.ToInt16((Height -
                              (nSourceHeight * nPercent)) / 2);
            }

            int nDestinationWidth = (int)(nSourceWidth * nPercent);
            int nDestinationHeight = (int)(nSourceHeight * nPercent);
            return new Size(nDestinationWidth, nDestinationHeight);
        }

        /// <summary>
        /// Applies the zoom.
        /// </summary>
        /// <param name="e">The <see cref="System.Windows.Forms.PaintEventArgs"/> instance containing the event data.</param>
        private void ApplyZoom(PaintEventArgs e)
        {
            Matrix mx = new Matrix(m_Zoom, 0, 0, m_Zoom, 0, 0);
            mx.Translate(this.AutoScrollPosition.X / m_Zoom, this.AutoScrollPosition.Y / Zoom);
            e.Graphics.Transform = mx;
            e.Graphics.InterpolationMode = m_InterpolationMode;
        }

        #region ISupportInitialize Members

        public void BeginInit()
        {
        }

        public void EndInit()
        {
        }

        #endregion
    }
}

21.06.2010 - 12:27 Uhr

@Rainbird:

Ein Verweis hierauf sei noch erwähnt:

Meine Erfahrungen zu Unit-Tests

Auszug aus Clean Code:

The moral of the story is simple: Test code is just as important as production code. It
is not a second-class citizen. It requires thought, design, and care. It must be kept as clean
as production code.

Außerdem sollte inzwischen TDD state of the Art sein, wie ja hier von anderen auch schon erwähnt wurde.

Ich habe nur gute Erfahrungen mit Unit-Tests gemacht.

Und man schreibt den Code doch etwas anders. Flexibler.

Außerdem hat man den Vorteil wenn man z.B.

Testdriven (C#) .NET

benutzt, bekommt man tools wie Code Coverage durch die Unit-Tests zusätzlich hinzu oder ein Visual Studio plugin mit dem man direkt nur die zu testende Methode ausführen lassen kann, egal ob im Test oder direkt im produktiven Code. Sehr zeitsparend.

Ich behaupt einfach mal dass Unit-Tests ab einem bestimmten Projektumfang IMMER den Zeitaufwand hinten raus reduzieren.

Und dass der produktive Code durch die Unittests besser wird, ist IMHO auch Tastache.

Auch die Conclusion aus Clean Code spricht für sich und kann der Aussage nur zustimmen:

Conclusion
We have barely scratched the surface of this topic. Indeed, I think an entire book could be
written about clean tests. Tests are as important to the health of a project as the production
code is. Perhaps they are even more important, because tests preserve and enhance the
flexibility, maintainability, and reusability of the production code. So keep your tests constantly
clean. Work to make them expressive and succinct. Invent testing APIs that act as
domain-specific language that helps you write the tests.
If you let the tests rot, then your code will rot too. Keep your tests clean.

14.06.2010 - 15:06 Uhr

@Janismac:

Eine weitere Möglichkeit ist über einen sogenannten

Eye-Dropper

Quasi den Pixel über den Desktop ermitteln ohne einen Screenshot zu machen.

s. auch:

Creating an eye-dropper

EDIT: Anmerkung: Dieser reagiert dann natürlich auf ALLE pixel auf dem Screen.

@sevo:
Ansonsten muss eine Umrechnungsroutine programmiert werden, wie Janismac schon
richtig die Richtung gezeigt hat. Denn wenn verzerrt bzw. skaliert angezeigt wird, wirst Du sonst nicht das richtige Pixel unter dem Mauszeiger bekommen.

Ganz andere Alternative: Eingabe per Control und nicht den Mauszeiger mit Klick-Koordinaten benutzen. Ist aber eben meist nicht so komfortabel

11.06.2010 - 17:04 Uhr

@gfoidl: Ich mach das in diesem Fall selbst. Ich hab vorgestern angefangen und die ersten Grafiken lassen sich schon darstellen.

😃

Ich kann schon einige Verkehrsschilder bei Wikipedia von

Bildtafel der Verkehrszeichen von Deutschland

anzeigen.

@realpk:

Wenn ich das neue Projekt dann online stelle kannst Du ausprobieren ob Du es mit der LowLevelGraphicsLibrary anzeigen kannst.

11.06.2010 - 14:35 Uhr

Nachtrag: da ich sowieso eine SVG-Anzeige benötige,
implementiere ich diese momentan selbst. Für die Anzeige
von Verkehrsschildern.

bzgl. Verkehrsschilderkennung in neuen Fahrzeugen

10.06.2010 - 15:58 Uhr

Aforge.net: Template Matching
Halcon: Template Matching
Wolfram: Template Matching
Open CV: Template Matching
LowLevelGraphicsLibrary: Template Matching

ebenso wie fast überall "Exhaustive Template Matching"

Außerdem liefert

Programmiersprache + Template Matching auch schon einiges...
in Google

...

usw.

10.06.2010 - 14:49 Uhr

@Scaer: Template Matching findet sich auch hier im Forum, einfach nur den Suchbegriff eingeben.

09.06.2010 - 10:56 Uhr

Ich habe die Aufgabe, eine Gesichtserkennung mit Eigenface zu schreiben, habe nur absolut keine ahnung wie ich das anstellen soll.
Ich werde im Internet nicht fündig.

Es findet sich alles im Internet bis zu fertigen Ansätzen. Aber es stimmt auch die Aussage, dass man oft selber Hand an den Code anlegen muss.

Ich habe schon mit Visual Studio alles soweit geschrieben, dass ich eine/meine Webcam ansprechen kann und auch schon ein Kreis automatisch um das Gesicht gemalt wird + das es dem Gesicht folgt und die größe ändert etc.

Wie hast Du diesen Teil programmiert? Was für Methodiken hast Du angewendet.

Die große Frage ist jetzt, wie schaffe ich es, das ich ein Gesicht erkennen kann und mir dann z.B. sagt Hallo Herr XYZ, wenn ich von dem Gesicht vorher ein Bild gemacht habe und das abgespeichert hab.

Habe ich das richtig verstanden, Du kannst das Gesicht schon lokalisieren?

Wenn ja, dann berechne z.B. die verscheidenen Eigenfaces der verschiedenen Personen die erkannt werden sollen, und speichere Dir diese ab.

Dann ermittelst Du anhand einer Matching-Methode (TemplateMatching, ExhaustiveTemplateMatching, Histogrammbasiertes TemplateMatching) oder einem neuronalen Netzwerk das Ergebnis.

Wenn du fertigen Libs benutzen darfst, nimm doch z.B. Aforge.net für das neuronale Netzwerk. (Namespace neuro glaube ich).

09.06.2010 - 10:20 Uhr

Erkennt wird immer(!) intern, es soll auf jeden Fall möglich sein zu sagen, welches Schild es ist, d.h. es gibt auf jeden Fall einen Text dazu. z.B. Geschwindigkeitsbeschränkung 50.

Um es genauer zu formulieren, es geht um den Ansatz, quasi ob aus der lokalisierten Bildstelle das Bild direkt ausgewertet soll, oder anhand einer Datenbank mittels klaren Formen. Ob das dann mittels einem neuronalen Netzwerk gemacht wird, oder per Statistik oder sonstigen Klassifizierungsmethoden sei vorerst mal dahingestellt.

Erkannt wird so oder so, das stimmt schon. Sonst wäre der Begriff "erkennen" ja falsch gewählt.

Ich werde einfach selbst eine Methode auswählen.

09.06.2010 - 09:41 Uhr

So viele Fehler sind korrigiert und ich kann an die Erkennung gehen.

Hierzu noch eine Frage zum ERKENNEN:

Erstellen wir hierzu eine Bilddatenbank mit den BEKANNTEN Schildern, oder soll das Programm einfach nur die Ausschnitte aus dem Realen Bild mit dem Verkehrsschild extrahieren?

Was meint ihr?

EDIT: Nebenbei bin ich dabei auch noch auf einen Ansatz gekommen, um Autonummern extrahieren zu lassen. Das war mehr oder weniger Zufall, funktioniert aber zuverlässig, wenn sich zumindest nur ein Auto im Bild befindet. (bzw. 1 beschriftete Nummerntafel)

09.06.2010 - 09:40 Uhr

Bzgl.

Verkehrsschilderkennung in neuen Fahrzeugen

hab ich jetzt noch ein paar Sachen zu programmieren.

Außerdem möchte ich für später die Videos die dabei entstanden sind später auch auswerten können, nicht nur die Einzelbilder die in Echtzeit von der Webcam kommen.

Hierzu ein paar Fragen:

1.) Kann man Codecs in C# benutzen, um einzelne Frames eines Videos zu lesen?
Ich möchte nicht wissen, sondern nur ob, vielleicht weiß das ja schon jemand. 😃

2.) und ist dabei Codecs per Api anzusteuern überhaupt der richtige Weg oder bietet mir da DirectShow schon wirklich alles was ich brauche?

Im Projekt WebTV1: Web-TV-Player, TV-Streams im Web hatte ich damals schon einen Video Player(Plugin) mit DirectX programmiert, dort ging es aber nur um das Abspielen des Streams.

Jetzt geht es darum einzelne Frames auszulesen.

Eine mögliche Quelle um das Problem für AVI-Files zu lösen, habe ich hier gefunden:

Der Grund dafür ist: möglichst nicht für jedes einzelne VideoFormat einen Frameextractor zu programmieren.

Avi Stream Info Structure

Codec-Basiert habe ich hier eine Diskussion gefunden:

Codecs in C#

Ich werde auf jeden Fall noch etwas weiter suchen, zuerst muss das obere Projekt abgeschlossenen werden.

EDIT: Ich habe natürlich auch hier im Forum gesucht aber dies bezüglich nichts gefunden was mir weiterhelfen würde mich für einen der beiden Ansätze zu entscheiden.

07.06.2010 - 16:36 Uhr

@Quaneu: Hat dich das jetzt wirklich nur für double interessiert was schneller ist (s. Überschrift) oder allgemein der Ausdruck? Denn sonst müssten wir das für andere Fälle auch noch testen.

Quasi verschiedene Überladungen von Math.Abs(...) mitberücksichtigen.

07.06.2010 - 16:34 Uhr

@d3!NL:

Das seh ich im Release für die double Überladung:


            double a = 3.0f;
0000009a  fld         dword ptr ds:[04161A50h] 
000000a0  fstp        qword ptr [ebp-44h] 
            double b = 7.0f;
000000a3  fld         dword ptr ds:[04161A58h] 
000000a9  fstp        qword ptr [ebp-4Ch] 
            bool test1 = Math.Abs(a) > b;
000000ac  fld         qword ptr [ebp-44h] 
000000af  fabs             
000000b1  fstp        qword ptr [ebp+FFFFFF7Ch] 
000000b7  fld         qword ptr [ebp+FFFFFF7Ch] 
000000bd  fld         qword ptr [ebp-4Ch] 
000000c0  fcomip      st,st(1) 
000000c2  fstp        st(0) 
000000c4  jp          000000CA 
000000c6  jb          000000CE 
000000c8  jmp         000000CA 
000000ca  xor         eax,eax 
000000cc  jmp         000000D3 
000000ce  mov         eax,1 
000000d3  mov         dword ptr [ebp-50h],eax 

07.06.2010 - 15:58 Uhr

@dN!3L:

Math.Abs internals:


public static int Abs(int value)
{
    if (value >= 0)
    {
        return value;
    }
    return AbsHelper(value);
}

und AbsHelper:


private static int AbsHelper(int value)
{
    if (value == -2147483648)
    {
        throw new OverflowException(Environment.GetResourceString("Overflow_NegateTwosCompNum"));
    }
    return -value;
}

07.06.2010 - 15:47 Uhr

@Gfoidl: Das wäre dann meiner Meinung nach der nächste Schritt für ihn gewesen.

😉

für z.B.


public void Test1()
{
    int a = 7;
    int b = 2904;

    bool bTest1 = Math.Abs(a) < b;
}

kommt heraus:


.method public hidebysig instance void  Test1() cil managed
{
  // Code size       20 (0x14)
  .maxstack  2
  .locals init ([0] int32 a,
           [1] int32 b,
           [2] bool bTest1)
  IL_0000:  nop
  IL_0001:  ldc.i4.7
  IL_0002:  stloc.0
  IL_0003:  ldc.i4     0xb58
  IL_0008:  stloc.1
  IL_0009:  ldloc.0
  IL_000a:  call       int32 [mscorlib]System.Math::Abs(int32)
  IL_000f:  ldloc.1
  IL_0010:  clt
  IL_0012:  stloc.2
  IL_0013:  ret
} // end of method Form1::Test1

und für test2:


public void Test2()
{
      int a = 7;
      int b = 2904;
      bool bTest2 = a < b && a > -b;
}


.method public hidebysig instance void  Test2() cil managed
{
  // Code size       23 (0x17)
  .maxstack  2
  .locals init ([0] int32 a,
           [1] int32 b,
           [2] bool bTest2)
  IL_0000:  nop
  IL_0001:  ldc.i4.7
  IL_0002:  stloc.0
  IL_0003:  ldc.i4     0xb58
  IL_0008:  stloc.1
  IL_0009:  ldloc.0
  IL_000a:  ldloc.1
  IL_000b:  bge.s      IL_0014
  IL_000d:  ldloc.0
  IL_000e:  ldloc.1
  IL_000f:  neg
  IL_0010:  cgt
  IL_0012:  br.s       IL_0015
  IL_0014:  ldc.i4.0
  IL_0015:  stloc.2
  IL_0016:  ret
} // end of method Form1::Test2

EDIT: muss noch mal den richtigen Code nachliefern statement ist falsch.

EDIT: korrigiert.

Das wird aus Test 1 (Release):


        public void Test1()
        {
00000000  push        ebp  
00000001  mov         ebp,esp 
00000003  push        edi  
00000004  push        esi  
00000005  push        ebx  
00000006  sub         esp,40h 
00000009  mov         esi,ecx 
0000000b  lea         edi,[ebp-38h] 
0000000e  mov         ecx,0Bh 
00000013  xor         eax,eax 
00000015  rep stos    dword ptr es:[edi] 
00000017  mov         ecx,esi 
00000019  xor         eax,eax 
0000001b  mov         dword ptr [ebp-1Ch],eax 
0000001e  mov         dword ptr [ebp-3Ch],ecx 
00000021  cmp         dword ptr ds:[04AC3D60h],0 
00000028  je          0000002F 
0000002a  call        75F68F91 
0000002f  xor         edx,edx 
00000031  mov         dword ptr [ebp-44h],edx 
00000034  xor         edx,edx 
00000036  mov         dword ptr [ebp-40h],edx 
00000039  mov         dword ptr [ebp-48h],0 
00000040  nop              
            int a = 7;
00000041  mov         dword ptr [ebp-40h],7 
            int b = 2904;
00000048  mov         dword ptr [ebp-44h],0B58h 

            bool bTest1 = Math.Abs(a) < b;
0000004f  mov         ecx,dword ptr [ebp-40h] 
00000052  call        FF87F03C 
00000057  mov         dword ptr [ebp-4Ch],eax 
0000005a  mov         eax,dword ptr [ebp-4Ch] 
0000005d  cmp         eax,dword ptr [ebp-44h] 
00000060  setl        al   
00000063  movzx       eax,al 
00000066  mov         dword ptr [ebp-48h],eax 
        }
00000069  nop              
0000006a  lea         esp,[ebp-0Ch] 
0000006d  pop         ebx  
0000006e  pop         esi  
0000006f  pop         edi  
00000070  pop         ebp  
00000071  ret              

und das aus Test 2 (Release):


        public void Test2()
        {
00000000  push        ebp  
00000001  mov         ebp,esp 
00000003  push        edi  
00000004  push        esi  
00000005  push        ebx  
00000006  sub         esp,40h 
00000009  mov         esi,ecx 
0000000b  lea         edi,[ebp-38h] 
0000000e  mov         ecx,0Bh 
00000013  xor         eax,eax 
00000015  rep stos    dword ptr es:[edi] 
00000017  mov         ecx,esi 
00000019  xor         eax,eax 
0000001b  mov         dword ptr [ebp-1Ch],eax 
0000001e  mov         dword ptr [ebp-3Ch],ecx 
00000021  cmp         dword ptr ds:[04AC3D60h],0 
00000028  je          0000002F 
0000002a  call        75F68F09 
0000002f  xor         edx,edx 
00000031  mov         dword ptr [ebp-40h],edx 
00000034  xor         edx,edx 
00000036  mov         dword ptr [ebp-44h],edx 
00000039  mov         dword ptr [ebp-48h],0 
00000040  nop              
            int a = 7;
00000041  mov         dword ptr [ebp-40h],7 
            int b = 2904;
00000048  mov         dword ptr [ebp-44h],0B58h 
            bool bTest2 = a < b && a > -b;
0000004f  mov         eax,dword ptr [ebp-40h] 
00000052  cmp         eax,dword ptr [ebp-44h] 
00000055  jge         0000006B 
00000057  nop              
00000058  mov         eax,dword ptr [ebp-44h] 
0000005b  neg         eax  
0000005d  cmp         eax,dword ptr [ebp-40h] 
00000060  setl        al   
00000063  movzx       eax,al 
00000066  mov         dword ptr [ebp-4Ch],eax 
00000069  jmp         00000070 
0000006b  xor         edx,edx 
0000006d  mov         dword ptr [ebp-4Ch],edx 
00000070  movzx       eax,byte ptr [ebp-4Ch] 
00000074  mov         dword ptr [ebp-48h],eax 
        }
00000077  nop              
00000078  lea         esp,[ebp-0Ch] 
0000007b  pop         ebx  
0000007c  pop         esi  
0000007d  pop         edi  
0000007e  pop         ebp  
0000007f  ret              

07.06.2010 - 15:37 Uhr

@Quaneu: Solche Unterschiede herauszufinden, ist immer interessant, vor allem natürlich wenn es um die Performance geht. Oft hilft dabei auch ein Blick in den IL-Code (Byte-Code).

s. dazu auch:

Disassemblieren von Projekte, ganz einfach mit ILDASM [VS2005 Deutsch]

31.05.2010 - 20:41 Uhr

Hallo Zommi und danke vorerst mal.

Wenn ich dann die Zusammenfassungen (sowohl von Wikipedia als auch von Dir. 😉 in meinen Worten wiedergeben darf:

1.) Der ausgewählte Interest-Operator könnte in diesem Fall ein Eckendetektor (z.B. Plessey, Harris-Corner Detektor und weitere) sein,

Hmmm, das bietet sich besonders an, da es hier nur um Quader geht, die auf dem Bild zu sehen sein werden.

2.) Einen Matching Algorithmus ausführen (das nanntest Du Features paaren so gut es geht).

Wenn ich einen Corner-Detektor wähle, wäre das z.B. welche Corner aus Bild 1 gehört zu Bild 2.

3.) Ein paar korrespondierende Punktpaare herausgreifen, die mit 2. erzeugt wurden

4.) Geometrischen Zusammenhang berechnen

D.h. die von 3 herausgegriffenen Koordinaten mittels der Fundamentalmatrix berechnen.
Wenn ich das richtig verstanden habe, bin ich dann bei der Epipolargeometrie soweit angelangt, das ich quasi die korrespondierenden Punkte auf Epipolare Linien setzen kann.

Das Funktioniert lt. Wikipedia auch, selbst wenn die Kameraposition doch nicht bekannt gewesen sein sollte.

5.) Und 5. sind quasi Trial and Error-Operationen.

Habe ich das so weit fürs erste richtig verstanden!?

Und das alles ist quasi nichts anderes als die Zusammenfassung was in

"Epipolargeometrie" unter Wikpedia steht.

Ok, sobald ich dazu komme, werde ich mich daran versuchen.

P.S.:
Das kann dann nur 2 Sachen bedeuten:

1.) ich hab für meinen Stereomatching bei 2 stereoskopischen Bildern einen anderen Weg entdeckt
2.) die Berechnung ist doch nicht so gut wie es auf den ersten Blick den Anschein hat.

Werde ich überprüfen. 😉

31.05.2010 - 19:29 Uhr

Ich suche diesesmal nach einem Algorithmus um ein Stereoanaglyph in eine Depthmap umzuwandeln.

Das Anaglyph wurde dabei z.B. als Optimized Anaglyph erzeugt. Ich gehe jetzt einfach von diesem Typ aus.

Um es einfacher zu machen: Ich kann auch mit Sicherheit davon ausgehen, dass die Kameras das Bild senkrecht von oben mittig betrachtet haben.

(Beispielbild habe ich hier angefügt, das ist nicht das aktuelle Bild um das es gehen wird, das Originalbild kann ich aus Copyright Gründen hier nicht posten)

Gibt es dann tatsächlich einen Algorithmus eurer Meinung nach in der Art wie:

Für das untenstehende Bild (angenommen die Kamera würde tatsächlich von oben mittig daraufsehen:

METHODE 1
========

1.) Finde das erste rote Pixel in der aktuellen Zeile
2.) Finde das erste blaue Pixel in der selben aktuellen Zeile
3.) rechne den Abstand der beiden Pixel in einen Farbwert (z.B. Grauwert, je größer der Abstand zwischen rot und blau desto dunkler)
4.) setze das Pixel auf den entsprechenden Grauwert im Ergebnisbild (mittig in den Abstand zwischen blau und rot).

oder muss ich ausgehend von der Kamera quasi die Strahlensätze für das Bild ermitteln (ausrechnen vom Punkt in der Mitte ausserhalb über dem Bild - Kameraposition) und dann die Linien berechnen

Methode 2
=======

1.) Von Kamerapunkt zu Blau
2.) Von Kamerapunkt zu Rot
3.) Ausmessen wie weit die Strahlen auseinandergehen
4.) Mittig zwischen die aufgespannte Linie von Blau und Rot den entsprechenden Wert setzen m Ergebnisbild

Ist für euch denkbar, dass Methode 1 auch (natürlich mit Abwandlungen) möglich sein könnte?

Oder hab ich bei beiden Methoden total falsch gedacht?

Möchte einfach noch ein paar andere Gedanken hören, bevor ich das irgendwann implementiere.

30.05.2010 - 16:57 Uhr

Zur Hintergrundaktivität:

Momentan bin ich dabei im Bereich in dieser Richtung ziemlich viel auszuprobieren und muß sagen, es funktioniert auch jetzt schon mit der Library ziemlich gut zu lokalisieren.

Heute hab ich noch (per Zufall) eine andere Sequenz gefunden, die funktioniert und im ersten Schritt NICHT farbabhängig ist, deswegen funktioniert diese auch gut mit allen Schildern wie es auf den ersten Blick scheint. Das müßte ich noch genauer testen.

Folgende Sequenz funktioniert soweit zur Lokalisierung nahezu perfekt(Filternamen aus LowLevelGraphicsLibrary)

1.) Normalize
2.) ChannelDifferences
3.) Threshold (mit > 127)
4.) Open
5.) ImageFill (Neu programmiert, Vorbild: Matlab)

Mit dem SimpleBlobExtractor können dann die Objekte geholt und weiterbearbeitet werden.

28.05.2010 - 14:31 Uhr

Gut zu wissen, ich hab nämlich momentan leider keine Zeit das selber in Erfahrung zu bringen. Aber das wissen hilft mir auf jeden Fall weiter.

28.05.2010 - 13:58 Uhr

@iginaz: such im Forum nach CMYK und Poste die besten Treffer hier

CMYK Problem

Außerdem hatte ich angedacht das ganze in die LowLevelGraphicsLibrary einzufügen.

Ob der Code richtig sein kann hab ich nicht überprüft. Er ist auch nicht getestet bisher.


  /// <summary>
  /// Used to calculate new channel values from rgb
  /// This is a simple formula WITHOUT ICC (Color management)
  /// </summary>
  protected override void CalcValues()
  {
            int nR = m_Color.R;
            int nG = m_Color.G;
            int nB = m_Color.B;

            m_K = Math.Min(Math.Min(255 - nR, 255 - nG), 255 - nB);
            m_C = (255 - nR - m_K) / (255 - m_K);
            m_M = (255 - nG - m_K) / (255 - m_K);
            m_Y = (255 - nB - m_K) / (255 - m_K); 
  }

28.05.2010 - 13:41 Uhr

@Jack30Lena und Gfoidl:

Wie sieht das ganze im Vergleich zu AddRange aus?

Was macht der Compiler daraus, wenn ich ein Array direkt in AddRange initialisiere?



List<int> aInt = new List<int>();
aInt.AddRange(new int[]{1,1,1,1,1,1,1,1});

//Vergleich 

List<int> aInt2 = new List<int>(new int[]{1,1,1,1,1,1,1,1,1,})

oder ähnliches?

Oder ist das eurer Meinung nach Unsinn das mit-zu-vergleichen!?

Außerdem: ich sehe es wird "var" benutzt. Was ist wenn man direkt den benötigten Typ benutzt?

25.05.2010 - 18:19 Uhr

@Mansur: Die Klassen BaseColorSegmentation2, BaseColorSegmentation3 usw. habe ich rausgeworfen, da diese jetzt in BaseColorSegmentation vereint sind und mit einem Parameter der Modus eingestellt werden kann.

Das Compillieren klappt bei mir leider immer noch nicht.
Ich konnte zwar die Verweise zu AVI... und LowLevel auf Deine Dlls umstellen,
Mir fehlt aber seltsamer weise die folgenden Klassen:
BaseColorSegmentation3
BaseColorSegmentation4
OwnOptimizedConvolution

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

Hmmm... das werde ich nochmal kontrollieren, auf jeden Fall solltest Du im VS 2008
auf die Projekte die "unavailable/nicht verfügbar" sind, einen "Reload Project/Projekt neu laden"-Befehl per Kontext-Menü ausführen.

Wenn ich einen Einstieg finden sollte, dann interessieren mich eher die Basisklassen.
Soweit ich die Beiträge gelesen habe ist ja das Projekt ImageRecognition2 nur die Frontend Anwendung, um die (komplexen) Filter entsprechend anzusprechen / zu konfigurieren.

Das ImageRecognition2 Projekt ist die Oberfläche um die Filter, Extraktoren und weiteres auszuprobieren, richtig.

Soweit ich das ganze (leider ohne Codeerklärung) mir bisher vorstellen kann ist es wohl die LowLevelGraphics Library die den Kern bildet.

LowLevelGraphicsLibraryGenau, diese Library bildet den Kern.

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

ScripterLibrary
Die ScripterLibrary wird von der ImageProcessingConsole.exe benutzt.
Mit der ImageProcessingConsole können die Filter in der Console ausprobiert werden.

Ich würde gerne mal probieren, ob sich Imageprocessing für GIS Anwendungen eignet ... so als Übungsprojekt.

Dann wäre es interessant die Ergebnisse zu veröffentlichen.

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

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

hier nochmal der Link:

ImageRecognition2

25.05.2010 - 12:04 Uhr

lol @Gfoidl:

Vielleicht als Ergänzung hierzu:

Marching Squares

und mich würde auch die Implementierung des Codes interessieren @tonka. 😉