Nowe posty

Pokaż wiadomości

Ta sekcja pozwala Ci zobaczyć wszystkie wiadomości wysłane przez tego użytkownika. Zwróć uwagę, że możesz widzieć tylko wiadomości wysłane w działach do których masz aktualnie dostęp.


Pokaż wątki -

Strony: [1]
1
C/C++ / format obrazu firewire a video4linux
« dnia: 2012-02-27, 19:27:11 »
Znalazłem program cvEyeTracker dzięki któremu można przy użyciu kamery zgodnej ze standardem firewire śledzić ruch źrenicy oka i obsługiwać komputer bez użycia rąk. Program powstał dla osób sparaliżowanych, które mogą poruszać tylko gałkami ocznymi. Nie mam kamery firewire więc chciałem zmodyfikować program tak, aby współpracował z kamerą Playstation 3 Eye. Kamera ta nadaje się doskonale do tego zastosowania - zalecają ją między innymi twórcy EyeWritera (pod Windows i Mac). Powstawiałem gdzie trzeba kod z przykładowego programu do obsługi urządzeń v4l o nazwie capturer oraz wykomentowałem fragmenty dotyczące przechwytywania z urządzeń standardu IEEE1394. Niestety wyświetlany obraz jest zniekształcony. Widzę dwa czaro-białe obrazy nałożone na siebie i przesunięte o połowę szerokości, jeden w lewo, drugi w prawo. Wydaje mi się że chodzi o różnicę w kodowaniu obrazu w urządzeniach firewire i w kamerach internetowych. Proszę o pomoc w szczególności osoby, którym znane są różnice w kodowaniu pojedynczych, nieskompresowanych klatek. Kamera PS3 Eye używa standardu YUYV, każda klatka zajmuje więc 640×480×2 bajtów. Problem może leżeć gdzieś w okolicach poniższej linijki. Kiedy zmieniam typ danych drugiego parametru funkcji wygląd obrazu nieco się zmienia.
memcpy(eye_image->imageData, (char*)buffers[0].start, monobytesperimage);
Kamerę wybieramy tutaj:
open_device (&fd, "/dev/video1");
/dev/video0 to kamerka wbudowana w mojego laptopa, /dev/video1 to PS3 Eye.
Kod źródłowy po moich przeróbkach w ostatnim poście.

2
C/C++ - GNOME/Gtk / Powtarzające się wciśnięcie klawisza
« dnia: 2010-03-12, 22:18:09 »
Piszę program z użyciem biblioteki GTK. Chciałbym żeby wykonywał pewną funkcję w momencie naciśnięcia klawisza na klawiaturze i inną w momencie zwolnienia go. Niestety GTK nie rozróżnia wciśnięcia klawisza od powtórzenia go, więc trzymając klawisz przez dłuższy czas cykl wciśnięcie-zwolnienie powtarza się wielokrotnie. Czy jest jakiś sposób na ominięcie tego problemu?
Wiem że klawiatura wysyła różne sygnały w zależności od tego czy klawisz był rzeczywiście w tym momencie wciśnięty czy tylko przytrzymany. Można to zaobserwować wykonując polecenie hexdump -x /dev/input/event1 (gdzie /dev/input/event1 to deskryptor klawiatury). Kiedy klawisz jest wciskany jedna z wyświetlanych wartości wynosi 1, kiedy jest zwalniany: 0, a kiedy przytrzymany: 2. Czy używając GTK można jakoś uzyskać dostęp do nieprzetworzonych danych wysyłanych przez klawiaturę w celu rozróżnienia tych przypadków?
Wiem też że można wysłać do układu elektronicznego klawiatury polecenie przełączające ją w tryb, w którym nie wysyła powtórzeń klawiszy (typematic repeat delay i typematic repeat rate), ale nie chciałbym korzystać z tego sposobu.

void klawisz_wcisniety(GtkWidget *widget,  GdkEventKey *event, gpointer  data)
{
/*funkcja wykonywana w momencie wciśnięcia klawisza*/
  uint klawisz;
  uint klawisz_hardware;
 
  klawisz = ((GdkEventKey*)event)->keyval;
  klawisz_hardware = ((GdkEventKey*)event)->hardware_keycode;
 
printf("klawisz wcisnięty: %8hd,%8hd\\n", klawisz, klawisz_hardware);
/*tymczasowa funkcja wyświetlająca kody wciśniętego klawisza*/
}


void klawisz_zwolniony(GtkWidget *widget,  GdkEventKey *event, gpointer  data)
{
/*funkcja wykonywana w momencie zwolnienia klawisza*/
  uint klawisz;
  uint klawisz_hardware;
 
  klawisz = ((GdkEventKey*)event)->keyval;
  klawisz_hardware = ((GdkEventKey*)event)->hardware_keycode;
 
printf("klawisz zwolniony: %8hd,%8hd\\n", klawisz, klawisz_hardware);
/*tymczasowa funkcja wyświetlająca kody zwolnionego klawisza*/
}

int main( int argc, char *argv[])
{
gtk_signal_connect(GTK_OBJECT(window),"key_press_event", G_CALLBACK(klawisz_wcisniety), NULL);
gtk_signal_connect(GTK_OBJECT(window),"key_release_event", G_CALLBACK(klawisz_zwolniony), NULL);
}

3
C/C++ / wczytywanie pliku konfiguracyjnego
« dnia: 2010-01-22, 13:39:46 »
Piszę program, który ma wczytywać ustawienia z pliku konfiguracyjnego. Chodzi głównie o deskryptory urządzeń, które są różne na poszczególnych komputerach.
Program otwiera plik i wczytuje kolejno wiersze:
void wczytaj_config()
{
FILE *filepointer;
filepointer = fopen("config.cfg","r");
char *wiersz;
if(filepointer == NULL)
{
puts("Nie można otworzyć pliku z ustawieniami");
/* tutaj przypisać wartości domyślne */
strcpy(keyboard_descriptor, "/dev/input/event5");
strcpy(joystick_descriptor, "/dev/input/js0");

comport_relayboard= 16;
comport_sk= 0;
}

else
{printf("[OTWARCIE PLIKU CONFIG]\\n");
while (fgets(wiersz,80,filepointer) != NULL)
{podziel(wiersz);}

fclose(filepointer);
printf("[ZAMKNIĘCIE PLIKU CONFIG]\\n");
}
}
Następnie (jeśli wiersz zawiera znak równości i nie zaczyna się od hasza) funkcja podziel dzieli wczytane wiersze na nazwę zmiennej (na lewo od znaku równości) i wartość zmiennej (na prawo od znaku równości):
int podziel(char* wiersz)
{  
int i= 0;
int dzielto = 0;
while (wiersz[i]!= '\\n')
{    
if (wiersz[i] == '=')
{dzielto= 1;}
i++;
/* jeśli w wierszu występuje znak równości */
}

if (wiersz[0] == '#')
{dzielto= 0;
/* jeśli wiersz NIE zaczyna się od hasza */
}  
  if (dzielto== 1)
  {
  char* zmienna= strtok (wiersz,"=");
  char* wartosc= strtok (NULL, "=");
przytnij(wartosc);
printf ("zmienna:<%s>, wartosc:<%s>\\n",zmienna, wartosc);
przypisz(zmienna, wartosc);
}

else
{printf ("niedziel: %s", wiersz);}
}
Funkcja przytnij obcina znak przejścia do nowego wiersza na końcu wartości oraz spacje na początku (jeśli występują).
void przytnij(char* wartosc)
{
 if (wartosc[0] == ' ')
{/* sprawdza czy na początku jest spacja */
  while (wartosc[0] == ' ')
  {/* obcina pierwszy znak i przesuwa całość w lewo dopóki nie trafi na pierwszy znak inny niż spacja */
  int i= 0;
  while (wartosc[i]!= '\\n')
  {
  wartosc[i]= wartosc[i+1];
  i++;
  }
  wartosc[i-1]= '\\0';
}
}
else
{
int i= 0;
while (wartosc[i]!= '\\n')
  {i++;}
  wartosc[i]= '\\0';
/* usuwa znak końca wiersza */
}
}
Potem można wydrukować obok siebie nazwę zmiennej i jej wartość:
printf ("zmienna:<%s>, wartosc:<%s>\\n",zmienna, wartosc);
Niestety problem pojawia się w momencie przypisywania wartości pobranych z pliku odpowiednim zmiennym. Ordynarne porównanie niestety nie działa, co objaśniono tutaj:
www.linuxforums.org/forum/linux-programming-scripting/126727-fscanf-read-configuration-files-c.html
if (zmienna == "deskryptor_klawiatury")
{keyboard_descriptor= wartosc;}
Natomiat kiedy używam funkcji strcmp porównującej ciągi znaków ma miejsce inne zjawisko:
if (strcmp(zmienna,"deskryptor_klawiatury")==0)
{keyboard_descriptor= wartosc;}
Program troszkę się zagalopowuje i kończy działanie z fragmentem ostatniej linijki pliku przypisanym jako wartość zmiennej.
Czy ktoś ma jakiś pomysł? Wydaje mi się że problem leży w ostatnim fragmencie. Do linijki wyświetlającej obok siebie nazwę i wartość zmiennej wszystko jest w porządku. Problemy zaczynają się przy przypisywaniu wartości.

Cały projekt można pobrać na forum.ubuntu.pl. Nie śmiejcie się ze sposobu przechwytywania zdarzeń klawiatury. Docelowo będzie to coś bardziej cywilizowanego.

Strony: [1]