public LPREngine(APPLICATION_DATA appData) { try { m_AppData = appData; m_AppData.AddOnClosing(Stop, APPLICATION_DATA.CLOSE_ORDER.MIDDLE); m_Log = (ErrorLog)m_AppData.Logger; m_FrameGen = (FrameGenerator)m_AppData.FrameGenerator; m_LPRProcessQ = new ThreadSafeQueue<FRAME>(m_LPRProcessQueSize, "QueueOverruns_LPR_LPRProcessQ", m_AppData); // this queue hold frames that come from the framegenerator and need to be processed by LPR m_AppData.LPRGettingBehind = false; m_LPRFinalPlateGroupOutputQ = new ThreadSafeQueue<FRAME>(60, "QueueOverruns_LPR_LPRFinalPlateGroupOutputQ", m_AppData); // filtered plate readings, grouped into similar readings, redundant readings removed m_LPRPerFrameReadingQ = new ThreadSafeQueue<FRAME>(60, "QueueOverruns_LPR_LPRPerFrameReadingQ", m_AppData); // instantaneous output from LPR for each fram processed m_StoredFrameData = new ThreadSafeHashableQueue(30 * 60);// 60 seconds of frames at 30fps m_LPRFuntions = new LPROCR_Lib(); unsafe { // the plate group processor accumulates per-frame plate readings and consolidates them into a single plate reading where appropriate m_LPRFuntions.RegisterPlateGroupCB(OnNewPlateGroupReady); } int maxW = 0, minW = 0, maxH = 0, minH = 0; m_LPRFuntions.GetMinMaxPlateSize(ref minW, ref maxW,ref minH, ref maxH); m_AppData.MAX_PLATE_HEIGHT = maxH; m_AppData.MIN_PLATE_HEIGHT = minH; m_AppData.MAX_PLATE_WIDTH = maxW; m_AppData.MIN_PLATE_WIDTH = minW; m_processOptions = new LPROCR_Lib.LPR_PROCESS_OPTIONS(); m_processOptions.roll = 1; m_processOptions.rotation = 1; // register with the frame grabber to get new bitmaps from the channel sources as they come in m_ConsumerID = m_FrameGen.GetNewConsumerID(); // m_NumSourceChannels = m_FrameGen.GetNumberOfConfiguredChannels(); m_NumSourceChannels = (m_AppData.RunninAsService) ? m_AppData.MAX_PHYSICAL_CHANNELS : m_AppData.MAX_VIRTUAL_CHANNELS; m_LPREngineProcessThread = new Thread(LPREngineProcessLoop); PushLPRResultsThread = new Thread(PushLPRResultsLoop); } catch (Exception ex) { m_Log.Trace(ex, ErrorLog.LOG_TYPE.FATAL); } }
void ProcessImage(Bitmap bmp) { try { listBoxRejectLog.Items.Clear(); if (bmp == null) return; // get the luminance array int[,] lum = GetLuminanceArray(bmp); int error = 0; LPROCR_Lib.LPR_PROCESS_OPTIONS processOptions; processOptions = new LPROCR_Lib.LPR_PROCESS_OPTIONS(); processOptions.EnableAutoRotationRoll = 1; processOptions.EnableRotationRoll = 1; int diagEnabled = 0; if (m_AppData.LPRDiagEnabled) diagEnabled = 1; // read the image int plateCount = m_LPREngine.m_LPRFuntions.ReadThisImage(lum, (int)diagEnabled, ref processOptions, ref error); // extract the plate images and detected strings PLATE_INFO[] plateInfos = new PLATE_INFO[plateCount]; // get the diag images (not plate, but full images) if (m_AppData.LPRDiagEnabled) { ClearDiagDisplayTable(); byte[,] r = new byte[bmp.Width, bmp.Height]; byte[,] g = new byte[bmp.Width, bmp.Height]; byte[,] b = new byte[bmp.Width, bmp.Height]; error = 0; m_LPREngine.m_LPRFuntions.diagsGetImage(1, r, g, b, ref error);// get the full resolution image Bitmap imageBmp = new Bitmap(bmp.Width, bmp.Height); putPixelsIntoBmp(imageBmp, r, g, b); pictureBoxDiag1.Image = imageBmp; int w = 0; int h = 0; w = bmp.Width; h = bmp.Height; // m_LPREngine.m_LPRFuntions.GetSubImageSize(ref w, ref h); Bitmap subscalledBmp = new Bitmap(w, h); r = new byte[w, h]; g = new byte[w, h]; b = new byte[w, h]; //m_LPREngine.m_LPRFuntions.diagsGetImage(0, r, g, b, ref error);// get the subscalled image int[,] edge = new int[w, h]; // m_LPREngine.m_LPRFuntions.getEdgeMapSub(edge, ref error); m_LPREngine.m_LPRFuntions.getEdgeMapFullRes(edge, ref error); ColorizeEdgeMap(edge, r, g, b); putPixelsIntoBmp(subscalledBmp, r, g, b); pictureBoxDiag2.Image = subscalledBmp; // get the intergal image r = new byte[bmp.Width, bmp.Height]; g = new byte[bmp.Width, bmp.Height]; b = new byte[bmp.Width, bmp.Height]; imageBmp = new Bitmap(bmp.Width, bmp.Height); m_LPREngine.m_LPRFuntions.GetIntegralImage(r, g, b); putPixelsIntoBmp(imageBmp, r, g, b); pictureBoxDiag3.Image = imageBmp; } // get the plates for (int p = 0; p < plateCount; p++) { float score = 0; plateInfos[p] = new PLATE_INFO(); plateInfos[p].sourceImage = bmp; plateInfos[p].sourceFileName = jpegsToProcess[m_CurrentIndex]; // get the string from the plate plateInfos[p].plateNumber = m_LPREngine.m_LPRFuntions.GetPlateString(p, ref score); // exract a bitmap of the plate itself int pw = 0; int ph = 0; m_LPREngine.m_LPRFuntions.GetPlateImageSize(p, ref pw, ref ph, false); plateInfos[p].plateImage = new Bitmap(pw, ph); m_LPREngine.m_LPRFuntions.GetPlateImage(p, plateInfos[p].plateImage); plateInfos[p].numChars = plateInfos[p].plateNumber.Length; plateInfos[p].charImages = new Bitmap[plateInfos[p].numChars]; for (int c = 0; c < plateInfos[p].numChars; c++) { plateInfos[p].charImages[c] = null; try { m_LPREngine.m_LPRFuntions.GetCharImage(p, c, out plateInfos[p].charImages[c], false); } catch (Exception ex) { m_Log.Trace(ex, ErrorLog.LOG_TYPE.INFORMATIONAL); } } }// end for each plate found if (plateCount == 0) { // perhaps we really screwed up and did not find a plate when one is really there, // allow the user to manually add the plate numbers plateInfos = new PLATE_INFO[1]; plateInfos[0] = new PLATE_INFO(); plateInfos[0].sourceImage = bmp; plateInfos[0].sourceFileName = jpegsToProcess[m_CurrentIndex]; // get the string from the plate plateInfos[0].plateNumber = "0"; plateInfos[0].plateImage = bmp;// use the main picture to fill the space plateInfos[0].numChars = 0; plateCount = 1; } // create a display ClearDisplayTable(); for (int p = 0; p < plateCount; p++) { AddPlateTabToEditPage(plateInfos[p]); } m_CurrentImageResult = plateInfos; m_HaveNewDataToStore = true; if (m_AppData.LPRDiagEnabled) { try { // get the reject log string log = m_LPREngine.m_LPRFuntions.GetRejectLog(); string[] sp = log.Split(','); foreach (string s in sp) listBoxRejectLog.Items.Add(s); // get the plate diagnostic images, and run a diagnostic histo on original plate images int count = m_LPREngine.m_LPRFuntions.GetNumCandidatePlates(); for (int i = 0; i < count; i++) { int w = 0; int h = 0; m_LPREngine.m_LPRFuntions.GetCandidatePlateImageSize(i, ref w, ref h); byte[,] r = new byte[w, h]; byte[,] g = new byte[w, h]; byte[,] b = new byte[w, h]; error = 0; int sucess = m_LPREngine.m_LPRFuntions.GetDiagCandidatePlateImage(i, r, g, b, ref error);// get the full resolution image if (sucess == 0) continue; Bitmap bt = new Bitmap(w, h); putPixelsIntoBmp(bt, r, g, b); PLATE_INFO plateDiagInfo = new PLATE_INFO(); plateDiagInfo.plateImage = bt; DrawHistoBoundsOnPlateImage(plateDiagInfo); // get the diagnostic char images from the OCR lib for (int c = 0; c < plateDiagInfo.charImages.Count(); c++) { Bitmap cBmp = null; m_LPREngine.m_LPRFuntions.GetDiagCharImage(i, c, out cBmp); plateDiagInfo.charImages[c] = cBmp; } // run diag histogram display on each plate { Bitmap plateImageUnprocessed = new Bitmap(w, h); m_LPREngine.m_LPRFuntions.GetCandidatePlateImage(i, out plateImageUnprocessed); plateDiagInfo.plateImageUnprocessed = plateImageUnprocessed; int[,] plum = new int[plateImageUnprocessed.Width, plateImageUnprocessed.Height]; PixelLib.Pixels.getPixelsFromImage(plateImageUnprocessed, plum); int[] histo = new int[256]; int[] integration = new int[256]; Bitmap hBmp = new Bitmap(256, 100); HistoResults histStats = null; plateDiagInfo.histString = historgram(plum, histo, integration, true, hBmp, plateDiagInfo.histoBounds, out histStats); plateDiagInfo.histoBmp = hBmp; } AddPlateTabToDiagPage(plateDiagInfo); } } catch (Exception ex) { MessageBox.Show(ex.Message + ex.StackTrace); } } } catch (Exception ex) { MessageBox.Show(ex.Message + ex.StackTrace); } }