Advertisement
Guest User

Untitled

a guest
Oct 31st, 2014
153
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.37 KB | None | 0 0
  1. using System;
  2. using System.Text.RegularExpressions;
  3.  
  4.  
  5. /* Hidde Westerhof & Yannick Strobl
  6. * L2A
  7. * Datum: 21 10 2014
  8. * Laatste Score: 175 (Treshold 30) (min moet 200 zijn)
  9. *
  10. */
  11.  
  12. namespace LicPlate
  13. {
  14. public class LicensePlateMatcher
  15. {
  16. /// <summary>
  17. /// Deze lijst staat vol met reguliere expressies die grammatica's van nummerborden voorstellen.
  18. /// </summary>
  19. private static readonly Regex[] regexes = new Regex[] { new Regex(@"^[a-zA-Z]{2}[\d]{2}[\d]{2}$"),
  20. new Regex(@"^[\d]{2}[\d]{2}[a-zA-Z]{2}$"),
  21. new Regex(@"^[\d]{2}[a-zA-Z]{2}[\d]{2}$"),
  22. new Regex(@"^[a-zA-Z]{2}[\d]{2}[a-zA-Z]{2}$"),
  23. new Regex(@"^[a-zA-Z]{2}[a-zA-Z]{2}[\d]{2}$"),
  24. new Regex(@"^[\d]{2}[a-zA-Z]{2}[a-zA-Z]{2}$"),
  25. new Regex(@"^[\d]{2}[a-zA-Z]{3}[\d]{1}$"),
  26. new Regex(@"^[\d]{1}[a-zA-Z]{3}[\d]{2}$"),
  27. new Regex(@"^[a-zA-Z]{2}[\d]{3}[a-zA-Z]{1}$"),
  28. new Regex(@"^[a-zA-Z]{1}[\d]{3}[a-zA-Z]{2}$"),
  29. new Regex(@"^[a-zA-Z]{3}[\d]{2}[a-zA-Z]{1}$"),
  30. new Regex(@"^[a-zA-Z]{1}[\d]{2}[a-zA-Z]{3}$"),
  31. new Regex(@"^[\d]{1}[a-zA-Z]{2}[\d]{3}$"),
  32. new Regex(@"^[\d]{3}[a-zA-Z]{2}[\d]{1}$")
  33. };
  34.  
  35. private class TresHolds
  36. {
  37. public static readonly TresHolds H_NORM = new TresHolds(11, 80);
  38. public static readonly TresHolds S_NORM = new TresHolds(100, 255);
  39. public static readonly TresHolds V_NORM = new TresHolds(100, 255);
  40.  
  41. public static readonly TresHolds H_ONDER = new TresHolds(11, 85);
  42. public static readonly TresHolds S_ONDER = new TresHolds(20, 160);
  43. public static readonly TresHolds V_ONDER = new TresHolds(30, 175);
  44.  
  45. public static readonly TresHolds H_OVER = new TresHolds(20, 240);
  46. public static readonly TresHolds S_OVER = new TresHolds(30, 150);
  47. public static readonly TresHolds V_OVER = new TresHolds(250, 255);
  48.  
  49. public static readonly TresHolds BLOBS = new TresHolds(1, 1000);
  50.  
  51. public int min { get; set; }
  52. public int max { get; set; }
  53. private TresHolds(int min, int max)
  54. {
  55. this.min = min;
  56. this.max = max;
  57. }
  58. }
  59.  
  60. /*
  61. * Description:
  62. * Find the largest license plate in the image
  63. * - Segment using ThresholdHSVchannels
  64. * - Remove blobs which are not license plates
  65. * Input:
  66. * //Original image
  67. * RGB888Image plateImage
  68. * Output:
  69. * //Segmented license plate
  70. * ref Int32Image binaryPlateImage
  71. * Return:
  72. * //License plate found?
  73. * bool
  74. */
  75. public static bool FindPlate(RGB888Image plateImage, ref Int32Image binaryPlateImage)
  76. {
  77. try
  78. {
  79. //*******************************//
  80. //** Exercise: **//
  81. //** adjust licenseplate **//
  82. //** segmentation **//
  83. //*******************************//
  84.  
  85. //Find licenseplate
  86.  
  87. Func<RGB888Image, TresHolds, Int32Image>[] methods = new Func<RGB888Image, TresHolds, Int32Image>[] {
  88. new Func<RGB888Image, TresHolds, Int32Image>((a, b) => FindPlateOnTres(a, b, TresHolds.H_NORM, TresHolds.S_NORM, TresHolds.V_NORM)),
  89. new Func<RGB888Image, TresHolds, Int32Image>((a, b) => FindPlateOnTres(a, b, TresHolds.H_ONDER, TresHolds.S_ONDER, TresHolds.V_ONDER)),
  90. new Func<RGB888Image, TresHolds, Int32Image>((a, b) => FindPlateOnTres(a, b, TresHolds.H_OVER, TresHolds.S_OVER, TresHolds.V_OVER)),
  91. FindPlateOnHSV};
  92.  
  93. Int32Image binaryImage;
  94.  
  95. foreach (var method in methods)
  96. {
  97. if ((VisionLab.SumIntPixels(binaryImage = method(plateImage, TresHolds.BLOBS)) > 0))
  98. {
  99. binaryPlateImage = binaryImage;
  100. return true;
  101. }
  102. }
  103. return false;
  104. }
  105. catch (System.Exception ex)
  106. {
  107. throw new Exception("FindPlate: " + ex.Message);
  108. }
  109. }
  110.  
  111. private static Int32Image FindPlateOnTres(RGB888Image plateImage, TresHolds blob, TresHolds h, TresHolds s, TresHolds v)
  112. {
  113. Int32Image binaryPlateImage = new Int32Image(plateImage.GetWidth(), plateImage.GetHeight());
  114.  
  115. HSV888Image plateImageHSV = new HSV888Image();
  116. VisionLab.FastRGBToHSV(plateImage, plateImageHSV);
  117. VisionLab.Threshold3Channels(plateImageHSV, binaryPlateImage, h.min, h.max, s.min, s.max, v.min, v.max);
  118. removeBlobs(binaryPlateImage, plateImageHSV, blob.min, blob.max);
  119. return binaryPlateImage;
  120. }
  121.  
  122. private static Int32Image FindPlateOnHSV(RGB888Image plateImage, TresHolds blob)
  123. {
  124. HSV888Image plateImageHSV = new HSV888Image();
  125. VisionLab.FastRGBToHSV(plateImage, plateImageHSV);
  126.  
  127. Int32Image h = new Int32Image();
  128. Int32Image s = new Int32Image();
  129. Int32Image v = new Int32Image();
  130.  
  131. VisionLab.Extract1Channel(plateImageHSV, HSVColor.Hue, h);
  132. VisionLab.Extract1Channel(plateImageHSV, HSVColor.Saturation, s);
  133. VisionLab.Threshold(h, 18, 55);
  134. VisionLab.Threshold(s, 140, 230);
  135. VisionLab.Add(h, s);
  136. removeBlobs(h, plateImageHSV, blob.min, blob.max);
  137. plateImageHSV.Dispose();
  138. return h;
  139. }
  140.  
  141. private static void removeBlobs(Int32Image binaryPlateImage, HSV888Image plateImageHSV, int c_remove_blobs_min, int c_remove_blobs_max)
  142. {
  143. //Remove blobs with small areas
  144. VisionLab.RemoveBlobs(binaryPlateImage, Connected.EightConnected, BlobAnalyse.BA_Area, c_remove_blobs_min, c_remove_blobs_max);
  145. VisionLab.RemoveBorderBlobs(binaryPlateImage, Connected.EightConnected, Border.AllBorders);
  146. VisionLab.RemoveBlobs(binaryPlateImage, Connected.EightConnected, BlobAnalyse.BA_LengthBreadthRatio, 0, 2.5);
  147.  
  148. //VisionLab.RemoveBlobs(binaryPlateImage, Connected.EightConnected, BlobAnalyse.BA_NrOfHoles, 0, 5);
  149. //Fill up characters
  150. VisionLab.FillHoles(binaryPlateImage, Connected.FourConnected);
  151. }
  152.  
  153. /*
  154. * Description:
  155. * Locates the characters of the license plate
  156. * - Warp image (Rectify)
  157. * - Segment characters
  158. * - Remove blobs which are to small (Lines between characters)
  159. * Input:
  160. * //Original image
  161. * RGB888Image plateImage
  162. * //Segmented license plate
  163. * Int32Image binaryPlateImage
  164. * Output:
  165. * //Image containing binary six characters
  166. * ref Int32Image binaryCharacterImage
  167. * Return:
  168. * //Function executed successfully
  169. * bool
  170. */
  171.  
  172.  
  173.  
  174. public static bool FindCharacters(RGB888Image plateImage, Int32Image binaryPlateImage, ref Int32Image binaryCharacterImage)
  175. {
  176. try
  177. {
  178. //Constants
  179. const int c_height = 100;
  180. const int c_width = 470;
  181. const int c_remove_blobs_min = 1;
  182. const int c_remove_blobs_max = 400;
  183.  
  184. XYCoord leftTop = new XYCoord();
  185. XYCoord rightTop = new XYCoord();
  186. XYCoord leftBottom = new XYCoord();
  187. XYCoord rightBottom = new XYCoord();
  188.  
  189. //Find licenseplate
  190. if (!VisionLab.FindCornersRectangle(binaryPlateImage, Connected.EightConnected, 0.5, Orientation.Landscape, leftTop, rightTop, leftBottom, rightBottom))
  191. {
  192. VisionLab.FindCornersRectangleSq(binaryPlateImage, Connected.EightConnected, leftTop, rightTop, leftBottom, rightBottom);
  193. }
  194.  
  195. Int32Image plateImageGray = new Int32Image();
  196. VisionLab.Convert(plateImage, plateImageGray);
  197.  
  198. try
  199. {
  200. //Rectify plate
  201. VisionLab.Warp(plateImageGray, binaryCharacterImage, TransformDirection.ForwardT, new Coord2D(leftTop), new Coord2D(rightTop), new Coord2D(leftBottom), new Coord2D(rightBottom), c_height, c_width, 0);
  202. }
  203. catch (Exception)
  204. {
  205. //Warp, 3 coords on one line
  206. return false;
  207. }
  208. plateImageGray.Dispose();
  209.  
  210. //*******************************//
  211. //** Exercise: **//
  212. //** adjust licenseplate **//
  213. //** segmentation **//
  214. //*******************************//
  215.  
  216. //Find dark text on bright licenseplate using ThresholdISOData
  217. if (VisionLab.ThresholdIsoData(binaryCharacterImage, ObjectBrightness.DarkObject) != 1)
  218. {
  219. VisionLab.ThresholdIsoData(binaryCharacterImage, ObjectBrightness.BrightObject);
  220. }
  221.  
  222.  
  223. //Remove small blobs and noise
  224. Int32Image binaryCharacterImageCopy = new Int32Image(binaryCharacterImage);
  225. VisionLab.Opening(binaryCharacterImageCopy, binaryCharacterImage, new Mask_Int32(5, 1, 1));
  226.  
  227. //Remove blobs connected to the border
  228. VisionLab.RemoveBorderBlobs(binaryCharacterImage, Connected.EightConnected, Border.AllBorders);
  229. //Remove small blobs
  230. VisionLab.RemoveBlobs(binaryCharacterImage, Connected.EightConnected, BlobAnalyse.BA_Area, c_remove_blobs_min, c_remove_blobs_max);
  231.  
  232. leftTop.Dispose();
  233. rightTop.Dispose();
  234. leftBottom.Dispose();
  235. rightBottom.Dispose();
  236.  
  237.  
  238. return true;
  239. }
  240. catch (System.Exception ex)
  241. {
  242. throw new Exception("FindCharacters: " + ex.Message);
  243. }
  244. }
  245.  
  246. /*
  247. * Description:
  248. * Read the license plate
  249. * Input:
  250. * //Rectified license plate image containing six characters
  251. * Int32Image labeledRectifiedPlateImage
  252. * Output:
  253. * //Result by the blob matcher
  254. * ref LicensePlate result
  255. * Return:
  256. * //six characters found
  257. * bool
  258. */
  259. public static bool MatchPlate(Int32Image binaryCharacterImage, BlobMatcher_Int32 matcher, ClassLexicon lexicon, ref LicensePlate result, ref LicensePlate lexiconResult)
  260. {
  261. try
  262. {
  263. //Check if 6 characters/blobs have been found and label image.
  264. if (VisionLab.LabelBlobs(binaryCharacterImage, Connected.EightConnected) != 6)
  265. return false;
  266.  
  267. //Calculate dimensions and locations of all characters/blobs.
  268. vector_BlobAnalyse ba_vec = new vector_BlobAnalyse();
  269. ba_vec.Add(BlobAnalyse.BA_TopLeft);
  270. ba_vec.Add(BlobAnalyse.BA_Height);
  271. ba_vec.Add(BlobAnalyse.BA_Width);
  272. vector_Blob returnBlobs = new vector_Blob();
  273. VisionLab.BlobAnalysis(binaryCharacterImage, VisionLab.VectorToSet_BlobAnalyse(ba_vec), VisionLab.MaxPixel(binaryCharacterImage), returnBlobs, SortOrder.SortDown, BlobAnalyse.BA_TopLeft, UseXOrY.UseX);
  274. ba_vec.Dispose();
  275. Int32Image binaryCharacter = new Int32Image();
  276.  
  277. //Create data structure for lexicon.
  278. vector_vector_LetterMatch match = new vector_vector_LetterMatch();
  279.  
  280. //Process each character/blob.
  281. foreach (Blob b in returnBlobs)
  282. {
  283. //Cut out character
  284. VisionLab.ROI(binaryCharacterImage, binaryCharacter, b.TopLeft(), new HeightWidth(b.Height(), b.Width()));
  285. //Convert ROI result to binary
  286. VisionLab.ClipPixelValue(binaryCharacter, 0, 1);
  287.  
  288. //Calculate character's classification for all classes.
  289. vector_PatternMatchResult returnMatches = new vector_PatternMatchResult();
  290. float conf = matcher.AllMatches(binaryCharacter, (float)-0.5, (float)0.5, returnMatches);
  291. float err = returnMatches[0].error;
  292. int id = returnMatches[0].id;
  293. string chr = matcher.PatternName(id);
  294. //letter veranderen
  295.  
  296.  
  297. //Fill datastructure for lexicon.
  298. match.Add(VisionLabEx.PatternMatchResultToLetterMatch(returnMatches));
  299.  
  300. //Store best match in result
  301. result.characters.Add(new LicenseCharacter(chr, err, conf));
  302. }
  303.  
  304. //Validate match with lexicon.
  305. vector_int bestWord = new vector_int();
  306. lexiconResult.confidence = lexicon.FindBestWord(match, bestWord, Optimize.OptimizeForMinimum);
  307. for (int i = 0; i < bestWord.Count; i++)
  308. {
  309. string character = matcher.PatternName(bestWord[i]);
  310. //Store lexicon result
  311. lexiconResult.characters.Add(new LicenseCharacter(character));
  312.  
  313.  
  314. }
  315.  
  316. binaryCharacter.Dispose();
  317. returnBlobs.Dispose();
  318. match.Dispose();
  319. bestWord.Dispose();
  320. return numchecker(result.getLicensePlateString());
  321. }
  322. catch (System.Exception ex)
  323. {
  324. throw new Exception("MatchPlate: " + ex.Message);
  325. }
  326. }
  327.  
  328. /// <summary>
  329. /// Methode kijkt of het kenteken een valide grammatica heeft.
  330. /// </summary>
  331. /// <param name="numbord">string van de gehele nummerbord</param>
  332. /// <returns>Methode returnt true als et een goede kentekenplaat is. </returns>
  333. private static bool numchecker(string numbord)
  334. {
  335. foreach (Regex s in regexes)
  336. {
  337. if (s.IsMatch(numbord))
  338. {
  339. return true;
  340. }
  341. }
  342. return false;
  343. }
  344.  
  345. }
  346. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement