diff --git a/src/bindings/csharp/openalpr-net/AssemblyInfo.cpp b/src/bindings/csharp/openalpr-net/AssemblyInfo.cpp index f600e22..ac5af8d 100644 --- a/src/bindings/csharp/openalpr-net/AssemblyInfo.cpp +++ b/src/bindings/csharp/openalpr-net/AssemblyInfo.cpp @@ -31,9 +31,9 @@ using namespace System::Security::Permissions; // You can specify all the value or you can default the Revision and Build Numbers // by using the '*' as shown below: -[assembly: AssemblyVersionAttribute("2.0.1")] -[assembly: AssemblyFileVersionAttribute("2.0.1")] -[assembly: AssemblyInformationalVersionAttribute("2.0.1")] +[assembly: AssemblyVersionAttribute("2.1.0")] +[assembly: AssemblyFileVersionAttribute("2.1.0")] +[assembly: AssemblyInformationalVersionAttribute("2.1.0")] [assembly:ComVisible(false)]; diff --git a/src/bindings/csharp/openalpr-net/bitmapmat-net.cpp b/src/bindings/csharp/openalpr-net/bitmapmat-net.cpp new file mode 100644 index 0000000..69db8f7 --- /dev/null +++ b/src/bindings/csharp/openalpr-net/bitmapmat-net.cpp @@ -0,0 +1,27 @@ +#include "stdafx.h" +#include "bitmapmat-net.h" + +using namespace openalprnet; + +BitmapMat::BitmapMat(array^ byteArray) +{ + this->m_bitmap = ByteArrayToMat(byteArray); +} + +BitmapMat::BitmapMat(Bitmap^ bitmap) +{ + this->m_bitmap = BitmapToMat(bitmap); +} + +BitmapMat::BitmapMat(MemoryStream^ memoryStream) +{ + this->m_bitmap = MemoryStreamBitmapToMat(memoryStream); +} + +BitmapMat::BitmapMat(String^ filename) +{ + Bitmap^ bitmap = gcnew Bitmap(filename); + this->m_bitmap = BitmapToMat(bitmap); + delete bitmap; +} + diff --git a/src/bindings/csharp/openalpr-net/bitmapmat-net.h b/src/bindings/csharp/openalpr-net/bitmapmat-net.h new file mode 100644 index 0000000..a65acf3 --- /dev/null +++ b/src/bindings/csharp/openalpr-net/bitmapmat-net.h @@ -0,0 +1,106 @@ +#pragma once + +#include "opencv2/imgproc/imgproc.hpp" + +using namespace System; +using namespace System::Drawing; +using namespace System::Drawing::Imaging; +using namespace System::IO; + +namespace openalprnet { + + private ref class BitmapMat : IDisposable + { + private: + cv::Mat* m_bitmap; + bool m_disposed; + public: + BitmapMat(array^ byteArray); + BitmapMat(Bitmap^ bitmap); + BitmapMat(MemoryStream^ memoryStream); + BitmapMat(String^ filename); + + ~BitmapMat() + { + if (this->m_disposed) + { + return; + } + + this->!BitmapMat(); + this->m_disposed = true; + } + + !BitmapMat() + { + delete[] m_bitmap->data; + } + + property cv::Mat Value { + cv::Mat get() + { + cv::Mat value = this->m_bitmap->clone(); + return value; + } + } + + private: + + static cv::Mat* BitmapToMat(Bitmap^ bitmap) + { + int channels = 0; + + switch (bitmap->PixelFormat) + { + case PixelFormat::Format8bppIndexed: + case PixelFormat::Format1bppIndexed: + channels = 1; + break; + case PixelFormat::Format24bppRgb: + channels = 3; + break; + case PixelFormat::Format32bppRgb: + case PixelFormat::Format32bppArgb: + case PixelFormat::Format32bppPArgb: + channels = 4; + break; + default: + throw gcnew NotImplementedException(); + } + + BitmapData^ bitmapData = bitmap->LockBits( + System::Drawing::Rectangle(0, 0, bitmap->Width, bitmap->Height), + ImageLockMode::ReadOnly, + bitmap->PixelFormat + ); + + const int totalBytes = bitmap->Height * bitmapData->Stride; + + char *dst = new char[totalBytes]; + ::memcpy(dst, bitmapData->Scan0.ToPointer(), totalBytes); + + cv::Mat* dstMat = new cv::Mat(cv::Size(bitmap->Width, bitmap->Height), CV_8UC(channels), dst); + + bitmap->UnlockBits(bitmapData); + + return dstMat; + } + + static cv::Mat* MemoryStreamBitmapToMat(MemoryStream^ memoryStream) + { + Bitmap^ bitmap = gcnew Bitmap(memoryStream); + cv::Mat* mat = BitmapToMat(bitmap); + delete bitmap; + return mat; + } + + static cv::Mat* ByteArrayToMat(array^ byteArray) + { + MemoryStream^ ms = gcnew MemoryStream(byteArray); + cv::Mat* mat = MemoryStreamBitmapToMat(ms); + delete ms; + return mat; + } + + }; +} \ No newline at end of file diff --git a/src/bindings/csharp/openalpr-net/config-net.h b/src/bindings/csharp/openalpr-net/config-net.h new file mode 100644 index 0000000..b1c7331 --- /dev/null +++ b/src/bindings/csharp/openalpr-net/config-net.h @@ -0,0 +1,666 @@ +#pragma once + +#include "config.h" // alpr +#include "types-net.h" +#include "helper-net.h" + +using namespace System; +using namespace openalprnet::types; + +namespace openalprnet +{ + + public ref class AlprConfigNet sealed + { + internal: + AlprConfigNet(Config* config) : m_config(config) + { + + } + + public: + + property bool IsLoaded { + bool get() + { + return this->m_config->loaded; + } + } + + property AlprDetectorTypeNet Detector { + AlprDetectorTypeNet get() { + return static_cast(this->m_config->detector); + } + void set(AlprDetectorTypeNet value) + { + this->m_config->detector = static_cast(value); + } + } + + property float DetectionIterationIncrease { + float get() + { + return this->m_config->detection_iteration_increase; + } + void set(float value) + { + this->m_config->detection_iteration_increase = value; + } + } + + property int DetectionStrictness { + int get() + { + return this->m_config->detectionStrictness; + } + void set(int value) + { + this->m_config->detectionStrictness = value; + } + } + + property float MaxPlateWidthPercent { + float get() + { + return this->m_config->maxPlateWidthPercent; + } + void set(float value) + { + this->m_config->maxPlateWidthPercent = value; + } + } + + property float MaxPlateHeightPercent { + float get() + { + return this->m_config->maxPlateHeightPercent; + } + void set(float value) + { + this->m_config->maxPlateHeightPercent = value; + } + } + + property int MaxDetectionInputWidth { + int get() + { + return this->m_config->maxDetectionInputWidth; + } + void set(int value) + { + this->m_config->maxDetectionInputWidth = value; + } + } + + property int MaxDetectionInputHeight { + int get() + { + return this->m_config->maxDetectionInputHeight; + } + void set(int value) + { + this->m_config->maxDetectionInputHeight = value; + } + } + + property bool SkipDetection { + bool get() + { + return this->m_config->skipDetection; + } + void set(bool value) + { + this->m_config->skipDetection = true; + } + } + + property String^ PreWarp { + String^ get() + { + return AlprHelper::ToManagedString(this->m_config->prewarp); + } + void set(String^ value) + { + if(String::IsNullOrWhiteSpace(value)) + { + this->m_config->prewarp = ""; + return; + } + this->m_config->prewarp = marshal_as(value); + } + } + + property int MaxPlateAngleDegrees { + int get() + { + return this->m_config->maxPlateAngleDegrees; + } + void set(int value) + { + this->m_config->maxPlateAngleDegrees = value; + } + } + + property float MinPlateSizeWidthPx { + float get() + { + return this->m_config->minPlateSizeWidthPx; + } + void set(float value) + { + this->m_config->minPlateSizeWidthPx = value; + } + } + + property float MinPlateSizeHeightPx { + float get() + { + return this->m_config->minPlateSizeHeightPx; + } + void set(float value) + { + this->m_config->minPlateSizeHeightPx = value; + } + } + + property bool Multiline { + bool get() + { + return this->m_config->multiline; + } + void set(bool value) + { + this->m_config->multiline = value; + } + } + + property float PlateWidthMM { + float get() + { + return this->m_config->plateWidthMM; + } + void set(float value) + { + this->m_config->plateWidthMM = value; + } + } + + property float PlateHeightMM { + float get() + { + return this->m_config->plateHeightMM; + } + void set(float value) + { + this->m_config->plateHeightMM = value; + } + } + + property float CharHeightMM { + float get() + { + return this->m_config->charHeightMM; + } + void set(float value) + { + this->m_config->charHeightMM = value; + } + } + + property float CharWidthMM { + float get() + { + return this->m_config->charWidthMM; + } + void set(float value) + { + this->m_config->charWidthMM = value; + } + } + + property float CharWhitespaceTopMM { + float get() + { + return this->m_config->charWhitespaceTopMM; + } + void set(float value) + { + this->m_config->charWhitespaceTopMM = value; + } + } + + property float CharWhitespaceBotMM { + float get() + { + return this->m_config->charWhitespaceBotMM; + } + void set(float value) + { + this->m_config->charWhitespaceBotMM = value; + } + } + + property int TemplateWidthPx { + int get() + { + return this->m_config->templateWidthPx; + } + void set(int value) + { + this->m_config->templateWidthPx = value; + } + } + + property int TemplateHeightPx { + int get() + { + return this->m_config->templateHeightPx; + } + void set(int value) + { + this->m_config->templateHeightPx = value; + } + } + + property int OcrImageWidthPx { + int get() + { + return this->m_config->ocrImageWidthPx; + } + void set(int value) + { + this->m_config->ocrImageWidthPx = value; + } + } + + property int OcrImageHeightPx { + int get() + { + return this->m_config->ocrImageHeightPx; + } + void set(int value) + { + this->m_config->ocrImageHeightPx = value; + } + } + + property int StateIdImageWidthPx { + int get() + { + return this->m_config->stateIdImageWidthPx; + } + void set(int value) + { + this->m_config->stateIdImageWidthPx = value; + } + } + + property int StateIdimageHeightPx { + int get() + { + return this->m_config->stateIdimageHeightPx; + } + void set(int value) + { + this->m_config->stateIdimageHeightPx = value; + } + } + + property float CharAnalysisMinPercent { + float get() + { + return this->m_config->charAnalysisMinPercent; + } + void set(float value) + { + this->m_config->charAnalysisMinPercent = value; + } + } + + property float CharAnalysisHeightRange { + float get() + { + return this->m_config->charAnalysisHeightRange; + } + void set(float value) + { + this->m_config->charAnalysisHeightRange = value; + } + } + + property float CharAnalysisHeightStepSize { + float get() + { + return this->m_config->charAnalysisHeightStepSize; + } + void set(float value) + { + this->m_config->charAnalysisHeightStepSize = value; + } + } + + property int CharAnalysisNumSteps { + int get() + { + return this->m_config->charAnalysisNumSteps; + } + void set(int value) + { + this->m_config->charAnalysisNumSteps = value; + } + } + + property float PlateLinesSensitivityVertical { + float get() + { + return this->m_config->plateLinesSensitivityVertical; + } + void set(float value) + { + this->m_config->plateLinesSensitivityVertical = value; + } + } + + property float PlateLinesSensitivityHorizontal { + float get() + { + return this->m_config->plateLinesSensitivityHorizontal; + } + void set(float value) + { + this->m_config->plateLinesSensitivityHorizontal = value; + } + } + + property int SegmentationMinBoxWidthPx { + int get() + { + return this->m_config->segmentationMinBoxWidthPx; + } + void set(int value) + { + this->m_config->segmentationMinBoxWidthPx = value; + } + } + + property float SegmentationMinCharHeightPercent { + float get() + { + return this->m_config->segmentationMinCharHeightPercent; + } + void set(float value) + { + this->m_config->segmentationMinCharHeightPercent = value; + } + } + + property float SegmentationMaxCharWidthvsAverage { + float get() + { + return this->m_config->segmentationMaxCharWidthvsAverage; + } + void set(float value) + { + this->m_config->segmentationMaxCharWidthvsAverage = value; + } + } + + property String^ OcrLanguage { + String^ get() + { + return AlprHelper::ToManagedString(this->m_config->ocrLanguage); + } + void set(String^ value) + { + if (String::IsNullOrWhiteSpace(value)) + { + this->m_config->prewarp = ""; + return; + } + this->m_config->ocrLanguage = marshal_as(value); + } + } + + property int OcrMinFontSize { + int get() + { + return this->m_config->ocrMinFontSize; + } + void set(int value) + { + this->m_config->ocrMinFontSize = value; + } + } + + property float PostProcessMinConfidence { + float get() + { + return this->m_config->postProcessMinConfidence; + } + void set(float value) + { + this->m_config->postProcessMinConfidence = value; + } + } + + property float PostProcessConfidenceSkipLevel { + float get() + { + return this->m_config->postProcessConfidenceSkipLevel; + } + void set(float value) + { + this->m_config->postProcessConfidenceSkipLevel = value; + } + } + + property unsigned int PostProcessMinCharacters { + unsigned int get() + { + return this->m_config->postProcessMinCharacters; + } + void set(unsigned int value) + { + this->m_config->postProcessMinCharacters = value; + } + } + + property unsigned int PostProcessMaxCharacters { + unsigned int get() + { + return this->m_config->postProcessMaxCharacters; + } + void set(unsigned int value) + { + this->m_config->postProcessMaxCharacters = value; + } + } + + property bool DebugGeneral { + bool get() + { + return this->m_config->debugGeneral; + } + void set(bool value) + { + this->m_config->debugGeneral = value; + } + } + + property bool DebugTiming { + bool get() + { + return this->m_config->debugTiming; + } + void set(bool value) + { + this->m_config->debugTiming = value; + } + } + + property bool DebugPrewarp { + bool get() + { + return this->m_config->debugPrewarp; + } + void set(bool value) + { + this->m_config->debugPrewarp = value; + } + } + + property bool DebugDetector { + bool get() + { + return this->m_config->debugDetector; + } + void set(bool value) + { + this->m_config->debugDetector = value; + } + } + + property bool DebugStateId { + bool get() + { + return this->m_config->debugStateId; + } + void set(bool value) + { + this->m_config->debugStateId = value; + } + } + + property bool DebugPlateLines { + bool get() + { + return this->m_config->debugPlateLines; + } + void set(bool value) + { + this->m_config->debugPlateLines = value; + } + } + + property bool DebugPlateCorners { + bool get() + { + return this->m_config->debugPlateCorners; + } + void set(bool value) + { + this->m_config->debugPlateCorners = value; + } + } + + property bool DebugCharSegmenter { + bool get() + { + return this->m_config->debugCharSegmenter; + } + void set(bool value) + { + this->m_config->debugCharSegmenter = value; + } + } + + property bool DebugCharAnalysis { + bool get() + { + return this->m_config->debugCharAnalysis; + } + void set(bool value) + { + this->m_config->debugCharAnalysis = value; + } + } + + property bool DebugColorFiler { + bool get() + { + return this->m_config->debugColorFiler; + } + void set(bool value) + { + this->m_config->debugColorFiler = value; + } + } + + property bool DebugOcr { + bool get() + { + return this->m_config->debugOcr; + } + void set(bool value) + { + this->m_config->debugOcr = value; + } + } + + property bool DebugPostProcess { + bool get() + { + return this->m_config->debugPostProcess; + } + void set(bool value) + { + this->m_config->debugPostProcess = value; + } + } + + property bool DebugShowImages { + bool get() + { + return this->m_config->debugShowImages; + } + void set(bool value) + { + this->m_config->debugShowImages = value; + } + } + + property bool DebugPauseOnFrame { + bool get() + { + return this->m_config->debugPauseOnFrame; + } + void set(bool value) + { + this->m_config->debugPauseOnFrame = value; + } + } + + void SetDebug(bool value) + { + this->m_config->setDebug(value); + } + + String^ GetKeypointsRuntimeDir() + { + return AlprHelper::ToManagedString(this->m_config->getKeypointsRuntimeDir()); + } + + String^ GetCascadeRuntimeDir() + { + return AlprHelper::ToManagedString(this->m_config->getCascadeRuntimeDir()); + } + + String^ GetPostProcessRuntimeDir() + { + return AlprHelper::ToManagedString(this->m_config->getPostProcessRuntimeDir()); + } + + String^ GetTessdataPrefix() + { + return AlprHelper::ToManagedString(this->m_config->getTessdataPrefix()); + } + + ~AlprConfigNet() + { + // void + } + + private: + Config *m_config; + }; +} \ No newline at end of file diff --git a/src/bindings/csharp/openalpr-net/helper-net.h b/src/bindings/csharp/openalpr-net/helper-net.h new file mode 100644 index 0000000..c0dd801 --- /dev/null +++ b/src/bindings/csharp/openalpr-net/helper-net.h @@ -0,0 +1,162 @@ +#pragma once + +#using +#include + +#include +#include +#include + +#include "alpr.h" +#include "opencv2/imgproc/imgproc.hpp" + +#include + +using namespace std; +using namespace alpr; + +using namespace msclr::interop; + +using namespace System; +using namespace System::Runtime::InteropServices; +using namespace System::Drawing; +using namespace System::Drawing::Imaging; +using namespace System::IO; +using namespace System::Collections::Generic; + +namespace openalprnet +{ + private ref class AlprHelper sealed + { + public: + + static std::vector ToVector(array^ src) + { + std::vector result(src->Length); + pin_ptr pin(&src[0]); + char *first(pin), *last(pin + src->Length); + std::copy(first, last, result.begin()); + return result; + } + + static std::vector ToVector(array^ src) + { + std::vector result(src->Length); + pin_ptr pin(&src[0]); + char* pch = reinterpret_cast(pin); + char *first(pch), *last(pch + src->Length); + std::copy(first, last, result.begin()); + return result; + } + + static Bitmap^ MatToBitmap(cv::Mat mat) + { + const int width = mat.size().width; + const int height = mat.size().height; + const int channels = mat.channels(); + const int totalSize = mat.total(); + void* data = reinterpret_cast(mat.data); + Bitmap ^bitmap; + + if (channels == 1) + { + bitmap = gcnew Bitmap(width, height, PixelFormat::Format8bppIndexed); + + ColorPalette ^palette = bitmap->Palette; + for (int i = 0; i < 256; i++) + { + palette->Entries[i] = Color::FromArgb(i, i, i); + } + + bitmap->Palette = palette; + } + else + { + bitmap = gcnew Bitmap(width, height, PixelFormat::Format24bppRgb); + } + + System::Drawing::Imaging::BitmapData ^bitmapData = bitmap->LockBits( + System::Drawing::Rectangle(0, 0, bitmap->Width, bitmap->Height), + System::Drawing::Imaging::ImageLockMode::ReadWrite, + bitmap->PixelFormat + ); + + char *src = reinterpret_cast(bitmapData->Scan0.ToPointer()); + pin_ptr pin(&src[0]); + + ::memcpy(pin, data, totalSize); + + bitmap->UnlockBits(bitmapData); + + return bitmap; + } + + static MemoryStream^ BitmapToMemoryStream(Bitmap^ bitmap, ImageFormat^ imageFormat) + { + MemoryStream^ ms = gcnew System::IO::MemoryStream(); + bitmap->Save(ms, imageFormat); + return ms; + } + + static std::vector MemoryStreamToVector(MemoryStream^ ms) + { + unsigned char* byteArray = ToCharPtr(ms->ToArray()); + std::vector result(byteArray, byteArray + ms->Length); + return result; + } + + static std::vector ToVector(List^ src) + { + std::vector result; + + for each(System::Drawing::Rectangle^ rect in src) + { + AlprRegionOfInterest roi(rect->X, rect->Y, rect->Width, rect->Height); + result.push_back(roi); + } + + return result; + } + + static unsigned char* ToCharPtr(array^ src) + { + //unsigned char* result = (unsigned char*) new unsigned char[src->Length]; + pin_ptr pin(&src[0]); + unsigned char* pc = pin; + return pc; + } + + static System::String^ ToManagedString(std::string s) + { + return gcnew String(s.c_str()); + } + + static std::string ToStlString(System::String^ s) + { + IntPtr ptr = Marshal::StringToHGlobalAnsi(s); + if (ptr != IntPtr::Zero) + { + std::string tmp(reinterpret_cast(static_cast(ptr))); + Marshal::FreeHGlobal(ptr); + return tmp; + } + return std::string(); + } + + static System::Drawing::Rectangle ToRectangle(cv::Rect rect) + { + return System::Drawing::Rectangle(rect.x, rect.y, rect.width, rect.height); + } + + static List^ ToRectangleList(std::vector srcRects) + { + List^ rects = gcnew List(); + for each(cv::Rect rect in srcRects) + { + rects->Add(ToRectangle(rect)); + } + return rects; + } + + }; +}; \ No newline at end of file diff --git a/src/bindings/csharp/openalpr-net/lock-net.h b/src/bindings/csharp/openalpr-net/lock-net.h new file mode 100644 index 0000000..56f05a3 --- /dev/null +++ b/src/bindings/csharp/openalpr-net/lock-net.h @@ -0,0 +1,18 @@ +#pragma once + +using namespace System::Threading; + +namespace openalprnet +{ + private ref class Lock { + Object^ m_pObject; + public: + Lock(Object ^ pObject) : m_pObject(pObject) { + Monitor::Enter(m_pObject); + } + ~Lock() { + Monitor::Exit(m_pObject); + } + }; +} + diff --git a/src/bindings/csharp/openalpr-net/motiondetector-net.cpp b/src/bindings/csharp/openalpr-net/motiondetector-net.cpp new file mode 100644 index 0000000..63721e9 --- /dev/null +++ b/src/bindings/csharp/openalpr-net/motiondetector-net.cpp @@ -0,0 +1,79 @@ +#include "stdafx.h" +#include "motiondetector-net.h" +#include "lock-net.h" +#include "bitmapmat-net.h" + +using namespace openalprnet; + +void AlprMotionDetectionNet::ResetMotionDetection(Bitmap^ bitmap) +{ + BitmapMat^ wrapper = gcnew BitmapMat(bitmap); + ResetMotionDetection(wrapper->Value); + delete wrapper; +} + +void AlprMotionDetectionNet::ResetMotionDetection(String^ filename) +{ + BitmapMat^ wrapper = gcnew BitmapMat(filename); + ResetMotionDetection(wrapper->Value); + delete wrapper; +} + +void AlprMotionDetectionNet::ResetMotionDetection(MemoryStream^ memoryStream) +{ + BitmapMat^ wrapper = gcnew BitmapMat(memoryStream); + ResetMotionDetection(wrapper->Value); + delete wrapper; +} + +void AlprMotionDetectionNet::ResetMotionDetection(array^ byteArray) +{ + BitmapMat^ wrapper = gcnew BitmapMat(byteArray); + ResetMotionDetection(wrapper->Value); + delete wrapper; +} + +System::Drawing::Rectangle AlprMotionDetectionNet::MotionDetect(Bitmap^ bitmap) +{ + BitmapMat^ wrapper = gcnew BitmapMat(bitmap); + System::Drawing::Rectangle motion = MotionDetect(wrapper->Value); + delete wrapper; + return motion; +} + +System::Drawing::Rectangle AlprMotionDetectionNet::MotionDetect(String^ filename) +{ + BitmapMat^ wrapper = gcnew BitmapMat(filename); + System::Drawing::Rectangle motion = MotionDetect(wrapper->Value); + delete wrapper; + return motion; +} + +System::Drawing::Rectangle AlprMotionDetectionNet::MotionDetect(MemoryStream^ memoryStream) +{ + BitmapMat^ wrapper = gcnew BitmapMat(memoryStream); + System::Drawing::Rectangle motion = MotionDetect(wrapper->Value); + delete wrapper; + return motion; +} + +System::Drawing::Rectangle AlprMotionDetectionNet::MotionDetect(array^ byteArray) +{ + BitmapMat^ wrapper = gcnew BitmapMat(byteArray); + System::Drawing::Rectangle motion = MotionDetect(wrapper->Value); + delete wrapper; + return motion; +} + +void AlprMotionDetectionNet::ResetMotionDetection(cv::Mat mat) +{ + Lock lock(this); + this->m_motionDetector->ResetMotionDetection(&mat); +} + +System::Drawing::Rectangle AlprMotionDetectionNet::MotionDetect(cv::Mat mat) +{ + Lock lock(this); + cv::Rect rect = this->m_motionDetector->MotionDetect(&mat); + return AlprHelper::ToRectangle(rect); +} \ No newline at end of file diff --git a/src/bindings/csharp/openalpr-net/motiondetector-net.h b/src/bindings/csharp/openalpr-net/motiondetector-net.h new file mode 100644 index 0000000..86c0909 --- /dev/null +++ b/src/bindings/csharp/openalpr-net/motiondetector-net.h @@ -0,0 +1,52 @@ +#pragma once + +#include "motiondetector.h" // alpr +#include "helper-net.h" + +using namespace alpr; + +namespace openalprnet +{ + public ref class AlprMotionDetectionNet : IDisposable { + public: + AlprMotionDetectionNet() : m_motionDetector(new MotionDetector()) + { + + } + + void AlprMotionDetectionNet::ResetMotionDetection(Bitmap^ bitmap); + void AlprMotionDetectionNet::ResetMotionDetection(String^ filename); + void AlprMotionDetectionNet::ResetMotionDetection(MemoryStream^ memoryStream); + void AlprMotionDetectionNet::ResetMotionDetection(array^ byteArray); + System::Drawing::Rectangle AlprMotionDetectionNet::MotionDetect(Bitmap^ bitmap); + System::Drawing::Rectangle AlprMotionDetectionNet::MotionDetect(String^ filename); + System::Drawing::Rectangle AlprMotionDetectionNet::MotionDetect(MemoryStream^ memoryStream); + System::Drawing::Rectangle AlprMotionDetectionNet::MotionDetect(array^ byteArray); + + private: + + ~AlprMotionDetectionNet() + { + if (this->m_disposed) + { + return; + } + + this->!AlprMotionDetectionNet(); + this->m_disposed = true; + } + + !AlprMotionDetectionNet() + { + delete m_motionDetector; + } + + private: + void ResetMotionDetection(cv::Mat mat); + System::Drawing::Rectangle MotionDetect(cv::Mat mat); + + private: + MotionDetector* m_motionDetector; + bool m_disposed; + }; +} \ No newline at end of file diff --git a/src/bindings/csharp/openalpr-net/openalpr-net.cpp b/src/bindings/csharp/openalpr-net/openalpr-net.cpp index 2849380..4988653 100644 --- a/src/bindings/csharp/openalpr-net/openalpr-net.cpp +++ b/src/bindings/csharp/openalpr-net/openalpr-net.cpp @@ -18,931 +18,34 @@ #include "stdafx.h" #include "openalpr-net.h" -#include "alpr.h" -#include "config.h" // alpr -#include "motiondetector.h" // alpr -#include -#include -#include -#using -//#include -#include - -#include "opencv2/highgui/highgui.hpp" -#include "opencv2/imgproc/imgproc.hpp" using namespace System; -using namespace msclr::interop; -using namespace System::Collections::Generic; -using namespace System::Runtime::InteropServices; -using namespace System::Drawing; -using namespace System::Drawing::Imaging; -using namespace System::IO; using namespace alpr; namespace openalprnet { - private ref class AlprHelper sealed - { - public: - - static std::vector ToVector(array^ src) - { - std::vector result(src->Length); - pin_ptr pin(&src[0]); - char *first(pin), *last(pin + src->Length); - std::copy(first, last, result.begin()); - return result; - } - - static cv::Mat BitmapToMat(Bitmap^ bitmap) - { - int channels = 0; - - switch(bitmap->PixelFormat) - { - case PixelFormat::Format8bppIndexed: - case PixelFormat::Format1bppIndexed: - channels = 1; - break; - case PixelFormat::Format24bppRgb: - channels = 3; - break; - case PixelFormat::Format32bppRgb: - case PixelFormat::Format32bppArgb: - case PixelFormat::Format32bppPArgb: - channels = 4; - break; - default: - throw gcnew NotImplementedException(); - } - - BitmapData^ bitmapData = bitmap->LockBits( - System::Drawing::Rectangle(0, 0, bitmap->Width, bitmap->Height), - ImageLockMode::ReadOnly, - bitmap->PixelFormat - ); - - cv::Mat dstMat(cv::Size(bitmap->Width, bitmap->Height), CV_8UC(channels), reinterpret_cast(bitmapData->Scan0.ToPointer())); - - bitmap->UnlockBits(bitmapData); - - return dstMat; - } - - static Bitmap^ MatToBitmap(cv::Mat mat) - { - const int width = mat.size().width; - const int height = mat.size().height; - const int channels = mat.channels(); - const int totalSize = mat.total(); - void* data = reinterpret_cast(mat.data); - Bitmap ^bitmap; - - if (channels == 1) - { - bitmap = gcnew Bitmap(width, height, PixelFormat::Format8bppIndexed); - - ColorPalette ^palette = bitmap->Palette; - for (int i = 0; i < 256; i++) - { - palette->Entries[i] = Color::FromArgb(i, i, i); - } - - bitmap->Palette = palette; - } - else - { - bitmap = gcnew Bitmap(width, height, PixelFormat::Format24bppRgb); - } - - System::Drawing::Imaging::BitmapData ^bitmapData = bitmap->LockBits( - System::Drawing::Rectangle(0, 0, bitmap->Width, bitmap->Height), - System::Drawing::Imaging::ImageLockMode::ReadWrite, - bitmap->PixelFormat - ); - - ::memcpy(bitmapData->Scan0.ToPointer(), data, totalSize); - - bitmap->UnlockBits(bitmapData); - - return bitmap; - } - - static MemoryStream^ BitmapToMemoryStream(Bitmap^ bitmap, ImageFormat^ imageFormat) - { - MemoryStream^ ms = gcnew System::IO::MemoryStream(); - bitmap->Save(ms, imageFormat); - return ms; - } - - static std::vector MemoryStreamToVector(MemoryStream^ ms) - { - unsigned char* byteArray = ToCharPtr(ms->ToArray()); - std::vector result(byteArray, byteArray + ms->Length); - return result; - } - - static std::vector ToVector(List^ src) - { - std::vector result; - - for each(System::Drawing::Rectangle^ rect in src) - { - AlprRegionOfInterest roi(rect->X, rect->Y, rect->Width, rect->Height); - result.push_back(roi); - } - - return result; - } - - static unsigned char* ToCharPtr(array^ src) - { - //unsigned char* result = (unsigned char*) new unsigned char[src->Length]; - pin_ptr pin(&src[0]); - unsigned char* pc = pin; - return pc; - } - - static System::String^ ToManagedString(std::string s) - { - return gcnew String(s.c_str()); - } - - static std::string ToStlString(System::String^ s) - { - IntPtr ptr = Marshal::StringToHGlobalAnsi(s); - if(ptr != IntPtr::Zero) - { - std::string tmp(reinterpret_cast(static_cast(ptr))); - Marshal::FreeHGlobal(ptr); - return tmp; - } - return std::string(); - } - - static System::Drawing::Rectangle ToRectangle(cv::Rect rect) - { - return System::Drawing::Rectangle(rect.x, rect.y, rect.width, rect.height); - } - - }; - - public enum class OpenCVMatType { - Unchanged = CV_LOAD_IMAGE_UNCHANGED, - Grayscale = CV_LOAD_IMAGE_GRAYSCALE, - Color = CV_LOAD_IMAGE_COLOR, - AnyDepth = CV_LOAD_IMAGE_ANYDEPTH, - AnyColor = CV_LOAD_IMAGE_ANYCOLOR - }; - - public ref class AlprMotionDetectionNet : IDisposable { - public: - AlprMotionDetectionNet() - { - m_motionDetector = new MotionDetector(); - } - - void ResetMotionDetection(Bitmap^ bitmap) - { - ResetMotionDetection(Mat(bitmap)); - } - - void ResetMotionDetection(String^ filename, OpenCVMatType matType) - { - return ResetMotionDetection(Mat(filename, matType)); - } - - System::Drawing::Rectangle MotionDetect(Bitmap^ bitmap) - { - return MotionDetect(Mat(bitmap)); - } - - System::Drawing::Rectangle MotionDetect(String^ filename, OpenCVMatType matType) - { - return MotionDetect(Mat(filename, matType)); - } - - private: - void ResetMotionDetection(cv::Mat mat) - { - this->m_motionDetector->ResetMotionDetection(&mat); - } - - System::Drawing::Rectangle MotionDetect(cv::Mat mat) - { - cv::Rect rect = this->m_motionDetector->MotionDetect(&mat); - return AlprHelper::ToRectangle(rect); - } - - cv::Mat Mat(String^ filename, OpenCVMatType matType) - { - cv::Mat mat = cv::imread(AlprHelper::ToStlString(filename), static_cast(matType)); - return mat; - } - - cv::Mat Mat(Bitmap^ bitmap) - { - cv::Mat mat = AlprHelper::BitmapToMat(bitmap); - return mat; - } - - private: - - ~AlprMotionDetectionNet() - { - if(this->m_Disposed) - { - return; - } - - this->!AlprMotionDetectionNet(); - this->m_Disposed = true; - } - - !AlprMotionDetectionNet() - { - delete m_motionDetector; - } - - private: - MotionDetector* m_motionDetector; - bool m_Disposed; - }; - - - public enum class AlprDetectorTypeNet : int { - DetectorLbpCpu = alpr::DETECTOR_LBP_CPU, - DetectorLbpGpu = alpr::DETECTOR_LBP_GPU, - DetectorLbpMorphCpu = alpr::DETECTOR_MORPH_CPU - }; - - public ref class AlprConfigNet sealed - { - public: - - AlprConfigNet(Config* config) : m_config (config) - { - - } - - property bool IsLoaded { - bool get() - { - return this->m_config->loaded; - } - } - - property AlprDetectorTypeNet Detector { - AlprDetectorTypeNet get() { - return static_cast(this->m_config->detector); - } - void set(AlprDetectorTypeNet value) - { - this->m_config->detector = static_cast(value); - } - } - - property float DetectionIterationIncrease { - float get() - { - return this->m_config->detection_iteration_increase; - } - void set(float value) - { - this->m_config->detection_iteration_increase = value; - } - } - - property float DetectionStrictness { - float get() - { - return this->m_config->detectionStrictness; - } - void set(float value) - { - this->m_config->detectionStrictness = value; - } - } - - property float MaxPlateWidthPercent { - float get() - { - return this->m_config->maxPlateWidthPercent; - } - void set(float value) - { - this->m_config->maxPlateWidthPercent = value; - } - } - - property float MaxPlateHeightPercent { - float get() - { - return this->m_config->maxPlateHeightPercent; - } - void set(float value) - { - this->m_config->maxPlateHeightPercent = value; - } - } - - property int MaxDetectionInputWidth { - int get() - { - return this->m_config->maxDetectionInputWidth; - } - void set(int value) - { - this->m_config->maxDetectionInputWidth = value; - } - } - - property int MaxDetectionInputHeight { - int get() - { - return this->m_config->maxDetectionInputHeight; - } - void set(int value) - { - this->m_config->maxDetectionInputHeight = value; - } - } - - property bool SkipDetection { - bool get() - { - return this->m_config->skipDetection; - } - void set(bool value) - { - this->m_config->skipDetection = true; - } - } - - property String^ PreWarp { - String^ get() - { - return AlprHelper::ToManagedString(this->m_config->prewarp); - } - void set(String^ value) - { - this->m_config->prewarp = marshal_as(value); - } - } - - property int MaxPlateAngleDegrees { - int get() - { - return this->m_config->maxPlateAngleDegrees; - } - void set(int value) - { - this->m_config->maxPlateAngleDegrees = value; - } - } - - property float MinPlateSizeWidthPx { - float get() - { - return this->m_config->minPlateSizeWidthPx; - } - void set(float value) - { - this->m_config->minPlateSizeWidthPx = value; - } - } - - property float minPlateSizeHeightPx { - float get() - { - return this->m_config->minPlateSizeHeightPx; - } - void set(float value) - { - this->m_config->minPlateSizeHeightPx = value; - } - } - - property bool Multiline { - bool get() - { - return this->m_config->multiline; - } - void set(bool value) - { - this->m_config->multiline = value; - } - } - - property float PlateWidthMM { - float get() - { - return this->m_config->plateWidthMM; - } - void set(float value) - { - this->m_config->plateWidthMM = value; - } - } - - property float PlateHeightMM { - float get() - { - return this->m_config->plateHeightMM; - } - void set(float value) - { - this->m_config->plateHeightMM = value; - } - } - - property float CharHeightMM { - float get() - { - return this->m_config->charHeightMM; - } - void set(float value) - { - this->m_config->charHeightMM = value; - } - } - - property float CharWidthMM { - float get() - { - return this->m_config->charWidthMM; - } - void set(float value) - { - this->m_config->charWidthMM = value; - } - } - - property float CharWhitespaceTopMM { - float get() - { - return this->m_config->charWhitespaceTopMM; - } - void set(float value) - { - this->m_config->charWhitespaceTopMM = value; - } - } - - property float CharWhitespaceBotMM { - float get() - { - return this->m_config->charWhitespaceBotMM; - } - void set(float value) - { - this->m_config->charWhitespaceBotMM = value; - } - } - - property int TemplateWidthPx { - int get() - { - return this->m_config->templateWidthPx; - } - void set(int value) - { - this->m_config->templateWidthPx = value; - } - } - - property int TemplateHeightPx { - int get() - { - return this->m_config->templateHeightPx; - } - void set(int value) - { - this->m_config->templateHeightPx = value; - } - } - - property int OcrImageWidthPx { - int get() - { - return this->m_config->ocrImageWidthPx; - } - void set(int value) - { - this->m_config->ocrImageWidthPx = value; - } - } - - property int OcrImageHeightPx { - int get() - { - return this->m_config->ocrImageHeightPx; - } - void set(int value) - { - this->m_config->ocrImageHeightPx = value; - } - } - - property int StateIdImageWidthPx { - int get() - { - return this->m_config->stateIdImageWidthPx; - } - void set(int value) - { - this->m_config->stateIdImageWidthPx = value; - } - } - - property int StateIdimageHeightPx { - int get() - { - return this->m_config->stateIdimageHeightPx; - } - void set(int value) - { - this->m_config->stateIdimageHeightPx = value; - } - } - - property float CharAnalysisMinPercent { - float get() - { - return this->m_config->charAnalysisMinPercent; - } - void set(float value) - { - this->m_config->charAnalysisMinPercent = value; - } - } - - property float CharAnalysisHeightRange { - float get() - { - return this->m_config->charAnalysisHeightRange; - } - void set(float value) - { - this->m_config->charAnalysisHeightRange = value; - } - } - - property float CharAnalysisHeightStepSize { - float get() - { - return this->m_config->charAnalysisHeightStepSize; - } - void set(float value) - { - this->m_config->charAnalysisHeightStepSize = value; - } - } - - property int CharAnalysisNumSteps { - int get() - { - return this->m_config->charAnalysisNumSteps; - } - void set(int value) - { - this->m_config->charAnalysisNumSteps = value; - } - } - - property float PlateLinesSensitivityVertical { - float get() - { - return this->m_config->plateLinesSensitivityVertical; - } - void set(float value) - { - this->m_config->plateLinesSensitivityVertical = value; - } - } - - property float PlateLinesSensitivityHorizontal { - float get() - { - return this->m_config->plateLinesSensitivityHorizontal; - } - void set(float value) - { - this->m_config->plateLinesSensitivityHorizontal = value; - } - } - - property int SegmentationMinBoxWidthPx { - int get() - { - return this->m_config->segmentationMinBoxWidthPx; - } - void set(int value) - { - this->m_config->segmentationMinBoxWidthPx = value; - } - } - - property float SegmentationMinCharHeightPercent { - float get() - { - return this->m_config->segmentationMinCharHeightPercent; - } - void set(float value) - { - this->m_config->segmentationMinCharHeightPercent = value; - } - } - - property float SegmentationMaxCharWidthvsAverage { - float get() - { - return this->m_config->segmentationMaxCharWidthvsAverage; - } - void set(float value) - { - this->m_config->segmentationMaxCharWidthvsAverage = value; - } - } - - property String^ OcrLanguage { - String^ get() - { - return AlprHelper::ToManagedString(this->m_config->ocrLanguage); - } - void set(String^ value) - { - this->m_config->ocrLanguage = marshal_as(value); - } - } - - property int OcrMinFontSize { - int get() - { - return this->m_config->ocrMinFontSize; - } - void set(int value) - { - this->m_config->ocrMinFontSize = value; - } - } - - property float PostProcessMinConfidence { - float get() - { - return this->m_config->postProcessMinConfidence; - } - void set(float value) - { - this->m_config->postProcessMinConfidence = value; - } - } - - property float PostProcessConfidenceSkipLevel { - float get() - { - return this->m_config->postProcessConfidenceSkipLevel; - } - void set(float value) - { - this->m_config->postProcessConfidenceSkipLevel = value; - } - } - - property unsigned int PostProcessMinCharacters { - unsigned int get() - { - return this->m_config->postProcessMinCharacters; - } - void set(unsigned int value) - { - this->m_config->postProcessMinCharacters = value; - } - } - - property unsigned int PostProcessMaxCharacters { - unsigned int get() - { - return this->m_config->postProcessMaxCharacters; - } - void set(unsigned int value) - { - this->m_config->postProcessMaxCharacters = value; - } - } - - property bool DebugGeneral { - bool get() - { - return this->m_config->debugGeneral; - } - void set(bool value) - { - this->m_config->debugGeneral = value; - } - } - - property bool DebugTiming { - bool get() - { - return this->m_config->debugTiming; - } - void set(bool value) - { - this->m_config->debugTiming = value; - } - } - - property bool DebugPrewarp { - bool get() - { - return this->m_config->debugPrewarp; - } - void set(bool value) - { - this->m_config->debugPrewarp = value; - } - } - - property bool DebugDetector { - bool get() - { - return this->m_config->debugDetector; - } - void set(bool value) - { - this->m_config->debugDetector = value; - } - } - - property bool DebugStateId { - bool get() - { - return this->m_config->debugStateId; - } - void set(bool value) - { - this->m_config->debugStateId = value; - } - } - - property bool DebugPlateLines { - bool get() - { - return this->m_config->debugPlateLines; - } - void set(bool value) - { - this->m_config->debugPlateLines = value; - } - } - - property bool DebugPlateCorners { - bool get() - { - return this->m_config->debugPlateCorners; - } - void set(bool value) - { - this->m_config->debugPlateCorners = value; - } - } - - property bool DebugCharSegmenter { - bool get() - { - return this->m_config->debugCharSegmenter; - } - void set(bool value) - { - this->m_config->debugCharSegmenter = value; - } - } - - property bool DebugCharAnalysis { - bool get() - { - return this->m_config->debugCharAnalysis; - } - void set(bool value) - { - this->m_config->debugCharAnalysis = value; - } - } - - property bool DebugColorFiler { - bool get() - { - return this->m_config->debugColorFiler; - } - void set(bool value) - { - this->m_config->debugColorFiler = value; - } - } - - property bool DebugOcr { - bool get() - { - return this->m_config->debugOcr; - } - void set(bool value) - { - this->m_config->debugOcr = value; - } - } - - property bool DebugPostProcess { - bool get() - { - return this->m_config->debugPostProcess; - } - void set(bool value) - { - this->m_config->debugPostProcess = value; - } - } - - property bool DebugShowImages { - bool get() - { - return this->m_config->debugShowImages; - } - void set(bool value) - { - this->m_config->debugShowImages = value; - } - } - - property bool DebugPauseOnFrame { - bool get() - { - return this->m_config->debugPauseOnFrame; - } - void set(bool value) - { - this->m_config->debugPauseOnFrame = value; - } - } - - void SetDebug(bool value) - { - this->m_config->setDebug(value); - } - - String^ GetKeypointsRuntimeDir() - { - return AlprHelper::ToManagedString(this->m_config->getKeypointsRuntimeDir()); - } - - String^ GetCascadeRuntimeDir() - { - return AlprHelper::ToManagedString(this->m_config->getCascadeRuntimeDir()); - } - - String^ GetPostProcessRuntimeDir() - { - return AlprHelper::ToManagedString(this->m_config->getPostProcessRuntimeDir()); - } - - String^ GetTessdataPrefix() - { - return AlprHelper::ToManagedString(this->m_config->getTessdataPrefix()); - } - - ~AlprConfigNet() - { - // void - } - - private: - Config *m_config; - }; - public ref class AlprPlateNet sealed { public: AlprPlateNet(AlprPlate plate){ - //_characters = marshal_as(plate.characters); m_characters = AlprHelper::ToManagedString(plate.characters); m_overall_confidence=plate.overall_confidence; m_matches_template=plate.matches_template; } - property System::String^ characters { + property System::String^ Characters { System::String^ get() { return m_characters; } } - property float overall_confidence { + property float OverallConfidence { float get() { return m_overall_confidence; } } - property bool matches_template { + property bool MatchesTemplate { bool get() { return m_matches_template; } @@ -978,49 +81,49 @@ namespace openalprnet { } } - property int requested_topn { + property int RequestedTopN { int get() { return m_requested_topn; } } - property int regionConfidence { + property int RegionConfidence { int get() { return m_regionConfidence; } } - property int plate_index { + property int PlateIndex { int get() { return m_plate_index; } } - property System::String^ region { + property System::String^ Region { System::String^ get() { return m_region; } } - property AlprPlateNet^ bestPlate { + property AlprPlateNet^ BestPlate { AlprPlateNet^ get() { return m_bestPlate; } } - property List^ plate_points { + property List^ PlatePoints { List^ get() { return m_plate_points; } } - property List^ topNPlates { + property List^ TopNPlates { List^ get() { return m_topNPlates; } } - property float processing_time_ms { + property float ProcessingTimeMs { float get() { return m_processing_time_ms; } @@ -1069,43 +172,43 @@ namespace openalprnet { m_json = AlprHelper::ToManagedString(json); } - property long epoch_time { + property long EpochTime { long get() { return m_epoch_time; } } - property int img_width { + property int ImageWidth { int get() { return m_img_width; } } - property int img_height { + property int ImageHeight { int get() { return m_img_height; } } - property float total_processing_time_ms { + property float TotalProcessingTimeMs { float get() { return m_total_processing_time_ms; } } - property List^ regionsOfInterest { + property List^ RegionsOfInterest { List^ get() { return m_regionsOfInterest; } } - property List^ plates { + property List^ Plates { List^ get() { return m_plates; } } - property System::String^ json { + property System::String^ Json { System::String^ get() { return m_json; } @@ -1175,13 +278,13 @@ namespace openalprnet { } ~AlprNet() { - if(this->m_Disposed) + if(this->m_disposed) { return; } this->!AlprNet(); - this->m_Disposed = true; + this->m_disposed = true; } property AlprConfigNet^ Configuration { @@ -1257,7 +360,7 @@ namespace openalprnet { /// /// Recognize from an image on disk /// - AlprResultsNet^ recognize(System::String^ filepath) { + AlprResultsNet^ Recognize(System::String^ filepath) { AlprResults results = m_Impl->recognize(marshal_as(filepath)); return gcnew AlprResultsNet(results); } @@ -1265,7 +368,7 @@ namespace openalprnet { /// /// Recognize from an image on disk /// - AlprResultsNet^ recognize(System::String^ filepath, List^ regionsOfInterest) { + AlprResultsNet^ Recognize(System::String^ filepath, List^ regionsOfInterest) { cv::Mat frame = cv::imread( marshal_as(filepath) ); std::vector rois = AlprHelper::ToVector(regionsOfInterest); AlprResults results = m_Impl->recognize(frame.data, frame.elemSize(), frame.cols, frame.rows, rois ); @@ -1275,29 +378,36 @@ namespace openalprnet { /// /// Recognize from a bitmap /// - AlprResultsNet^ recognize(Bitmap^ bitmap, List^ regionsOfInterest) + AlprResultsNet^ Recognize(Bitmap^ bitmap) { - cv::Mat frame = AlprHelper::BitmapToMat(bitmap); - std::vector rois = AlprHelper::ToVector(regionsOfInterest); - AlprResults results = m_Impl->recognize(frame.data, frame.elemSize(), frame.cols, frame.rows, rois); - return gcnew AlprResultsNet(results); + return Recognize(bitmap, gcnew List()); } /// /// Recognize from a bitmap /// - AlprResultsNet^ recognize(Bitmap^ bitmap) + AlprResultsNet^ Recognize(Bitmap^ bitmap, List^ regionsOfInterest) { - cv::Mat frame = AlprHelper::BitmapToMat(bitmap); - std::vector rois; + BitmapMat^ wrapper = gcnew BitmapMat(bitmap); + cv::Mat frame = wrapper->Value; + std::vector rois = AlprHelper::ToVector(regionsOfInterest); AlprResults results = m_Impl->recognize(frame.data, frame.elemSize(), frame.cols, frame.rows, rois); + delete wrapper; return gcnew AlprResultsNet(results); } /// /// Recognize from MemoryStream representing an encoded image (e.g., BMP, PNG, JPG, GIF etc). /// - AlprResultsNet^ recognize(MemoryStream^ memoryStream) + AlprResultsNet^ Recognize(MemoryStream^ memoryStream) + { + return Recognize(memoryStream, gcnew List()); + } + + /// + /// Recognize from MemoryStream representing an encoded image (e.g., BMP, PNG, JPG, GIF etc). + /// + AlprResultsNet^ Recognize(MemoryStream^ memoryStream, List^ regionsOfInterest) { std::vector p = AlprHelper::MemoryStreamToVector(memoryStream); AlprResults results = m_Impl->recognize(p); @@ -1308,7 +418,15 @@ namespace openalprnet { /// Recognize from byte data representing an encoded image (e.g., BMP, PNG, JPG, GIF etc). /// /// Bytes representing image data - AlprResultsNet^ recognize(cli::array^ imageBuffer) { + AlprResultsNet^ Recognize(cli::array^ imageBuffer) { + return Recognize(imageBuffer, gcnew List()); + } + + /// + /// Recognize from byte data representing an encoded image (e.g., BMP, PNG, JPG, GIF etc). + /// + /// Bytes representing image data + AlprResultsNet^ Recognize(cli::array^ imageBuffer, List^ regionsOfInterest) { std::vector p = AlprHelper::ToVector(imageBuffer); AlprResults results = m_Impl->recognize(p); return gcnew AlprResultsNet(results); @@ -1317,19 +435,26 @@ namespace openalprnet { /// /// Recognize from raw pixel data /// - AlprResultsNet^ recognize(cli::array^ pixelData, int bytesPerPixel, int imgWidth, int imgHeight, List^ regionsOfInterest) { - unsigned char* p = AlprHelper::ToCharPtr(pixelData); + AlprResultsNet^ Recognize(cli::array^ imageBuffer, int bytesPerPixel, int imgWidth, int imgHeight) { + return Recognize(imageBuffer, bytesPerPixel, imgWidth, imgHeight, gcnew List()); + } + + /// + /// Recognize from raw pixel data + /// + AlprResultsNet^ Recognize(cli::array^ imageBuffer, int bytesPerPixel, int imgWidth, int imgHeight, List^ regionsOfInterest) { + unsigned char* p = AlprHelper::ToCharPtr(imageBuffer); std::vector rois = AlprHelper::ToVector(regionsOfInterest); AlprResults results = m_Impl->recognize(p, bytesPerPixel, imgWidth, imgHeight, rois); free(p); // ?? memory leak? return gcnew AlprResultsNet(results); } - bool isLoaded() { + bool IsLoaded() { return m_Impl->isLoaded(); } - static System::String^ getVersion() { + static System::String^ GetVersion() { return AlprHelper::ToManagedString(Alpr::getVersion()); } @@ -1346,6 +471,6 @@ namespace openalprnet { int m_topN; bool m_detectRegion; System::String^ m_defaultRegion; - bool m_Disposed; + bool m_disposed; }; } diff --git a/src/bindings/csharp/openalpr-net/openalpr-net.h b/src/bindings/csharp/openalpr-net/openalpr-net.h index e56ad27..52ec33e 100644 --- a/src/bindings/csharp/openalpr-net/openalpr-net.h +++ b/src/bindings/csharp/openalpr-net/openalpr-net.h @@ -1,8 +1,21 @@ -// openalpr-net.h - #pragma once -//using namespace System; +#include "alpr.h" + +#include +#include +#include + +#include "opencv2/highgui/highgui.hpp" +#include "opencv2/imgproc/imgproc.hpp" + +#using +#include + +#include "helper-net.h" +#include "bitmapmat-net.h" +#include "motiondetector-net.h" +#include "config-net.h" namespace openalprnet { diff --git a/src/bindings/csharp/openalpr-net/openalpr-net.vcxproj b/src/bindings/csharp/openalpr-net/openalpr-net.vcxproj index 690aacc..2fe36e2 100644 --- a/src/bindings/csharp/openalpr-net/openalpr-net.vcxproj +++ b/src/bindings/csharp/openalpr-net/openalpr-net.vcxproj @@ -1,4 +1,4 @@ - + @@ -23,20 +23,22 @@ v4.0 ManagedCProj openalprnet - 2.1.0 - v120 - ..\..\..\..\windows - None - $(OpenALPRWindowsDir)\build\dist\$(OpenALPRVersion)\$(PlatformToolset)\$(Configuration)\$(Platform) - $(OpenALPRWindowsDir)\build\dist\$(OpenALPRVersion)\$(PlatformToolset)\$(Configuration)\$(Platform)_CUDA_Fermi - $(OpenALPRWindowsDir)\build\dist\$(OpenALPRVersion)\$(PlatformToolset)\$(Configuration)\$(Platform)_CUDA_Kepler - 248 - 303 - 170 - d - - -debug - + 2.1.0 + v120 + ..\..\..\..\windows + None + $(OpenALPRWindowsDir)\build\dist\$(OpenALPRVersion)\$(PlatformToolset)\$(Configuration)\$(Platform) + $(OpenALPRWindowsDir)\build\dist\$(OpenALPRVersion)\$(PlatformToolset)\$(Configuration)\$(Platform)_CUDA_Fermi + $(OpenALPRWindowsDir)\build\dist\$(OpenALPRVersion)\$(PlatformToolset)\$(Configuration)\$(Platform)_CUDA_Kepler + 248 + 303 + 170 + d + + + -debug + + @@ -150,12 +152,20 @@ + + + + + + + + Create diff --git a/src/bindings/csharp/openalpr-net/openalpr-net.vcxproj.filters b/src/bindings/csharp/openalpr-net/openalpr-net.vcxproj.filters index 221dbe4..22e7904 100644 --- a/src/bindings/csharp/openalpr-net/openalpr-net.vcxproj.filters +++ b/src/bindings/csharp/openalpr-net/openalpr-net.vcxproj.filters @@ -24,6 +24,24 @@ Header Files + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + @@ -35,6 +53,12 @@ Source Files + + Source Files + + + Source Files + diff --git a/src/bindings/csharp/openalpr-net/types-net.h b/src/bindings/csharp/openalpr-net/types-net.h new file mode 100644 index 0000000..002d67c --- /dev/null +++ b/src/bindings/csharp/openalpr-net/types-net.h @@ -0,0 +1,18 @@ +#pragma once + +#include "alpr.h" // alpr +#include "config.h" // alpr + +using namespace alpr; + +namespace openalprnet +{ + namespace types + { + public enum class AlprDetectorTypeNet : int { + DetectorLbpCpu = alpr::DETECTOR_LBP_CPU, + DetectorLbpGpu = alpr::DETECTOR_LBP_GPU, + DetectorLbpMorphCpu = alpr::DETECTOR_MORPH_CPU + }; + } +} \ No newline at end of file diff --git a/src/bindings/csharp/openalprnet-cli/Program.cs b/src/bindings/csharp/openalprnet-cli/Program.cs index fee8e32..556d4d3 100644 --- a/src/bindings/csharp/openalprnet-cli/Program.cs +++ b/src/bindings/csharp/openalprnet-cli/Program.cs @@ -66,11 +66,11 @@ namespace openalprnet_cli val => { if (val.Any()) filename = val.First().Trim(); }) ); - Console.WriteLine("OpenAlpr Version: {0}", AlprNet.getVersion()); + Console.WriteLine("OpenAlpr Version: {0}", AlprNet.GetVersion()); var config = Path.Combine(AssemblyDirectory, "openalpr.conf"); var runtime_data = Path.Combine(AssemblyDirectory, "runtime_data"); var alpr = new AlprNet(region, config, runtime_data); - if (!alpr.isLoaded()) + if (!alpr.IsLoaded()) { Console.WriteLine("OpenAlpr failed to load!"); return; @@ -110,8 +110,7 @@ namespace openalprnet_cli private static void PerformAlpr(AlprNet alpr, byte[] buffer, bool benchmark, bool writeJson) { var sw = Stopwatch.StartNew(); - sbyte[] signedBuffer = (sbyte[])(Array)buffer; - var results = alpr.recognize(signedBuffer); + var results = alpr.Recognize(buffer); sw.Stop(); if (benchmark) { @@ -125,14 +124,14 @@ namespace openalprnet_cli else { var i = 0; - foreach (var result in results.plates) + foreach (var result in results.Plates) { - Console.WriteLine("Plate {0}: {1} result(s)", i++, result.topNPlates.Count); - Console.WriteLine(" Processing Time: {0} msec(s)", result.processing_time_ms); - foreach (var plate in result.topNPlates) + Console.WriteLine("Plate {0}: {1} result(s)", i++, result.TopNPlates.Count); + Console.WriteLine(" Processing Time: {0} msec(s)", result.ProcessingTimeMs); + foreach (var plate in result.TopNPlates) { - Console.WriteLine(" - {0}\t Confidence: {1}\tMatches Template: {2}", plate.characters, - plate.overall_confidence, plate.matches_template); + Console.WriteLine(" - {0}\t Confidence: {1}\tMatches Template: {2}", plate.Characters, + plate.OverallConfidence, plate.MatchesTemplate); } } } diff --git a/src/bindings/csharp/openalprnet-windemo/Form1.cs b/src/bindings/csharp/openalprnet-windemo/Form1.cs index 98587c8..e2081c4 100644 --- a/src/bindings/csharp/openalprnet-windemo/Form1.cs +++ b/src/bindings/csharp/openalprnet-windemo/Form1.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2015 OpenALPR Technology, Inc. * * This file is part of OpenALPR. @@ -22,6 +22,7 @@ using System.Drawing; using System.IO; using System.Linq; using System.Reflection; +using System.Threading.Tasks; using System.Windows.Forms; using openalprnet; @@ -135,7 +136,7 @@ namespace openalprnet_windemo String runtime_data_dir = Path.Combine(AssemblyDirectory, "runtime_data"); using (var alpr = new AlprNet(region, config_file, runtime_data_dir)) { - if (!alpr.isLoaded()) + if (!alpr.IsLoaded()) { lbxPlates.Items.Add("Error initializing OpenALPR"); return; @@ -143,24 +144,24 @@ namespace openalprnet_windemo picOriginal.ImageLocation = fileName; picOriginal.Load(); - var results = alpr.recognize(fileName); + var results = alpr.Recognize(fileName); - var images = new List(results.plates.Count()); + var images = new List(results.Plates.Count()); var i = 1; - foreach (var result in results.plates) + foreach (var result in results.Plates) { - var rect = boundingRectangle(result.plate_points); + var rect = boundingRectangle(result.PlatePoints); var img = Image.FromFile(fileName); var cropped = cropImage(img, rect); images.Add(cropped); lbxPlates.Items.Add("\t\t-- Plate #" + i++ + " --"); - foreach (var plate in result.topNPlates) + foreach (var plate in result.TopNPlates) { lbxPlates.Items.Add(string.Format(@"{0} {1}% {2}", - plate.characters.PadRight(12), - plate.overall_confidence.ToString("N1").PadLeft(8), - plate.matches_template.ToString().PadLeft(8))); + plate.Characters.PadRight(12), + plate.OverallConfidence.ToString("N1").PadLeft(8), + plate.MatchesTemplate.ToString().PadLeft(8))); } }