Próbuję uzyskać zdjęcia z kamer internetowych. Istnieje usługa sieciowa php-python, która pobiera zdjęcia z kamer internetowych i udostępnia je: wyświetla obraz taki jak http://ip/jpeg/camera=1.

private HttpWebRequest request;
private HttpWebResponse response;
private CookieContainer container;
private Uri uri;
private string _user;
private string _pass;
private string _ip;
//Login code as seen in the previous section should be here
//GetImages is meant to run as a separate thread 
private void GetImages(string camNo)
{
//create the GET request for the JPEG snapshot (found at /jpeg on the IP Camera)
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://" + deviceIP + "/jpeg/camera"+camNo);
request.Method = "GET";
request.ContentType = "application/x-www-form-urlencoded";
request.CookieContainer = container;

//attempt to get a response from the IP110, event if error

try
{
    response = (HttpWebResponse)request.GetResponse();
}
catch (WebException e)
{
    ConnectionError(new ConnectionErrorEventArgs(e.Message));
}

//Get the stream containing the JPEG image.
Stream stream = response.GetResponseStream();

//Read the stream to memory.
byte[] buffer = new byte[100000];
int read, total = 0;

while ((read = stream.Read(buffer, total, 1000)) != 0)
{
    total += read;
}

//create a BMP image from the stream
Bitmap bmp = (Bitmap)Bitmap.FromStream(new MemoryStream(buffer, 0, total));

//send the bmp image to where you would like to display it. 
 }

... następnie przechowuję tę bitmapę jako jpeg w folderze. Mój problem zaczyna się tutaj; Chcę przeprowadzić ten proces tak szybko, jak to możliwe. Chcę robić zdjęcia z 50 kamerek używając tego kodu i przechowywać jako jpeg, i ma to być szybkie - to znaczy co 10 sekund muszę pobierać nowe zdjęcia z 50 kamer.

Użyłem timecontrol i dałem mu 500 ms co 500 ms program używał tego kodu powyżej numeru kamery i zapisywał jpeg, ale działa jeden po drugim, więc wydajność spada!

50ms x 500cams = 25000 ms (25s), jeśli ustawię interwał timera na 100 ms zatrzymanie programu. Kiedy używam powyższego kodu, otrzymuję bitmapę bmp w 200 ms, ale gdy próbuje pisać jako jpeg na dysku, zajmuje to dużo czasu.

Co mogę zrobić, aby szybciej zapisywać na dysku? Szukałem zmapowanej pamięci - czy to pomoże? Chcę przechowywać jpegi na dysku, ponieważ będę udostępniać te zdjęcia na stronie internetowej i udostępniać je ludziom. Czy mogę używać mapowania pamięci i udostępniać je publicznie za pośrednictwem witryny internetowej?

AKTUALIZACJA: Wykorzystałem również klasę WebClient do prac asynchronicznych, http://www.informit.com/guides/content.aspx?g =dotnet&seqNum=571

Rezultat był taki: uzyskać obraz o długości 300 ms i zapisywać go na dysku około 700 ms. Muszę więc znaleźć rozwiązanie, aby jak najwięcej zapisywać na dysk.

Który jest lepszy? Zapisać zdjęcia na dysk czy wysłać zdjęcia do bazy danych? Próbowałem przechowywać zdjęcia, aby były gotowe do podania, ponieważ na stronie ludzie muszą zobaczyć zaktualizowane zdjęcia. Który jest lepszy dla tysięcy zapytań klientów? Przechowywać je na dysku lub przechowywać w bazie danych jako binarne?

0
Mustafa Ekici 2 czerwiec 2011, 01:36
Czy to jest sieć? pulpit? mobilny?
 – 
balexandre
2 czerwiec 2011, 01:39
Jest to aplikacja komputerowa, obsługuje je usługa python-php i na tej samej maszynie próbuję uzyskać zdjęcia za pomocą powyższego kodu.
 – 
Mustafa Ekici
2 czerwiec 2011, 01:43

2 odpowiedzi

Najlepsza odpowiedź

Kod do pobrania obrazów jest synchroniczny. Sugeruję zmodyfikowanie kodu, aby używał HttpWebRequest.BeginGetResponse() do pobierania obrazów, jak opisano w ta odpowiedź.

Tak więc, gdy twój (pojedynczy) timer zostanie uruchomiony, rozpocznij asynchroniczne żądania do kamer, a następnie (po ich zakończeniu) wywołanie zwrotne zostanie uruchomione dla każdego zakończonego żądania i możesz zapisać zwrócony obraz.

Jeśli potrzebujesz dalszej optymalizacji, możesz delegować zapisywanie obrazu na dysku w tle ThreadPool element pracy.

1
Community 23 maj 2017, 15:22
Wiesz, co próbowałem wcześniej, zrobiłem tablicę Timer[] i jeśli jest 50 kamer, długość tablicy Timer wynosiła 50, więc gdy zegar działa, ten kod działa asynchronicznie, robię zdjęcia z kamer w tym samym czasie, ale wydajność była zbyt niska, kiedy ja zobacz zdjęcia, które są przechowywane, zostały zamrożone, nie można ich odświeżyć. Czy Twoja odpowiedź może być moim rozwiązaniem? co myślisz? Dzięki
 – 
Mustafa Ekici
2 czerwiec 2011, 02:01
1
Tak, lepiej byłoby użyć BeginGetResponse(), jak sugeruje @arcain. Problem z zegarami zależy od rodzaju wybranych zegarów, uruchamiasz je wszystkie w wątku interfejsu użytkownika i blokujesz interfejs użytkownika. Co więcej, lepiej jest również dodać do rekomendacji @arcain i warstw w wywołaniu asynchronicznym, aby wykonać czytanie strumienia, ponieważ jest to prawdopodobnie najbardziej czasochłonna część.
 – 
Michael Kennedy
2 czerwiec 2011, 02:37
Myślę, że klasa webclient ma już metodę asynchronicznego procesu. Użyłem go i działa tak, jak sądzę, szybciej niż Httprequest, pozostał jeden problem, jak mogę zapisywać na dysku tak dużo, jak to możliwe?
 – 
Mustafa Ekici
2 czerwiec 2011, 21:48

Za każdym razem, gdy potrzebujesz uzyskać odpowiedzi szybciej niż pozwalają na to skumulowane odpowiedzi, musisz wykonać wiele prac jednocześnie, używając więcej niż jednego wątku (ostatnie słowo jest tutaj wskazówką).

W .NET oznacza to albo skonfigurowanie własnej biblioteki wątków, użycie TPL itp.

DODANE: Może to oznaczać, jak wskazano w poniższym komentarzu, używanie wywołań asynchronicznych i umożliwienie frameworkowi niejawnego tworzenia wątków dla ciebie, zamiast samodzielnego kontrolowania ich. W rzeczywistości można korzystać z puli wątków i nadal wybierać asynchroniczną lub synchronizowaną bez kontrolowania liczby utworzonych wątków. Jeśli naprawdę chcesz przejść do sedna, możesz nawet odciążyć wątki do systemu operacyjnego za pomocą obsługi przerwań na poziomie systemu operacyjnego (metoda używana na przykład przez Rubiego przed wersją 1.9, która wprowadziła „prawdziwe” wątki zamiast „ zielone" wątki - tak, TMI).

Odpowiedź nadal pozostaje aktualna, jeśli masz 2 minuty pracy do wykonania i 30 sekund na wykonanie, potrzebujesz rozwiązania wielowątkowego, niezależnie od tego, czy jesteś świadomy, że faktycznie pracujesz w wątkach (tworzenie jawne), czy nie (obsługa tworzenia niejawnego przez framework/OS).

0
Gregory A Beamer 2 czerwiec 2011, 17:35
W rzeczywistości nie wiem nic o TPL, czy starzejesz się z @arcain?
 – 
Mustafa Ekici
2 czerwiec 2011, 01:56
-1 „konfigurowanie własnej biblioteki wątków” naprawdę? więc .NET nie ma nic do tego? co to jest BeginMETHOD? .NET ma wywołania asynchroniczne dla prawie każdej ważnej metody, po prostu ich użyj!
 – 
balexandre
2 czerwiec 2011, 16:31
@balexandre: Więc brakuje mi punktu, jeśli nie mówię „użyj niejawnego wątku przez wywołania asynchroniczne”. Było to dość ogólne stwierdzenie i poprawne, choć nie tak przekonujące, jak byś chciał. Zredagowałem go tylko po to, by cię zadowolić. ;-)
 – 
Gregory A Beamer
2 czerwiec 2011, 17:54