lineCrossing shutter speed change app - Readable licences

trempa92

Pulling my weight
Joined
Mar 26, 2020
Messages
736
Reaction score
230
Location
Croatia,Zagreb
Greetings,

Creating this tread in hope to create a cheap solution for having a nice image + capturing licence plate without having 2 cameras or an expensive one.

I need testers for various hikvision cameras. I am giving away source + compiled version in return for your feedback.

Please let me know what else would need to be changed or added as a variable inside config file.

All you need to do is update configfile with your data, run exe and trigger linecrossing on camera.(Please install .net runtime 6.0 min, in order to run app)

1702626180000.png

1702626197022.png


Source:


C#:
using Newtonsoft.Json;
using System;
using System.IO;
using System.Net;
using System.Net.Http.Headers;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;

namespace TcpServerExample
{
    class Program
    {
        class Config
        {
            public ServerConfig Server { get; set; }
            public CameraConfig Camera { get; set; }
        }

        class ServerConfig
        {
            public string IpAddress { get; set; }
            public int Port { get; set; }
        }

        class CameraConfig
        {
            public string IpAddress { get; set; }
            public string cameraPort { get; set; }
            public string Username { get; set; }
            public string Password { get; set; }
            public string SlowShutter { get; set; }
            public string FastShutter { get; set; }
            public int switchDelay { get; set; }
        }


        static void Main(string[] args)
        {
            / Load configuration for the server
            string jsonConfig = File.ReadAllText("config.json");
            Config config = JsonConvert.DeserializeObject<Config>(jsonConfig);

            IPAddress serverAddr = IPAddress.Parse(config.Server.IpAddress);
            int port = config.Server.Port;
            string cameraIp = config.Camera.IpAddress;
            string cameraPort = config.Camera.cameraPort;

            / Use camera configuration from JSON        
            string cameraUsername = config.Camera.Username;
            string cameraPassword = config.Camera.Password;
            string slowShutter = config.Camera.SlowShutter;
            string fastShutter = config.Camera.FastShutter;
            int switchDelay = config.Camera.switchDelay;

            TcpListener server = new TcpListener(serverAddr, port);
            server.Start();
            Console.WriteLine($"Server is listening on {cameraIp}:{port}...");

            while (true)
            {
                Console.WriteLine("Waiting for client...");
                using (TcpClient client = server.AcceptTcpClient())
                {
                    Console.WriteLine("Client connected.");
                    try
                    {
                        using (NetworkStream stream = client.GetStream())
                        {
                            byte[] buffer = new byte[1024]; / Smaller buffer size
                            int bytesRead;
                            StringBuilder requestBuilder = new StringBuilder();

                            while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
                            {
                                requestBuilder.Append(Encoding.UTF8.GetString(buffer, 0, bytesRead));

                                / Check if we have read the linedetection data
                                if (requestBuilder.ToString().Contains("name=\"linedetection\""))
                                {
                                    / Process only the relevant part
                                    HandleLineDetectionEvent(cameraIp,cameraPort,slowShutter,fastShutter, cameraUsername, cameraPassword, switchDelay);
                                    break;
                                }
                            }

                            / Send a response back to the client
                            byte[] responseBytes = Encoding.ASCII.GetBytes("HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n");
                            stream.Write(responseBytes, 0, responseBytes.Length);
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"Exception: {ex.Message}");
                    }
                    Console.WriteLine("Client disconnected.");
                }
            }
        }

        static async void HandleLineDetectionEvent(string cameraIp, string cameraPort, string slowShutter,string fastShutter,string cameraUsername,string cameraPassword, int switchDelay)
        {

            string cameraUrl = "http://"+ cameraIp + "/ISAPI/Image/channels/1/shutter";

            var credentialCache = new CredentialCache();
            credentialCache.Add(new Uri(cameraUrl), "Digest", new NetworkCredential(cameraUsername, cameraPassword));

            using var httpClientHandler = new HttpClientHandler
            {
                Credentials = credentialCache
            };
            using var httpClient = new HttpClient(httpClientHandler);

            / Set common headers (if necessary, adjust according to your requirements)
            httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*"));
            httpClient.DefaultRequestHeaders.Connection.Add("keep-alive");
            httpClient.DefaultRequestHeaders.CacheControl = new CacheControlHeaderValue { NoCache = true };

            / First PUT request
            var firstContent = new StringContent("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Shutter><ShutterLevel>1/"+fastShutter+"</ShutterLevel></Shutter>", Encoding.UTF8, "application/x-www-form-urlencoded");
            var firstResponse = await httpClient.PutAsync(cameraUrl, firstContent);
            Console.WriteLine("Switching to fast shutter: " + firstResponse.StatusCode);

            / Wait for 5 seconds
            await Task.Delay(switchDelay);

            / Second PUT request
            var secondContent = new StringContent("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Shutter><ShutterLevel>1/"+slowShutter+"</ShutterLevel></Shutter>", Encoding.UTF8, "application/x-www-form-urlencoded");
            var secondResponse = await httpClient.PutAsync(cameraUrl, secondContent);
            Console.WriteLine("Switching back to slow shutter: " + secondResponse.StatusCode);
        }

    }
}
After testing, please comment out:

Camera Model:
Camera firmware:
Scenario:
Results comment:
Adjustments neded:

Thank you, cheers
 

Attachments

Last edited:

paulpeter

n3wb
Joined
May 31, 2018
Messages
11
Reaction score
6
Location
china
this is the cheap ANPR mode in Hikvison DS-2CD3646G2T/P-IZSY(2.7-13.5mm)eF/O-STD
 

trempa92

Pulling my weight
Joined
Mar 26, 2020
Messages
736
Reaction score
230
Location
Croatia,Zagreb
Updated code to Capture image upon switching to fastShutter


C#:
using Newtonsoft.Json;
using System;
using System.IO;
using System.Net;
using System.Net.Http.Headers;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;

namespace TcpServerExample
{
    class Program
    {
        class Config
        {
            public ServerConfig Server { get; set; }
            public CameraConfig Camera { get; set; }
        }

        class ServerConfig
        {
            public string IpAddress { get; set; }
            public int Port { get; set; }
        }

        class CameraConfig
        {
            public string IpAddress { get; set; }
            public string cameraPort { get; set; }
            public string Username { get; set; }
            public string Password { get; set; }
            public string SlowShutter { get; set; }
            public string FastShutter { get; set; }
            public int switchDelay { get; set; }
        }


        static void Main(string[] args)
        {
            / Load configuration for the server
            string jsonConfig = File.ReadAllText("config.json");
            Config config = JsonConvert.DeserializeObject<Config>(jsonConfig);

            IPAddress serverAddr = IPAddress.Parse(config.Server.IpAddress);
            int port = config.Server.Port;
            string cameraIp = config.Camera.IpAddress;
            string cameraPort = config.Camera.cameraPort;

            / Use camera configuration from JSON         
            string cameraUsername = config.Camera.Username;
            string cameraPassword = config.Camera.Password;
            string slowShutter = config.Camera.SlowShutter;
            string fastShutter = config.Camera.FastShutter;
            int switchDelay = config.Camera.switchDelay;

            TcpListener server = new TcpListener(serverAddr, port);
            server.Start();
            Console.WriteLine($"Server is listening on {cameraIp}:{port}...");

            while (true)
            {
                Console.WriteLine("Waiting for client...");
                using (TcpClient client = server.AcceptTcpClient())
                {
                    Console.WriteLine("Client connected.");
                    try
                    {
                        using (NetworkStream stream = client.GetStream())
                        {
                            byte[] buffer = new byte[1024]; / Smaller buffer size
                            int bytesRead;
                            StringBuilder requestBuilder = new StringBuilder();

                            while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
                            {
                                requestBuilder.Append(Encoding.UTF8.GetString(buffer, 0, bytesRead));

                                / Check if we have read the linedetection data
                                if (requestBuilder.ToString().Contains("name=\"linedetection\""))
                                {
                                    / Process only the relevant part
                                    HandleLineDetectionEvent(cameraIp,cameraPort,slowShutter,fastShutter, cameraUsername, cameraPassword, switchDelay);
                                    break;
                                }
                            }

                            / Send a response back to the client
                            byte[] responseBytes = Encoding.ASCII.GetBytes("HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n");
                            stream.Write(responseBytes, 0, responseBytes.Length);
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"Exception: {ex.Message}");
                    }
                    Console.WriteLine("Client disconnected.");
                }
            }
        }

        static async void HandleLineDetectionEvent(string cameraIp, string cameraPort, string slowShutter,string fastShutter,string cameraUsername,string cameraPassword, int switchDelay)
        {

            
 
            string cameraUrl = "http://"+ cameraIp + "/ISAPI/Image/channels/1/shutter";

            var credentialCache = new CredentialCache();
            credentialCache.Add(new Uri(cameraUrl), "Digest", new NetworkCredential(cameraUsername, cameraPassword));

            using var httpClientHandler = new HttpClientHandler
            {
                Credentials = credentialCache
            };
            using var httpClient = new HttpClient(httpClientHandler);

            / Set common headers (if necessary, adjust according to your requirements)
            httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*"));
            httpClient.DefaultRequestHeaders.Connection.Add("keep-alive");
            httpClient.DefaultRequestHeaders.CacheControl = new CacheControlHeaderValue { NoCache = true };

            / First PUT request
            var firstContent = new StringContent("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Shutter><ShutterLevel>1/"+fastShutter+"</ShutterLevel></Shutter>", Encoding.UTF8, "application/x-www-form-urlencoded");
            var firstResponse = await httpClient.PutAsync(cameraUrl, firstContent);
            Console.WriteLine("Switching to fast shutter: " + firstResponse.StatusCode);

            / Wait for 5 seconds
            await Task.Delay(1000);
            await DownloadImage(cameraIp, cameraPort, cameraUsername, cameraPassword);
            Console.WriteLine("Taking screenshot with fast shutter");
            await Task.Delay(4000);
            / Second PUT request
            var secondContent = new StringContent("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Shutter><ShutterLevel>1/"+slowShutter+"</ShutterLevel></Shutter>", Encoding.UTF8, "application/x-www-form-urlencoded");
            var secondResponse = await httpClient.PutAsync(cameraUrl, secondContent);
            Console.WriteLine("Switching back to slow shutter: " + secondResponse.StatusCode);
        }

        static async Task DownloadImage(string cameraIp, string cameraPort , string username, string password)
        {

            string url = "http://"+cameraIp+":"+cameraPort+ "/ISAPI/Streaming/channels/101/picture";

            var credentialCache = new System.Net.CredentialCache();
            credentialCache.Add(new Uri(url), "Digest", new System.Net.NetworkCredential(username, password));

            using var httpClientHandler = new HttpClientHandler
            {
                Credentials = credentialCache
            };
            using var httpClient = new HttpClient(httpClientHandler);

            var response = await httpClient.GetAsync(url);
            if (response.IsSuccessStatusCode)
            {
                var imageData = await response.Content.ReadAsByteArrayAsync();
                SaveImage(imageData);
            }
            else
            {
                throw new Exception("Failed to download the image.");
            }
        }

        static void SaveImage(byte[] imageData)
        {
            string directoryPath = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "images");
            if (!Directory.Exists(directoryPath))
            {
                Directory.CreateDirectory(directoryPath);
            }

            string fileName = DateTime.Now.ToString("dd-MM-yyyy-HH-mm-ss") + ".jpg";
            string filePath = Path.Combine(directoryPath, fileName);

            File.WriteAllBytes(filePath, imageData);
        }


    }
}
 

venturis

Getting the hang of it
Joined
Aug 8, 2016
Messages
157
Reaction score
98
Location
Australia
I decided to give it a try however, the app didn't appear to see the line crossing trigger events from my camera. Probably something I've missed. I opened the firewall to the app.

Any reason the app might not work for a camera located behind an NVR? I have a Hikvision NVR with the passthrough enabled. I also have static routes set on my local LAN to direct traffic directly to NVR subnet from the local LAN allows the camera to be reached directly from its IP address on the NVR subnet.

As an alternative, why not just trigger a scene change (say, Daylight -> Low Illumination) which could be pre-set with the desired settings rather than manipulating only shutter speed. In a lot of cases LPR will benefit from HLC being enabled which under normal circumstances you may not want.

Good work.
 

trempa92

Pulling my weight
Joined
Mar 26, 2020
Messages
736
Reaction score
230
Location
Croatia,Zagreb
As an alternative, why not just trigger a scene change (say, Daylight -> Low Illumination) which could be pre-set with the desired settings rather than manipulating only shutter speed.

Because people want to have good quality and readable licences. Often doesnt go together due to fast shutter. But changing scenes is not something that cant be done. Could be entirelly different config for that. Like choose Automation dropdown.

the app didn't appear to see the line crossing trigger events from my camera

Have you entered Alarm center inside camera? It needs to have a pointer where to push events.

1703055674847.png

In a lot of cases LPR will benefit from HLC being enabled which under normal circumstances you may not want.

Something that i can easily trigger by adding it to config file as true/false

Any reason the app might not work for a camera located behind an NVR?

That depend how NVR does outing. usually on PoE NVR's there is a virtual host in order to access cameras, perhaps that virtual host does not allow event traffic over alarm server. I might be mistaken but could be one of the reasons.


One more reason can be why linecrossing wasnt detected is that your camera linecrossing does not contain Contains("name=\"linedetection\""), in order to test that use updated app that outputs all raw data received in console(attachment).



ps: Who ever wants a cheap solution for this without having PC running/vm or something. I have tested and it works stable on RaPi 4 Windows arm as a service installed.
 

Attachments

Last edited:

venturis

Getting the hang of it
Joined
Aug 8, 2016
Messages
157
Reaction score
98
Location
Australia
I set the IP address of the server app in the alarm centre of the IP camera. That did not appear to work.

I then wondered if I should try setting the IP address for the server app in the NVR instead. That also did not work.

Virtual Host is enabled on the NVR. The camera is directly accessible from it's IP address on the local LAN from the PC running the server software.

Out of interest I'll keep trying over the next week.
 

venturis

Getting the hang of it
Joined
Aug 8, 2016
Messages
157
Reaction score
98
Location
Australia
Finally, had some success.

Camera Model: 2CD2386G2-LSU/LU
Camera firmware: 5.5.801
Scenario: Camera connected directly to a Hikvision NVR. Virtual host enabled.
Results comment:
1. The alarm server was only reachable from the camera when port was set to "80". All other port numbers failed.
2. The app failed to set the shutter speed. See below. This may be caused by "Image Parameters Switch" setting enabled under the camera Image Settings.

Switching to fast shutter: Forbidden
Client disconnected.
Waiting for client...
Client connected.
Received Data: POST / HTTP/1.1
Content-Type: application/xml; charset="UTF-8"
Host: 192.168.0.243
Connection: Keep-Alive
Content-Length: 764


Adjustments needed: When camera is located behind an NVR, server listening port number should default to 80. Not working with "Image Switch Parameter" settting.
 

trempa92

Pulling my weight
Joined
Mar 26, 2020
Messages
736
Reaction score
230
Location
Croatia,Zagreb
This may be caused by "Image Parameters Switch" setting enabled under the camera Image Settings.

Yes this is it, if you have image parameter switch schedule enabled you cant manually change shutter.
 

bp2008

Staff member
Joined
Mar 10, 2014
Messages
12,678
Reaction score
14,032
Location
USA
Bravo for creating this. I was not aware you could get a camera to promptly push out a simple HTTP request like that upon a line crossing event. So I always sort of assumed there would be too much lag between the motion/vehicle detection and getting the exposure/gain changed for license plate capture. I figured such a feature would need to be implemented directly in the camera's firmware in order to be very effective, but I never saw it done before (do proper LPR cameras have this sort of dual exposure thing??).

I would be curious to see some clips of this working.
 

trempa92

Pulling my weight
Joined
Mar 26, 2020
Messages
736
Reaction score
230
Location
Croatia,Zagreb
@bp2008 The LPR camera is calibrated to capture licence plate regardless how video look to human eye(Dark and barely visable)
So they are not meant to be part of video surveillance its rather access control cameras.

But what i am trying to do is , use normal vdeosurveillance cameras to capture plate on video atleast and then to get back to normal state.

I have tested on 2686G2-IZS and it seems only a second is needed to switch and adapt from 25 to 4000 shutter image.
Afterall this script will work as good as camera allows it.

I will do some real scene tests and post back
 
Last edited:

trempa92

Pulling my weight
Joined
Mar 26, 2020
Messages
736
Reaction score
230
Location
Croatia,Zagreb
Next step will be implementing open source OCR to captured image(under fast shutter). Hopefully some good results will come out of it.
 

johnfitz

Getting comfortable
Joined
Feb 4, 2021
Messages
319
Reaction score
452
Location
NY
Howdy @trempa92 ... this seems interesting, and I wanted to try it out... but, when I downloaded the V1.01 zip file Windows Defender reported this:

Screenshot 2024-03-10 215030.png

Can you post the source code for this latest release that includes the "outputs all raw data received in console(attachment). "
 

wittaj

IPCT Contributor
Joined
Apr 28, 2019
Messages
25,042
Reaction score
48,830
Location
USA
Howdy @trempa92 ... this seems interesting, and I wanted to try it out... but, when I downloaded the V1.01 zip file Windows Defender reported this:

View attachment 189085

Can you post the source code for this latest release that includes the "outputs all raw data received in console(attachment). "
I can't speak to the file itself, but it is how the "unknown Publisher" or "potential virus" or "compromised" messages are generated (just called virus moving forward in the rest of this post for simplicity).

It is not a virus, rather it is whatever antivirus you are using has flagged it as a potential virus. Some programs look at the total number of users and below a certain number, it is flagged. These specialty type files/programs get false positives all the time.

Something created by someone that nobody else is using will be flagged. You have to decide whether you want to trust the user or not.

You can check the file with VirusTotal , an antivirus website owned by Google that runs it thru a lot of different antivirus algorithms and see if it finds anything.
 

johnfitz

Getting comfortable
Joined
Feb 4, 2021
Messages
319
Reaction score
452
Location
NY
I figured it was a false positive from what I just googled... and I do trust the source... thanks for confirming!
 

johnfitz

Getting comfortable
Joined
Feb 4, 2021
Messages
319
Reaction score
452
Location
NY
Hi @trempa92 ... Good stuff... I'm trying this out... it runs to this section:

/ First PUT request var firstContent = new StringContent("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Shutter><ShutterLevel>1/"+fastShutter+"</ShutterLevel></Shutter>", Encoding.UTF8, "application/x-www-form-urlencoded"); var firstResponse = await httpClient.PutAsync(cameraUrl, firstContent); Console.WriteLine("Switching to fast shutter: " + firstResponse.StatusCode);
I know the first put request to the camera works, because the shutter speed on the camera change to the fast 4000 speed... but then it does not do the console write "Switching to fast shutter".... the next console output is "Client disconnected"...

Also, I can only connect to a test camera I have on the LAN... can't seem to connect to a camera on the DVR PoE port using virtual terminal... I did use 80 as the server port as @venturis mentioned above... do I have to have a default gateway set on the camera and this:

I also have static routes set on my local LAN to direct traffic directly to NVR subnet from the local LAN allows the camera to be reached directly from its IP address on the NVR subnet.
Maybe this is how @venturis is able to connect to the camera on the NVR?
 

trempa92

Pulling my weight
Joined
Mar 26, 2020
Messages
736
Reaction score
230
Location
Croatia,Zagreb
You need to enable virtual host, use the NVR ip address plus port 6500(Channelnumber) for example channel 1 is 65001. In Theory it should work.

Regarding the virus trigger, it is most likely unsigned and uncertiffied application. It is false positive.

Latest source code:


Code:
using Newtonsoft.Json;
using System;
using System.IO;
using System.Net;
using System.Net.Http.Headers;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;

namespace TcpServerExample
{
    class Program
    {
        class Config
        {
            public ServerConfig Server { get; set; }
            public CameraConfig Camera { get; set; }
        }

        class ServerConfig
        {
            public string IpAddress { get; set; }
            public int Port { get; set; }
        }

        class CameraConfig
        {
            public string IpAddress { get; set; }
            public string cameraPort { get; set; }
            public string Username { get; set; }
            public string Password { get; set; }
            public string SlowShutter { get; set; }
            public string FastShutter { get; set; }
            public int switchDelay { get; set; }
        }


        static void Main(string[] args)
        {
            / Load configuration for the server
            string jsonConfig = File.ReadAllText("config.json");
            Config config = JsonConvert.DeserializeObject<Config>(jsonConfig);

            IPAddress serverAddr = IPAddress.Parse(config.Server.IpAddress);
            int port = config.Server.Port;
            string cameraIp = config.Camera.IpAddress;
            string cameraPort = config.Camera.cameraPort;

            / Use camera configuration from JSON         
            string cameraUsername = config.Camera.Username;
            string cameraPassword = config.Camera.Password;
            string slowShutter = config.Camera.SlowShutter;
            string fastShutter = config.Camera.FastShutter;
            int switchDelay = config.Camera.switchDelay;

            TcpListener server = new TcpListener(serverAddr, port);
            server.Start();
            Console.WriteLine($"Server is listening on {cameraIp}:{port}...");

            while (true)
            {
                Console.WriteLine("Waiting for client...");
                using (TcpClient client = server.AcceptTcpClient())
                {
                    Console.WriteLine("Client connected.");
                    try
                    {
                        using (NetworkStream stream = client.GetStream())
                        {
                            byte[] buffer = new byte[1024]; / Smaller buffer size
                            int bytesRead;
                            StringBuilder requestBuilder = new StringBuilder();

                            while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
                            {
                                string receivedData = Encoding.UTF8.GetString(buffer, 0, bytesRead);
                                Console.WriteLine("Received Data: " + receivedData); / Output the received data
                                requestBuilder.Append(receivedData);

                                / Check if we have read the linedetection data
                                if (requestBuilder.ToString().Contains("name=\"linedetection\""))
                                {
                                    / Process only the relevant part
                                    HandleLineDetectionEvent(cameraIp, cameraPort, slowShutter, fastShutter, cameraUsername, cameraPassword, switchDelay);
                                    break;
                                }
                            }

                            / Send a response back to the client
                            byte[] responseBytes = Encoding.ASCII.GetBytes("HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n");
                            stream.Write(responseBytes, 0, responseBytes.Length);
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"Exception: {ex.Message}");
                    }
                    Console.WriteLine("Client disconnected.");
                }
            }
        }

        static async void HandleLineDetectionEvent(string cameraIp, string cameraPort, string slowShutter,string fastShutter,string cameraUsername,string cameraPassword, int switchDelay)
        {

            
  
            string cameraUrl = "http://"+ cameraIp + "/ISAPI/Image/channels/1/shutter";

            var credentialCache = new CredentialCache();
            credentialCache.Add(new Uri(cameraUrl), "Digest", new NetworkCredential(cameraUsername, cameraPassword));

            using var httpClientHandler = new HttpClientHandler
            {
                Credentials = credentialCache
            };
            using var httpClient = new HttpClient(httpClientHandler);

            / Set common headers (if necessary, adjust according to your requirements)
            httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*"));
            httpClient.DefaultRequestHeaders.Connection.Add("keep-alive");
            httpClient.DefaultRequestHeaders.CacheControl = new CacheControlHeaderValue { NoCache = true };

            / First PUT request
            var firstContent = new StringContent("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Shutter><ShutterLevel>1/"+fastShutter+"</ShutterLevel></Shutter>", Encoding.UTF8, "application/x-www-form-urlencoded");
            var firstResponse = await httpClient.PutAsync(cameraUrl, firstContent);
            Console.WriteLine("Switching to fast shutter: " + firstResponse.StatusCode);

            / Wait for 5 seconds
            await Task.Delay(500);
            await DownloadImage(cameraIp, cameraPort, cameraUsername, cameraPassword);
            Console.WriteLine("Taking screenshot with fast shutter");
            await Task.Delay(switchDelay);
            / Second PUT request
            var secondContent = new StringContent("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Shutter><ShutterLevel>1/"+slowShutter+"</ShutterLevel></Shutter>", Encoding.UTF8, "application/x-www-form-urlencoded");
            var secondResponse = await httpClient.PutAsync(cameraUrl, secondContent);
            Console.WriteLine("Switching back to slow shutter: " + secondResponse.StatusCode);
        }

        static async Task DownloadImage(string cameraIp, string cameraPort , string username, string password)
        {

            string url = "http://"+cameraIp+":"+cameraPort+ "/ISAPI/Streaming/channels/101/picture";

            var credentialCache = new System.Net.CredentialCache();
            credentialCache.Add(new Uri(url), "Digest", new System.Net.NetworkCredential(username, password));

            using var httpClientHandler = new HttpClientHandler
            {
                Credentials = credentialCache
            };
            using var httpClient = new HttpClient(httpClientHandler);

            var response = await httpClient.GetAsync(url);
            if (response.IsSuccessStatusCode)
            {
                var imageData = await response.Content.ReadAsByteArrayAsync();
                SaveImage(imageData);
            }
            else
            {
                throw new Exception("Failed to download the image.");
            }
        }

        static void SaveImage(byte[] imageData)
        {
            string directoryPath = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "images");
            if (!Directory.Exists(directoryPath))
            {
                Directory.CreateDirectory(directoryPath);
            }

            string fileName = DateTime.Now.ToString("dd-MM-yyyy-HH-mm-ss") + ".jpg";
            string filePath = Path.Combine(directoryPath, fileName);

            File.WriteAllBytes(filePath, imageData);
        }


    }
}
}

This is config file for server/channel

1710141327361.png

Play with switchDelay to get the best outcome. Depends on scene, if cars are faster, switchDelay should be around 1000, if its like a parking lot or driveway, leave it at 5000.

Client disconnected.
Waiting for client...
Client connected.


This msg you receive means events pushing to server are filtered, can be anything from motion detection, videoloss, some exception,...
Hence you can see connect/disconnect

I am filtering them out, and using line crossing only.
 

Attachments

trempa92

Pulling my weight
Joined
Mar 26, 2020
Messages
736
Reaction score
230
Location
Croatia,Zagreb
I am working now on codeproject alpr to detect plates, and store either in db or some file(OR store images of vehicles with filename as platenumber and timestamp). Something that blue iris already have
 

trempa92

Pulling my weight
Joined
Mar 26, 2020
Messages
736
Reaction score
230
Location
Croatia,Zagreb
I wonder why it cant detect anything :/ I guess not many effective pixels, but object detecting detects its a plate. Any Codeproject user that have an idea whats the issue? Perhaps angle is just bad

1710667038692.png

1710667185740.png
 
Top