Odczyt co trzeciego obrazu

0

Cześć,

Mam następujący problem. Dostaję z kamery obraz w pętli. Wygląda to dokładnie tak:

                for (int i = 0; i < m_PaneCount; i++)
                {
                    Width = m_Imgs[i].Width;
                    Height = m_Imgs[i].Height;

                RESIZED:
                    m_Imgs[i].LockBits(new Rectangle(0, 0, Width, Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppRgb, bmpData);
                    if (Camera.UpdateBuffer(m_Logic, i, bmpData.Scan0, bmpData.Stride, ref Width, ref Height) == false)
                    {
                        //Was it the wrong size
                        if ((Width != m_Imgs[i].Width) || (Height != m_Imgs[i].Height))
                        {
                            // Unlock it kill it resize it!
                            m_Imgs[i].UnlockBits(bmpData);
                            m_Imgs[i].Dispose();
                            m_Imgs[i] = new Bitmap(Width, Height, System.Drawing.Imaging.PixelFormat.Format32bppRgb);
                            //image saving function, need to add a name's index to save every image frame
                            m_PicBoxes[i].Image = m_Imgs[i];
                            //file or catalog address should include double slash \\ !!!
                            // everybody loves a GOTO!
                            goto RESIZED;
                        }
                        else
                        {
                            // Didnt update Buffer
                        }
                    }

Obraz znajduje się pod zmienną m_Imgs, ale jest mały szkopuł, kamera wysyła trzy rozdzielczości obrazów. Odbywa się to tak, że najpierw odczytujemy pod zmienną m_Imgs obraz o rozdzielczości 1, potem o rozdzielczości 2 a na koniec o rozdzielczości 3. Mnie interesuje wyświetlanie oraz zapisywanie tylko rozdzielczości 1 i 3. Jak to zrobić? Mógłby mi ktoś podpowiedzieć coś w tym temacie?
Nie jestem biegły w programowaniu obiektowym, mam nadzieję, że tutaj dobrze trafiłem prosząc o pomoc.

Z góry dziękuję.
Marcin

0

Może jakiś licznik?

2

to GOTO to chyba żart? przecież wewnątrz pętli możesz użyć kolejnej pętli.
warunek if (funkcja() == false) robi się if (!funkcja()).
co do pytania - tak jak napisał olo, int index = 0; a w pętli if (index++ % 3 == 0) { /* jestem co trzeci */}

0

dzięki za odpowiedzi oraz za umieszczenie wątku w poprawnym miejscu. GOTO nie jest moim pomysłem, mi niestety przyszło zmodyfikować czyjś kod. nie chcę wchodzić ze zmianami za głęboko.

Zastosuję poradę i dam znać o efektach. Bardzo dziękuję za pomoc :)

0

Nie jestem pewien ale spróbuj to:

... Camera.UpdateBuffer(m_Logic, 3*i, bmpData.Scan0, bmpData.Stride, ref Width, ref Height) ...
0
_13th_Dragon napisał(a):

Nie jestem pewien ale spróbuj to:

... Camera.UpdateBuffer(m_Logic, 3*i, bmpData.Scan0, bmpData.Stride, ref Width, ref Height) ...

to niestety nie działa.

0
ŁF napisał(a):

to GOTO to chyba żart? przecież wewnątrz pętli możesz użyć kolejnej pętli.
warunek if (funkcja() == false) robi się if (!funkcja()).
co do pytania - tak jak napisał olo, int index = 0; a w pętli if (index++ % 3 == 0) { /* jestem co trzeci */}

Czy miałeś na myśli coś takiego:

 for (int i = 0; i < m_PaneCount; i++)
                {
                    Width = m_Imgs[i].Width;
                    Height = m_Imgs[i].Height;
                    int index = 0;

                RESIZED:
                    m_Imgs[i].LockBits(new Rectangle(0, 0, Width, Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppRgb, bmpData);
                    if (TVCore.UpdateBuffer(m_Logic, i, bmpData.Scan0, bmpData.Stride, ref Width, ref Height) == false)
                       // if (TVCore.UpdateBuffer(m_Logic, 3*i, bmpData.Scan0, bmpData.Stride, ref Width, ref Height) == false) // dodane do sprawdzenia
                    {
                        //Was it the wrong size
                        if ((Width != m_Imgs[i].Width) || (Height != m_Imgs[i].Height))
                        {
                            if (index++ % 3 == 0)
                            {
                                // Unlock it kill it resize it!
                                m_Imgs[i].UnlockBits(bmpData);
                                m_Imgs[i].Dispose();
                                m_Imgs[i] = new Bitmap(Width, Height, System.Drawing.Imaging.PixelFormat.Format32bppRgb);
                                //image saving function, need to add a name's index to save every image frame
                                m_PicBoxes[i].Image = m_Imgs[i];
                                //file or catalog address should include double slash \\ !!!
                                // everybody loves a GOTO!
                                goto RESIZED;
                            }
                        }
                        else
                        {
                            // Didnt update Buffer
                        }
                    }
0

W sumie racja. Czyli coś takiego?

for (int i = 0; i < m_PaneCount; i++)
                {
                    Width = m_Imgs[i].Width;
                    Height = m_Imgs[i].Height;
                    //int index = 0;

                RESIZED:
                    m_Imgs[i].LockBits(new Rectangle(0, 0, Width, Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppRgb, bmpData);
                    if (TVCore.UpdateBuffer(m_Logic, i, bmpData.Scan0, bmpData.Stride, ref Width, ref Height) == false)
                       // if (TVCore.UpdateBuffer(m_Logic, 3*i, bmpData.Scan0, bmpData.Stride, ref Width, ref Height) == false) // dodane do sprawdzenia
                    {
                        //Was it the wrong size
                        if ((Width != m_Imgs[i].Width) || (Height != m_Imgs[i].Height))
                        {
                            if (i++ % 3 == 0)
                            {
                                // Unlock it kill it resize it!
                                m_Imgs[i].UnlockBits(bmpData);
                                m_Imgs[i].Dispose();
                                m_Imgs[i] = new Bitmap(Width, Height, System.Drawing.Imaging.PixelFormat.Format32bppRgb);
                                //image saving function, need to add a name's index to save every image frame
                                m_PicBoxes[i].Image = m_Imgs[i];
                                //file or catalog address should include double slash \\ !!!
                                // everybody loves a GOTO!
                                goto RESIZED;
                            }
                        }
                        else
                        {
                            // Didnt update Buffer
                        }
                    } 
0

Już wiem, że to nie będzie działać poprawnie, sprawdziłem to na kamerze. Po właczeniu programu otrzymuję od razu komunikat jak z załącznika.

0

To się podłącz debuggerem i sprawdź gdzie leci ten wyjątek i jaka jest wartość indeksu. Jeżeli nie wiesz co to jest debuger to się dowiedz, bo to jest najbardziej podstawowe narzędzie programisty (oprócz kompilatora i IDE)

0

Jeżeli i == m_PaneCount-1, to przekraczasz zakres tablicy.

                            if (i++ % 3 == 0)
                            {
                                // Unlock it kill it resize it!
                                m_Imgs[i].UnlockBits(bmpData);
0

a po co robisz i++? nie przepisuj bezmyślnie kodu! przecież i jest zwiększane przez pętlę for.

2
bikekowal napisał(a):

Po właczeniu programu otrzymuję od razu komunikat jak z załącznika.
Przecież to widać gołym okiem gdzie i kiedy.
Widzę że ten temat nigdy się nie skończy dopóki ktoś nie poda ci gotowca na tacy.

Masz tak - jeżeli jednak potrzebujesz te m_Imgs[i] dla niewłaściwej rozdzielczości:

m_PaneCount*=3; // tu musisz ustalić czy m_PaneCount obejmuje te w innych rozdzielczościach czy nie jeżeli TAK to WYWALIĆ ten wiersz.
for (int i=0;i<m_PaneCount;)
  {
   Width=m_Imgs[i].Width;
   Height=m_Imgs[i].Height;
   m_Imgs[i].LockBits
     (
      new Rectangle(0,0,Width,Height),
      System.Drawing.Imaging.ImageLockMode.ReadWrite,
      System.Drawing.Imaging.PixelFormat.Format32bppRgb,
      bmpData
     );
   if(!TVCore.UpdateBuffer(m_Logic,i,bmpData.Scan0,bmpData.Stride,ref Width,ref Height))
     {
      if((Width==m_Imgs[i].Width)&&(Height==m_Imgs[i].Height)) i+=3;
      else
        {
         m_Imgs[i].UnlockBits(bmpData);
         m_Imgs[i].Dispose();
         m_Imgs[i]=new Bitmap(Width,Height,System.Drawing.Imaging.PixelFormat.Format32bppRgb);
         m_PicBoxes[i].Image = m_Imgs[i];
        }
     }
  }

Lub tak jeżeli do m_Imgs[i] wchodzą tylko te z właściwą rozdzielczością:

m_PaneCount/=3; // tu musisz ustalić czy m_PaneCount obejmuje te w innych rozdzielczościach czy nie jeżeli NIE to WYWALIĆ ten wiersz.
for (int i=0;i<m_PaneCount;)
  {
   Width=m_Imgs[i].Width;
   Height=m_Imgs[i].Height;
   m_Imgs[i].LockBits
     (
      new Rectangle(0,0,Width,Height),
      System.Drawing.Imaging.ImageLockMode.ReadWrite,
      System.Drawing.Imaging.PixelFormat.Format32bppRgb,
      bmpData
     );
   if(!TVCore.UpdateBuffer(m_Logic,3*i,bmpData.Scan0,bmpData.Stride,ref Width,ref Height))
     {
      if((Width==m_Imgs[i].Width)&&(Height==m_Imgs[i].Height)) ++i;
      else
        {
         m_Imgs[i].UnlockBits(bmpData);
         m_Imgs[i].Dispose();
         m_Imgs[i]=new Bitmap(Width,Height,System.Drawing.Imaging.PixelFormat.Format32bppRgb);
         m_PicBoxes[i].Image = m_Imgs[i];
        }
     }
  }

Mam na temat tego wątku i innych wątków o językach (C-podobnych) osobliwe zdanie, jak w takim wątku ponad trzy razy pojawia się wyraz goto w kodzie - to natychmiast temat do kosza, administratorzy powinni zrobić na to automat. Tobie zasugerowano pozbycie się goto na samym początku, ignorujesz to czego powinieneś posłuchać i na odwrót wsadzasz do kodu to co powinieneś zignorować.

0

Panowie,

Przepraszam, że moje odpowiedzi mogą wyglądać jak ignoranta. Jedyne co mam na swoje usprawiedliwienie to moja niewiedza, co w sumie nie jest poważnym usprawiedliwieniem. Zastosowałem kod _13th_Dragon i mam następujące przypadki:

wersja 1 - błąd o przekroczeniu zakresu tablicy.
wersja 2 - program startuje, ale niestety nie wyświetla obrazu (okno obrazu jest puste)

Na tą chwilę spróbuję sobie poradzić, chociaż gdyby ktoś z Was miał pomysł to oczywiście bardzo chętnie skorzystam.

Bardzo dziękuję Wam za pomoc i wyrozumiałość.
Pozdrawiam

0

A komentarz przeczytałeś w pierwszym wierszu? "jeżeli TAK to WYWALIĆ ten wiersz". -

Tak przeczytałem i przetestowałem obie wersje - brak różnic w zachowaniu.

0
bikekowal napisał(a):

<no i w którym miejscu?

Dokładnie tutaj:

 if ((Width != m_Imgs[i].Width) || (Height != m_Imgs[i].Height))
                        {
                            if ((i % 3 == 0 ) || (i % 2 == 0 ))
                            {
                                // Unlock it kill it resize it!
                                m_Imgs[i].UnlockBits(bmpData);
                                m_Imgs[i].Dispose();
                                m_Imgs[i] = new Bitmap(Width, Height, System.Drawing.Imaging.PixelFormat.Format32bppRgb);
                                //image saving function, need to add a name's index to save every image frame
                                m_PicBoxes[i].Image = m_Imgs[i];
                            }
                        }
                        else
                        {
                            // Didnt update Buffer
                        }

Czyli mam wyświetlany co drugi oraz co trzeci. Pytanie jak je rozróżnić (drugi od trzeciego?). Chcę te obrazy dalej obrabiać, tylko muszę je mieć w postaci osobnych macierzy.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.