tutorials.de Buch-Aktion 05/2012
Like Tree1Danke
  • 1 Beitrag von PhoenixLoe
ERLEDIGT
NEIN
ANTWORTEN
8
ZUGRIFFE
1046
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    Terminator2 Terminator2 ist offline Mitglied Brokat
    Registriert seit
    Aug 2005
    Beiträge
    256
    Hallo,

    Habe im Internet ein dshow Projekt gefunden und muss dieses in Visual Basic konvertieren, da ich sonst einfach gar nichts vom Quellcode verstehe.

    Jetzt habe ich soweit die einzelnen Module und Namespaces konvertiert. Allerdings bleiben einen Haufen Fehlermeldungen über, wo ich bei folgenden absolut keine Ahnung habe, wie ich das lösen könnte:

    Fehlermeldung:
    "end of-Anweisung erwartet"
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
                Dim ptr As Byte* = CByte(data.Scan0.ToPointer())
    'Der Typ Byte* ist mir nicht bekannt und funktioniert auch nicht...
     
                For y As Integer = 0 To height - 1
                    Dim x As Integer = 0
                    While x < width
                        count += ((*ptr) >> 7)
                        x += 1
                        ptr += 1
                    End While
                    ptr += offset
                Next


    Fehlermeldung:
    "Class "MotionDetector2" muss "Property MotionLevelCalculation() As Boolean" für die IMotionDetector-Schnittstelle implementieren. Die implementierende Eigenschaft muss übereinstimmende ReadOnly- oder WriteOnly-Spezifizierer aufweisen."
    "Class "MotionDetector2" muss "ReadOnly Property MotionLevel() As Double" für die IMotionDetector-Schnittstelle implementieren. Die implementierende Eigenschaft muss übereinstimmende ReadOnly- oder WriteOnly-Spezifizierer aufweisen."
    "Class "MotionDetector2" muss "Sub ProcessFrame(ByRef image As System.Drawing.Bitmap)" für die IMotionDetector-Schnittstelle implementieren. "
    "Fehler 9 Class "MotionDetector2" muss "Sub Reset()" für die IMotionDetector-Schnittstelle implementieren."
    Code :
    1
    2
    3
    4
    
    Namespace motion
        Public Class MotionDetector2
            Implements IMotionDetector
    'Wenn man einfach die Implementierung entfernt, ist der Fehler weg, aber sicherlich funktioniert dann das Programm auch nicht...

    Fehlermeldung:
    "Public Event Alarm(sender As Object, e As System.EventArgs)" ist ein Ereignis und kann nicht direkt aufgerufen werden. Verwenden Sie eine RaiseEvent-Anweisung, um ein Ereignis aufzurufen.
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    
    Imports System
    Imports System.Drawing
    Imports System.Threading
    Imports VideoSource
     
    Namespace motion
     
        Public Class Camera
     
            Public Event Alarm As EventHandler
     
    Private Sub video_NewFrame(ByVal sender As Object, ByVal e As CameraEventArgs)
                        If (motionDetecotor.MotionLevel >= alarmLevel) AndAlso (Alarm IsNot Nothing) Then
                            Alarm(Me, New EventArgs())
                        End If
                    End If

    Und noch eine Warnung:
    "property "AutoSize" führt Shadowing für eine überschreibbare Methode in Basis-class "Control" durch. Wenn Sie die Basismethode überschreiben möchten, muss die Methode als "Overrides" deklariert werden."
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    
    Namespace motion
        Public Class CameraWindow
            Inherits System.Windows.Forms.Control
            Private m_camera As Camera = Nothing
            Private m_autosize As Boolean = False
            Private needSizeUpdate As Boolean = False
            Private firstFrame As Boolean = True
     
            Private timer As System.Timers.Timer
            Private flash As Integer = 0
            Private rectColor As Color = Color.Black
     
            ' AutoSize property
            <DefaultValue(False)> _
            Public Property AutoSize() As Boolean
                Get
                    Return m_autosize
                End Get
                Set(ByVal value As Boolean)
                    m_autosize = value
                    UpdatePosition()
                End Set
            End Property

    Wäre echt toll, wenn mir da jemand weiterhelfen könnte
    Geändert von Terminator2 (27.03.09 um 15:20 Uhr)
     

  2. #2
    PhoenixLoe PhoenixLoe ist offline Mitglied Gold
    Registriert seit
    Apr 2005
    Beiträge
    120
    Hallo Terminator2,

    womit hast Du denn den Quelltext konvertiert? Oder hast Du es von Hand gemacht?

    C# unterstützt sogenannte Zeiger, die einen direkten Zugriff auf die Speicherstelle einer Variablen erlauben. Visual Basic kennt dazu keine Entsprechung. Daher hast Du mehrere Alternativen:
    1. Du lässt den Code, wie er ist, und lagerst ihn in eine C#-DLL aus, die Du in Dein VB-Projekt einbindest. Anschließend rufst Du die entsprechende Funktion aus VB heraus auf.
    2. Du versuchst, C# zu lernen oder zumindest Zeiger zu verstehen, damit Du den Quelltext auch in C# richtig interpretieren kannst.
    3. Du verwendest Visual Basic und gehst den Umweg über das sog. Marshalling (suche danach hier im Forum, da gibt es einiges dazu ).
    Zur Klasse MotionDetector2:
    Wie lauten denn Deine übersetzten Eigenschaften und Funktionen? Da C# Eigenschaften auf anderem Wege mit Lese- und Schreibrechten ausstattet als VB, wäre die Frage, ob Du nicht tatsächlich hinter die betreffenden Property-Anweisungen eine ReadOnly- bzw. WriteOnly-Anweisung einfügen musst. Zudem scheinen zwei Funktionen der Schnittstelle noch nicht implementiert zu sein. Du müsstest also mal nachsehen, ob Du alle Funktionen übersetzt hast.

    Zur video_newFrame-Funktion:
    Die Ereignis-Systeme von C# und VB unterscheiden sich ein bisschen. Während in C# überprüft werden muss, ob das Ereignis überhaupt aufrufbar ist und anschließend das Ereignis wie eine Funktion behandelt wird, kennt VB dafür eine Kurzform: Die RaiseEvent-Anweisung. Du müsstest den Code also folgendermaßen abändern:

    Code :
    1
    2
    
    [COLOR=Blue] If[/COLOR] motionDetector.MotionLevel >= alarmLevel[INDENT][COLOR=Blue]RaiseEvent [/COLOR]Alarm([COLOR=Blue]Me[/COLOR], [COLOR=Teal]EventArgs[/COLOR].Empty)
    [/INDENT][COLOR=Blue]End If[/COLOR]
    Zum letzten Problem:
    Die Eigenschaft AutoSize ist bereits Bestandteil der Basisklasse Control. Da die neue Klasse ebenfalls eine Eigenschaft AutoSize implementiert, musst Du angeben, wie in diesem Fall verfahren werden soll:
    1. Du verwendest vor Property das Shadows-Schlüsselwort, um anzugeben, dass beide Eigenschaften verwendet werden.
    2. Du verwendest vor Property das Overrides-Schlüsselwort, um anzugeben, dass Du die AutoSize-Eigenschaft der Control-Klasse überscheibst und damit ausblendest.
    Ich hoffe, dass ich verständlich geschrieben habe. Versuche, die Änderungen umzusetzen. Bei Fragen kannst Du Dich gerne wieder melden.

    Gruß
    PhoenixLoe
    Terminator2 bedankt sich. 

  3. #3
    Terminator2 Terminator2 ist offline Mitglied Brokat
    Registriert seit
    Aug 2005
    Beiträge
    256
    Hey,

    Deine Erklärung ist wirklich gut.
    Mittlerweise habe ich mich wohl dazu entschlossen, alles in C# zu schreiben. Das war zwar anfangs ziehmlich schwer, aber ich bin jetzt fast fertig mit dem Programm.
    Also wenn ich ein Fazit ziehen müsste, Visual Basic finde ich bei weitem besser, es gibt nur wenige Dinge, die mir bisher bei C# positiv aufgefallen sind.
    Trotzdem ist es gut, auch mal eine andere Sprache zu schreiben, da doch sehr viele Projekte in C# zu finden sind
     

  4. #4
    calvin65 calvin65 ist offline Mitglied Bronze
    Registriert seit
    Nov 2005
    Beiträge
    31
    Hallo Terminator2,

    mit demselben "Problem" wie du hatte ich auch zu kämpfen.
    Den Code den du hier übersetzen wolltest stammt doch sicher von Sourceforge? Kommt mir sehr bekannt vor. Habe auch mit gekämpft.

    Was du da hast ist die "Rohfassung" oder auch ein Teil des Aforge Frameworks:
    http://www.aforgenet.com/framework/

    Da gibts mit Version 2 auch Motion(detector) komplett drin, glaube ich. Solltest du dir ansehen, bevor du alles selber machst.
     
    MfG Calvin

  5. #5
    Terminator2 Terminator2 ist offline Mitglied Brokat
    Registriert seit
    Aug 2005
    Beiträge
    256
    Ich habe den motion detector von codeprojekt runtergeladen und dann versucht ihn zu übersetzen. Aber das hätte Tage gedauert... Nach geschlagenen 10 Stunden lief es fast, aber ich hab jetzt soweit alles in C# geschrieben.
    Leider bleibt jetzt auf dem AMD PC, auf dem ich das Programm laufen lassen will, das Bild alle 5 Sekunden hängen, das für 5 Sekunden, und läuft dann wieder weiter.
    Keinen Schimmer, wie das kommt, aber es sieht nach einem Timer aus. Nur dumm, dass da eigentlich gar kein Timer sein dürfte, der so ein Phänomen hervorruft...
    Kann das vielleicht daran liegen, dass es ein AMD CPU ist, mit ATI (AMD) Chipsatz und einer onboard Grafikkarte von ATI? Habe den Grafikspeicher auf 256MB gesteigert, dann schien es wunderbar zu klappen, leider nur für kurze Zeit.
     

  6. #6
    calvin65 calvin65 ist offline Mitglied Bronze
    Registriert seit
    Nov 2005
    Beiträge
    31
    Kann es sein, dass du irgendwo im MotionDetector Bilder speicherst und nicht wieder freigibst?
    Ansonsten war es bei mir so, dass eine lokal angeschlossene Kamera(Webcam) einfach so schnell Bilder geliefert hat, dass der Rechner kaum nachkam und dadurch insgesamt langsam wurde (hohe CPU-Last).

    Auf jeden Fall solltest du dir Aforge ansehen, dass brauchst du eigentlich nur einzubinden und fertig ist. Wenn die CPU zu sehr belastet wird, setze die maximale Framerate runter. Es gibt eine entsprechende Property da drin.
    Geändert von calvin65 (16.04.09 um 15:03 Uhr)
     
    MfG Calvin

  7. #7
    Terminator2 Terminator2 ist offline Mitglied Brokat
    Registriert seit
    Aug 2005
    Beiträge
    256
    Das hört sich ganz gut an. Ich habe auch schon überlegt, ob irgendwelche Objekte nicht wieder gelöscht werden, habe allerdings nichts finden können.
    Die Einstellung der maximalen Framerate würde ich gerne ändern, aber ich habe die Einstellung nicht finden können. Weder im Camera Objekt noch sonst wo...

    Ich poste aber mal den Code, der das Bild bei der Bewegungserkennung verarbeitet, wenn irgendwo was falsch läuft, dann bestimmt hier:
    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
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    
            // Process new frame
            public void ProcessFrame(ref Bitmap image)
            {
                if ( backgroundFrame == null )
                {
                    // create initial backgroung image
                    backgroundFrame = grayscaleFilter.Apply( image );
     
                    // get image dimension
                    width   = image.Width;
                    height  = image.Height;
     
                    // just return for the first time
                    return;
                }
     
                Bitmap tmpImage;
     
                // apply the grayscale file
                tmpImage = grayscaleFilter.Apply( image );
     
                // set backgroud frame as an overlay for difference filter
                differenceFilter.OverlayImage = backgroundFrame;
     
                // apply difference filter
                Bitmap tmpImage2 = differenceFilter.Apply( tmpImage );
     
                // lock the temporary image and apply some filters on the locked data
                bitmapData = tmpImage2.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);
     
                // threshold filter
                thresholdFilter.ApplyInPlace( bitmapData );
                // erosion filter
                Bitmap tmpImage3 = erosionFilter.Apply( bitmapData );
                
                // unlock temporary image
                tmpImage2.UnlockBits( bitmapData );
                tmpImage2.Dispose( );
     
                // dispose old background
                backgroundFrame.Dispose( );
                // set backgound to current
                backgroundFrame = tmpImage;
     
                // extract red channel from the original image
                Bitmap redChannel = extrachChannel.Apply( image );
     
                //  merge red channel with moving object
                mergeFilter.OverlayImage = tmpImage3;
                Bitmap tmpImage4 = mergeFilter.Apply(redChannel);
                redChannel.Dispose();
     
                // replace red channel in the original image
                replaceChannel = new ReplaceChannel(RGB.R, tmpImage4);
                Bitmap tmpImage5 = replaceChannel.Apply(image);
                tmpImage4.Dispose();
     
                image.Dispose();
                image = tmpImage5;
     
                //Falls Alarm-Fenster vorhanden sind:
                if (MainForm.Instance.AlarmWindow.Count > 0)
                {
                    //Erst einmal die Bildausschnitte extrahieren:                
                    Single W_korrektur = (Single)1 / (Single)100 * (Single)tmpImage3.Width;
                    Single H_korrektur = (Single)1 / (Single)100 * (Single)tmpImage3.Height;
     
                    bool AlarmActivated = MainForm.Instance.tmrBildSperre.Enabled;
     
                    for (int i = 0; i < MainForm.Instance.AlarmWindow.Count; i++)
                    {
                        //Da die Koordinaten sortiert vorliegen, kann die Breite einfach errechnet werden
                        int X1 = (int)((Single)MainForm.Instance.AlarmWindow[i].Pos1_X * W_korrektur);
                        int Y1 = (int)((Single)MainForm.Instance.AlarmWindow[i].Pos1_Y * H_korrektur);
     
                        //Prozentualer Anteil an bewegten Pixel im Fenster in Objekt schreiben:
                        MainForm.Instance.AlarmWindow[i].AlarmLevel = (int)Pixels(GetPicturePart(tmpImage3, new Rectangle(X1, Y1, ((int)((Single)MainForm.Instance.AlarmWindow[i].Pos2_X * W_korrektur) - X1), ((int)((Single)MainForm.Instance.AlarmWindow[i].Pos2_Y * H_korrektur) - Y1))));
     
                        if ((int)MainForm.Instance.AlarmWindow[i].AlarmLevel >= (int)MainForm.Instance.AlarmWindow[i].AlarmMinLevel)
                        {
                            MainForm.Instance.AlarmWindow[i].AlarmActive = true;
                            if (AlarmActivated == false)   
                            {
                                AlarmActivated = true;  //Jetzt wird ein Signal gesendet:
                                MainForm.Instance.tmrBildSperre.Enabled = true;   
                                MainForm.Instance.tmrSavePicture.Enabled = true;   
                            }
                        }
                        //Speicher freigeben
                        //Puffer.Dispose();
                    }
                }
                tmpImage2.Dispose();
                tmpImage3.Dispose();
            }

    Prinzipiell funktioniert das alles auch. Auf dem Notebook macht die Webcam bei ca. 8fps keine Probleme. Auf dem AMD PC macht die selbe WebCam bei 16fps aber nach einer gewissen Zeit den Fehler...
     

  8. #8
    calvin65 calvin65 ist offline Mitglied Bronze
    Registriert seit
    Nov 2005
    Beiträge
    31
    Ich weiß nicht ob es daran liegt, aber nach dem Durchzählen der verwendeten Images fehlt für tmpImage und tmpImage5 jeweils das Dispose.
     
    MfG Calvin

  9. #9
    Terminator2 Terminator2 ist offline Mitglied Brokat
    Registriert seit
    Aug 2005
    Beiträge
    256
    Das stimmt.
    Habe schon versucht, die beiden zu disposen, dann wird aber kein Bild mehr angezeigt. Auch bei nur einem der beiden Bilder funktioniert es nicht.
    Man müsste die Rückgabe evtl. als neues Bild zurückgeben, und dafür die anderen beiden disposen. Werde das gleich mal ausprobieren.
     

Ähnliche Themen

  1. Konvertierung von YUV4:2:2 nach YUV 4:2:0
    Von Dorschty im Forum C/C++
    Antworten: 4
    Letzter Beitrag: 21.02.08, 10:23
  2. Konvertierung .max nach C4D (obj etc)
    Von mamboben im Forum 3D Studio Max
    Antworten: 4
    Letzter Beitrag: 22.02.05, 09:52
  3. konvertierung von float nach int?
    Von Evola im Forum C/C++
    Antworten: 10
    Letzter Beitrag: 13.12.04, 13:14
  4. [VC++]Konvertierung von VC++6 nach VC++7 fehlerhaft
    Von TakaBo im Forum VisualStudio & MFC
    Antworten: 3
    Letzter Beitrag: 14.10.04, 11:11
  5. J2ME - Konvertierung Int nach Hex
    Von page im Forum Java
    Antworten: 2
    Letzter Beitrag: 26.07.04, 16:58