dim sar Ответов: 2

C# получение изображения номерного знака с ip-камеры


Я пытаюсь получить информацию о ЛНР с ip-камеры.
Структуры из пакета SDK:
[StructLayoutAttribute(LayoutKind.Sequential)]
        public struct NET_ITS_PLATE_RESULT
        {
             public uint dwSize;
            public uint dwMatchNo;//The match number, composed of vehicle serial number, data type and lane number;
             public byte byGroupNum;//The total number of picture groups (the number of pictures continuously captured when one car passed)
            public byte byPicNo;//The sequence number of the picture (if byPicNo==byGroupNum, it means finished to receive the last picture; if byPicNo! =byGroupNum, the picture will be deleted or reserved as needed)
            public byte bySecondCam;// whether captured by the second camera (e.g. the vista camera of the vision and close-up snapshot, or the rear camera of front and rear snapshot, will be used in special projects)
            public byte byFeaturePicNo;// which picture is taken as close-up view (it is used for automatic detecting system of vehicle violation of traffic signal), and 0xff means not take any one
            public byte byDriveChan;// the lane that triggered snapshot
            public byte byVehicleType;// Vehicle type, refer to VTR_RESULT
            public byte byDetSceneID;//detected scene ID[1,4], IPC is 0 by default
            public byte byVehicleAttribute;// 0-no additional Properties, 1- Yellow Label Car(Banner),2- Dangerous goods vehicles;
            public ushort wIllegalType;// Illegal type, definition of GB
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 8, ArraySubType = UnmanagedType.I1)]
            public byte[] byIllegalSubType;// Sub type of illegal behavior
            public byte byPostPicNo;// which picture is taken to record for intelligent vehicle monitoring and recording system, 0xff means not take any one;
            public byte byChanIndex;// Channel number (Reserved)
            public byte wSpeedLimit;// The upper limit of speed (valid when overspeed£©
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 2, ArraySubType = UnmanagedType.I1)]
            public byte[] byRes2;
            [MarshalAsAttribute(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.I1)]
            public NET_DVR_PLATE_INFO[] struPlateInfo;// License plate information
            public NET_DVR_VEHICLE_INFO struVehicleInfo;// Vehicle information
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 48, ArraySubType = UnmanagedType.I1)]
            public byte[] byMonitoringSiteID;// ID of monitoring point
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 48, ArraySubType = UnmanagedType.I1)]
            public byte[] byDeviceID;// ID of the device
            public byte byDir;// Monitoring direction: 1- up-road, 2- down-road, 3- two-way, 4- from east to west, 5- from south to north, 6- from west to east, 7- from north to south, 8- else
            public byte byDetectType;// Detection type: 1- triggered by inductive coil, 2- triggered by video detection, 3- multi-frame recognition, 4- triggered by radar
	// relevant lane direction type, please refer to ITC_RELA_LANE_DIRECTION_TYPE
	//Act as the parameter of lane direction, corresponding to the relevant lane number
            public byte byRelaLaneDirectionType;
            public byte byRes3;
            public uint dwCustomIllegalType;//illegal type definition(customized)
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 9, ArraySubType = UnmanagedType.I1)]
            public byte[] byRes4;
            public byte byPilotSafebelt;//0-unknown,1- Fastened seat belt,2-without seat belt
            public byte byCopilotSafebelt;// 0-unknown,1- Fastened seat belt,2-without seat belt
            public byte byPilotSunVisor;//0- unknown,1- sun louver closed,2- sun louver open
            public byte byCopilotSunVisor;// 0- unknown,1- sun louver closed,2- sun louver open
            public byte byPilotCall;// 0- unknown, 1-don΅―t make a phone call,2-call up//0- switch off, 1-non- switch off (Dedicated to the historical data in the camera after the match according to the black and white list, the flag of switch off success)
            public byte byBarrierGateCtrlType;
            public byte byAlarmDataType;//0-real time data, 1-history data
            public NET_DVR_TIME_V30 struSnapFirstPicTime;//time of the first picture captured (ms)
            public uint dwIllegalTime;//illegal time of duration(ms) = time of the last picture captured - time of the first picture captured;
            public uint dwPicNum;// The number of pictures (different form icGroupNum, it is the number of pictures in this message)
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 6, ArraySubType = UnmanagedType.I1)]
            public NET_ITS_PICTURE_INFO[] struPicInfo;// Picture information, up to 6 pitures  
        }


и

[StructLayoutAttribute(LayoutKind.Sequential)]
        public struct NET_ITS_PICTURE_INFO
        {
              public uint   dwDataLen;
              public byte   byType;
              [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 3, ArraySubType = UnmanagedType.I1)]
              public byte[]    byRes1;
              public uint   dwRedLightTime;
              [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 32, ArraySubType = UnmanagedType.I1)]
              public byte[]  byAbsTime;
              public NET_VCA_RECT  struPlateRect;
              public NET_VCA_RECT  struPlateRecgRect;
            public byte pBuffer;
              [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 12, ArraySubType = UnmanagedType.I1)]
              public byte[] byRes2;     
        }


При каждом распознавании номерного знака камера отправляет 2 снимка. Один маленький только с номерным знаком и один большой со всей площадью.
я могу взять номерной знак и все значения, которые мне нужны, но я не могу создать фотографии.

Код, который я использую в каждом сигнале, который посылает мне камера, таков::

CHCNetSDK.NET_ITS_PLATE_RESULT struITSPlateResult = new CHCNetSDK.NET_ITS_PLATE_RESULT { };
var ver = (CHCNetSDK.NET_ITS_PLATE_RESULT)Marshal.PtrToStructure(pAlarmInfo, typeof(CHCNetSDK.NET_ITS_PLATE_RESULT));
struITSPlateResult = (CHCNetSDK.NET_ITS_PLATE_RESULT)ver;


здесь все правильно.

Далее я должен создать 2 фотографии, которые отправит камера

ценности, которые я имею от camere, таковы:

struITSPlateResult.struPicInfo[i].dwDataLen
какой размер в uint

и

struITSPlateResult.struPicInfo[i].pBuffer
что такое буфер в байтах

с каждым кодом, который я пытаюсь создать из буфера изображений, я получаю поврежденные файлы

sdk имеет справку c++ для этого, но я не знаю, как ее правильно настроить

sprintf(filename, "testITSpic%d_%d.jpg", iNum, i);
fSnapPic = fopen(filename, "wb");
fwrite(struITSPlateResult.struPicInfo[i].pBuffer,struITSPlateResult.struPicInfo[i].dwDataLen, 1, fSnapPic);
iNum++;
fclose(fSnapPic);


Что я уже пробовал:

for (i = 0; i < struITSPlateResult.dwPicNum; i++)
{
   //Save scene picture
   if ((struITSPlateResult.struPicInfo[i].dwDataLen != 0) &&
      (struITSPlateResult.struPicInfo[i].byType == 1) ||
      (struITSPlateResult.struPicInfo[i].byType == 2))
   {
      string scene = System.IO.Path.Combine(pic_path, "scene.jpg");

      using (System.IO.FileStream fs = System.IO.File.Create(scene))
      {
         using (BinaryWriter writer = new BinaryWriter(fs))
         {
            IntPtr ptr = Marshal.AllocHGlobal((Marshal.SizeOf(struITSPlateResult.struPicInfo[i].dwDataLen)));
            Marshal.StructureToPtr(struITSPlateResult.struPicInfo[i].pBuffer, ptr, true);
            var bytes = new byte[struITSPlateResult.struPicInfo[i].dwDataLen];
            Marshal.Copy(ptr, bytes, 0, (int)struITSPlateResult.struPicInfo[i].dwDataLen);

            writer.Write(bytes, 0, (int)struITSPlateResult.struPicInfo[i].dwDataLen);
            Marshal.Release(ptr);
         }
      }
   }

   //License plate thumbnails
   if ((struITSPlateResult.struPicInfo[i].dwDataLen != 0) &&
      (struITSPlateResult.struPicInfo[i].byType == 0))
   {
      string plate_pic = System.IO.Path.Combine(pic_path, "plate.jpg");

      using (System.IO.FileStream fs = System.IO.File.Create(plate_pic))
      {
         using (BinaryWriter writer = new BinaryWriter(fs))
         {
            IntPtr ptr = Marshal.AllocHGlobal((Marshal.SizeOf(struITSPlateResult.struPicInfo[i].dwDataLen)));
            Marshal.StructureToPtr(struITSPlateResult.struPicInfo[i].pBuffer, ptr, true);
            var bytes = new byte[struITSPlateResult.struPicInfo[i].dwDataLen];
            Marshal.Copy(ptr, bytes, 0, (int)struITSPlateResult.struPicInfo[i].dwDataLen);

            writer.Write(bytes, 0, (int)struITSPlateResult.struPicInfo[i].dwDataLen);
            Marshal.Release(ptr);
         }
      }
   }
}

2 Ответов

Рейтинг:
1

Garth J Lancaster

Интересно, может быть, вместо того, чтобы копировать данные вот так, вам лучше использовать неуправляемый поток памяти Класс UnmanagedMemoryStream (System.IO)[^]

"может быть" это или что-то близкое к этому .....

// build filename string
string plate_pic_filename = System.IO.Path.Combine(pic_path, "plate.jpg");

// create file stream based on filename
// Set UnmanagedMemoryStream to the API's return byte pointer, length 

using FileStream plate_pic_stream = 
	new FileStream(plate_pic_filename, FileMode.Create, FileAccess.Write)
using (UnmanagedMemoryStream ustream = 
	new UnmanagedMemoryStream(
		(byte *)struITSPlateResult.struPicInfo[i].pBuffer, 
		(uint)struITSPlateResult.struPicInfo[i].dwDataLen)
{
	ustream.CopyTo(plate_pic_stream);
}


[edit] очевидно, что если бы эта "техника" работала, я бы абстрагировал ее в функцию или что-то в этом роде, так как она используется дважды [/edit]


dim sar

Спасибо за ваш ответ. Ваш код выдает ошибку:

Необработанное исключение типа 'System.AccessViolationException' произошло в mscorlib.dll

Там написано, что я пытаюсь читать память разрушителя.

Рейтинг:
0

Azmat Shir

Define Structure <pre>NET_ITS_PICTURE_INFO
подобный этому

[StructLayoutAttribute(LayoutKind.Sequential)]
        public struct NET_ITS_PICTURE_INFO
        {
            public uint dwDataLen;
            public byte byType;
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 3, ArraySubType = UnmanagedType.I1)]
            public byte[] byRes1;
            public uint dwRedLightTime;
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 32, ArraySubType = UnmanagedType.I1)]
            public byte[] byAbsTime;
            public NET_VCA_RECT struPlateRect;
            public NET_VCA_RECT struPlateRecgRect;
            public IntPtr pBuffer;
            public uint dwUTCTime;
            public byte byCompatibleAblity;
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 12, ArraySubType = UnmanagedType.I1)]
            public byte[] byRes2;
                                 

        }


Код для извлечения номера номерного знака и изображения

CHCNetSDK.NET_ITS_PLATE_RESULT struITSPlateResult = new CHCNetSDK.NET_ITS_PLATE_RESULT { };
           struITSPlateResult = (CHCNetSDK.NET_ITS_PLATE_RESULT)Marshal.PtrToStructure(pAlarmInfo, typeof(CHCNetSDK.NET_ITS_PLATE_RESULT));

           var licensePlateNo = new string(struITSPlateResult.struPlateInfo.sLicense);
           var countryIndex = struITSPlateResult.struPlateInfo.byCountry;
           var direction = struITSPlateResult.byDir;


           for (var i = 0; i < struITSPlateResult.dwPicNum; i++)
           {

           if ((struITSPlateResult.struPicInfo[i].dwDataLen != 0) && (struITSPlateResult.struPicInfo[i].byType == 0))
               {
                   var fileName = string.Format("LicensePlate_{0}.jpg", DateTime.Now.Ticks);

                   using (FileStream fs = File.Create(fileName))
                   {
                       var bytes = new byte[struITSPlateResult.struPicInfo[i].dwDataLen];
                       Marshal.Copy(struITSPlateResult.struPicInfo[i].pBuffer, bytes, 0, (int)struITSPlateResult.struPicInfo[i].dwDataLen);
                       fs.Write(bytes, 0, (int)struITSPlateResult.struPicInfo[i].dwDataLen);

                   }
               }
           }