}//end private void writeLicensePlateCharsOnImage(Mat imgOriginalScene, PossiblePlate licPlate) { Point ptCenterOfTextArea = new Point(); Point ptLowerLeftTextOrigin = new Point(); FontFace fontFace = FontFace.HersheySimplex; double dblFontScale = licPlate.imgPlate.Height / 30; int intFontThickness = (int)(dblFontScale * 1.5); Size textSize = new Size(); textSize.Width = (int)(dblFontScale * 18.5 * licPlate.strChars.Length); textSize.Height = (int)(dblFontScale * 25); ptCenterOfTextArea.X = (int)(licPlate.rrLocationOfPlateInScene.Center.X); if (licPlate.rrLocationOfPlateInScene.Center.Y < (imgOriginalScene.Height * 0.75)) { ptCenterOfTextArea.Y = (int)(licPlate.rrLocationOfPlateInScene.Center.Y + (int)((double)(licPlate.rrLocationOfPlateInScene.MinAreaRect().Height) * 1.6)); } else { ptCenterOfTextArea.Y = (int)(licPlate.rrLocationOfPlateInScene.Center.Y - (int)((double)(licPlate.rrLocationOfPlateInScene.MinAreaRect().Height) * 1.6)); } ptLowerLeftTextOrigin.X = (int)(ptCenterOfTextArea.X - (textSize.Width / 2)); ptLowerLeftTextOrigin.Y = (int)(ptCenterOfTextArea.Y + (textSize.Height / 2)); CvInvoke.PutText(imgOriginalScene, licPlate.strChars, ptLowerLeftTextOrigin, fontFace, dblFontScale, SCALAR_YELLOW, intFontThickness); }
}//end btnOpneFile private void drawRedRectangleAroundPlate(Mat imgOriginalScene, PossiblePlate licPlate) { PointF[] ptfRectPoints = new PointF[4]; ptfRectPoints = licPlate.rrLocationOfPlateInScene.GetVertices(); Point pt0 = new Point((int)(ptfRectPoints[0].X), (int)(ptfRectPoints[0].Y)); Point pt1 = new Point((int)(ptfRectPoints[1].X), (int)(ptfRectPoints[1].Y)); Point pt2 = new Point((int)(ptfRectPoints[2].X), (int)(ptfRectPoints[2].Y)); Point pt3 = new Point((int)(ptfRectPoints[3].X), (int)(ptfRectPoints[3].Y)); CvInvoke.Line(imgOriginalScene, pt0, pt1, SCALAR_RED, 2); CvInvoke.Line(imgOriginalScene, pt1, pt2, SCALAR_RED, 2); CvInvoke.Line(imgOriginalScene, pt2, pt3, SCALAR_RED, 2); CvInvoke.Line(imgOriginalScene, pt3, pt0, SCALAR_RED, 2); }//end
}//end possibleplateinscene public static PossiblePlate extractPlate(Mat imgOriginal, List <PossibleChar> listOfMatchingChars) { PossiblePlate possiblePlate = new PossiblePlate(); listOfMatchingChars.Sort((firstChar, secondChar) => firstChar.intCenterX.CompareTo(secondChar.intCenterX));//?????????????????????? double dblPlateCenterX = (double)(listOfMatchingChars[0].intCenterX + listOfMatchingChars[listOfMatchingChars.Count - 1].intCenterX) / 2.0; double dblPlateCenterY = (double)(listOfMatchingChars[0].intCenterY + listOfMatchingChars[listOfMatchingChars.Count - 1].intCenterY) / 2.0; PointF ptfPlateCenter = new PointF((float)dblPlateCenterX, (float)dblPlateCenterY); int intPlateWidth = (int)((double)(listOfMatchingChars[listOfMatchingChars.Count - 1].boundingRect.X + listOfMatchingChars[listOfMatchingChars.Count - 1].boundingRect.Width - listOfMatchingChars[0].boundingRect.X) * PLATE_WIDTH_PADDING_FACTOR); int intTotalOfCharHeights = 0; foreach (PossibleChar matchingChar in listOfMatchingChars) { intTotalOfCharHeights = intTotalOfCharHeights + matchingChar.boundingRect.Height; } double dblAverageCharHeight = (double)(intTotalOfCharHeights) / (double)(listOfMatchingChars.Count); int intPlateHeight = (int)(dblAverageCharHeight * PLATE_HEIGHT_PADDING_FACTOR); double dblOpposite = listOfMatchingChars[listOfMatchingChars.Count - 1].intCenterY - listOfMatchingChars[0].intCenterY; double dblHypotenuse = DetectChars.distanceBetweenChars(listOfMatchingChars[0], listOfMatchingChars[listOfMatchingChars.Count - 1]); double dblCorrectionAngleInRad = Math.Asin(dblOpposite / dblHypotenuse); double dblCorrectionAngleInDeg = dblCorrectionAngleInRad * (180.0 / Math.PI); possiblePlate.rrLocationOfPlateInScene = new RotatedRect(ptfPlateCenter, new SizeF((Single)intPlateWidth, (Single)intPlateHeight), (Single)dblCorrectionAngleInDeg); Mat rotationMatrix = new Mat(); Mat imgRotated = new Mat(); Mat imgCropped = new Mat(); CvInvoke.GetRotationMatrix2D(ptfPlateCenter, dblCorrectionAngleInDeg, 1.0, rotationMatrix); CvInvoke.WarpAffine(imgOriginal, imgRotated, rotationMatrix, imgOriginal.Size); CvInvoke.GetRectSubPix(imgRotated, possiblePlate.rrLocationOfPlateInScene.MinAreaRect().Size, possiblePlate.rrLocationOfPlateInScene.Center, imgCropped); possiblePlate.imgPlate = imgCropped; return(possiblePlate); }//end extractplate
private void btnOpenFile_Click(object sender, EventArgs e) { Mat imgOriginalScene = new Mat(); OpenFileDialog openFileDialog = new OpenFileDialog(); openFileDialog.Multiselect = false; openFileDialog.Filter = "Img Files|*.bmp;*.png;*.jpg;*.jpeg"; openFileDialog.DefaultExt = ".png"; if (openFileDialog.ShowDialog() == DialogResult.OK) { //Image<Bgr, byte> input_img = new Image<Bgr, byte>(openFileDialog.FileName); //imgOriginalScene = input_img.Mat; //ibOriginal.Image = imgOriginalScene; lblChosenFile.Text = openFileDialog.FileName; CvInvoke.DestroyAllWindows(); imgOriginalScene = CvInvoke.Imread(openFileDialog.FileName); ibOriginal.Image = imgOriginalScene; } List <PossiblePlate> listOfPossiblePlates = DetectPlate.detectPlatesInScene(imgOriginalScene); listOfPossiblePlates = DetectChars.detectCharsInPlates(listOfPossiblePlates); if (listOfPossiblePlates == null) { MessageBox.Show("No detected :( :("); } else if (listOfPossiblePlates.Count == 0) { MessageBox.Show("No detected :( :("); } else { listOfPossiblePlates.Sort((onePlate, otherPlate) => otherPlate.strChars.Length.CompareTo(onePlate.strChars.Length)); PossiblePlate licPlate = listOfPossiblePlates[0]; CvInvoke.Imshow("final imgPlate", licPlate.imgPlate); CvInvoke.Imshow("final imgThresh", licPlate.imgThresh); if (licPlate.strChars.Length == 0) { MessageBox.Show("No detected characters :( :("); } txtInfo.Text = DetectPlate.tmptxt; //drawRedRectangleAroundPlate(imgOriginalScene, licPlate); do dorobienia funkcja drawRedRectangleAroundPlate(imgOriginalScene, licPlate); MessageBox.Show(licPlate.strChars); writeLicensePlateCharsOnImage(imgOriginalScene, licPlate); ibOriginal.Image = imgOriginalScene; CvInvoke.Imwrite("imgOriginalScene.png", imgOriginalScene); } }//end btnOpneFile