public void MSER() { using var msers = new VectorOfVectorOfPoint(); using var bboxes = new VectorOfRect(); _mser.DetectRegions(_gray, msers, bboxes); }
/// <summary> /// Extracts MSER by C++-style code (cv::MSER) /// </summary> /// <param name="gray"></param> /// <param name="dst"></param> private void CppStyleMSER(Mat gray, Mat dst) { MSER mser = MSER.Create(); Point[][] contours; Rect[] bboxes; mser.DetectRegions(gray, out contours, out bboxes); foreach (Point[] pts in contours) { Scalar color = Scalar.RandomColor(); foreach (Point p in pts) { dst.Circle(p, 1, color); } } //Cv2.Rectangle(dst, bboxes, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), 3); foreach (var item in bboxes) { Cv2.Rectangle(dst, item, Scalar.Red); } }
public async Task <string> PostAsync() { /*var task = this.Request.Content.ReadAsStreamAsync(); * task.Wait(); * Stream requestStream = task.Result;*/ try { string root = HttpContext.Current.Server.MapPath("~/App_Data"); var provider = new MultipartFormDataStreamProvider(root); await Request.Content.ReadAsMultipartAsync(provider); MultipartFileData file = provider.FileData[0]; string filename = file.LocalFileName; string newfilename = file.Headers.ContentDisposition.FileName.Trim(new char[] { '\"' }); string newfilepath = root + '\\' + newfilename; try { File.Delete(newfilepath); File.Move(filename, newfilepath); } catch (Exception e) { Trace.WriteLine(e); } try { using (Mat src = new Mat(newfilepath, ImreadModes.Color)) using (Mat gray = new Mat()) using (Mat dst = src.Clone()) { Cv2.CvtColor(src, gray, ColorConversionCodes.BGR2GRAY); MSER mser = MSER.Create(); Point[][] msers; Rect[] bboxes; mser.DetectRegions(gray, out msers, out bboxes); } } catch (Exception e) { Trace.WriteLine(e); } } catch (IOException) { throw new HttpResponseException(HttpStatusCode.InternalServerError); } return(JsonConvert.SerializeObject(new { Dummy = "descriptor" })); }
/// <summary> /// Extracts MSER by C++-style code (cv::MSER) /// </summary> /// <param name="gray"></param> /// <param name="dst"></param> private void CppStyleMSER(Mat gray, Mat dst) { MSER mser = MSER.Create(); mser.DetectRegions(gray, out Point[][] contours, out _); foreach (Point[] pts in contours) { Scalar color = Scalar.RandomColor(); foreach (Point p in pts) { dst.Circle(p, 1, color); } } }
public static List <Pix> GetTextAreas(string filePath) { using (Mat src = new Mat(filePath, ImreadModes.Color)) using (Mat gray = new Mat()) { Cv2.CvtColor(src, gray, ColorConversionCodes.BGR2GRAY); MSER mser = MSER.Create(); Point[][] msers = null; OpenCvSharp.Rect[] boundingBoxes = null; mser.DetectRegions(gray, out msers, out boundingBoxes); // MSER::operator() int meanWidth = (int)(boundingBoxes.Select(x => x.Width).Average()); int stdWidth = (int)( Math.Sqrt( boundingBoxes.Select( x => x.Width ).Average( x => x * x ) - Math.Pow(meanWidth, 2))); int meanHeight = (int)(boundingBoxes.Select(x => x.Height).Average()); int stdHeight = (int)( Math.Sqrt( boundingBoxes.Select( x => x.Height ).Average( x => x * x ) - Math.Pow(meanHeight, 2))); foreach (OpenCvSharp.Rect rect in boundingBoxes) { rect.Inflate(6, 2); if (rect.Width - meanWidth < stdWidth && rect.Height - meanHeight < stdHeight) { gray.Rectangle(rect, Scalar.Black, -1); } } var bitmapToPix = new BitmapToPixConverter(); return(ExtractTextAreasFromMask(gray).Select(x => bitmapToPix.Convert(x.ToBitmap())).ToList()); } }
/// <summary> /// Extracts MSER by C++-style code (cv::MSER) /// </summary> /// <param name="gray"></param> /// <param name="dst"></param> private static void CppStyleMSER(Mat gray, Mat dst) { MSER mser = MSER.Create(); Point[][] contours; Rect[] bboxes; mser.DetectRegions(gray, out contours, out bboxes); foreach (var item in bboxes) { Scalar color = Scalar.Blue; dst.Rectangle(item, color); } /*foreach (Point[] pts in contours) * { * Scalar color = Scalar.RandomColor(); * foreach (Point p in pts) * { * dst.Circle(p, 1, color); * } * }*/ }
//MyMSER static List <Point[][]> My_MSER(int my_delta, int my_minArea, int my_maxArea, double my_maxVariation, Mat img, ref Mat img_rgb, int big_flag) { //img.SaveImage("img_detected.jpg"); List <Point[][]> final_area = new List <Point[][]>(); Point[][] contours; Rect[] bboxes; MSER mser = MSER.Create(delta: my_delta, minArea: my_minArea, maxArea: my_maxArea, maxVariation: my_maxVariation); mser.DetectRegions(img, out contours, out bboxes); //====================================Local Majority Vote // to speed up, create four shift image first var shift_mat = set_shift_image(ref img); Mat[] neighbor_img = new Mat[4]; for (int i = 0; i < 4; i++) { neighbor_img[i] = new Mat(); var imageCenter = new Point2f(img.Cols / 2f, img.Rows / 2f); var rotationMat = Cv2.GetRotationMatrix2D(imageCenter, 100, 1.3); Cv2.WarpAffine(img, neighbor_img[i], shift_mat[i], img.Size()); //neighbor_img[i].SaveImage("./shift_image" + i + ".jpg"); } //for each contour, apply local majority vote foreach (Point[] now_contour in contours) { OpenCvSharp.Point[][] temp = new Point[1][]; Point[] Convex_hull = Cv2.ConvexHull(now_contour); Point[] Approx = Cv2.ApproxPolyDP(now_contour, 0.5, true); RotatedRect rotateRect = Cv2.MinAreaRect(Approx); //Debug //Console.WriteLine(Cv2.ContourArea(Approx)+" "+ rotateRect.Size.Height / rotateRect.Size.Width+ " "+rotateRect.Size.Width / rotateRect.Size.Height); if (Cv2.ContourArea(Approx) > 10000 || (Cv2.ContourArea(Approx) < stop1_inner_defect_size_min || ((rotateRect.Size.Height / rotateRect.Size.Width)) > stop1_arclength_area_ratio || ((rotateRect.Size.Width / rotateRect.Size.Height)) > stop1_arclength_area_ratio)) { continue; } //======================intensity in the area temp[0] = Approx; double mean_in_area_temp = 0, min_in_area_temp = 0; Mat mask_img_temp = Mat.Zeros(img.Size(), MatType.CV_8UC1); Cv2.DrawContours(mask_img_temp, temp, -1, 255, thickness: -1);//notice the difference between temp = Approx and Convex_hull mean_in_area_temp = img.Mean(mask_img_temp)[0]; img.MinMaxLoc(out min_in_area_temp, out _, out _, out _, mask_img_temp); //Console.WriteLine(min_in_area_temp + " " + mean_in_area_temp); if (min_in_area_temp > 100 || mean_in_area_temp > 130) { continue; } // Convex hull temp[0] = Approx; if (big_flag == 0)//small area: local majority vote { //Cv2.Polylines(img_rgb, temp, true, new Scalar(0, 0, 255), 1); //inside the area double mean_in_area = 0, min_in_area = 0; Mat mask_img = Mat.Zeros(img.Size(), MatType.CV_8UC1); Cv2.DrawContours(mask_img, temp, -1, 255, thickness: -1);//notice the difference between temp = Approx and Convex_hull mean_in_area = img.Mean(mask_img)[0]; img.MinMaxLoc(out min_in_area, out _, out _, out _, mask_img); //Console.WriteLine(min_in_area + " " + mean_in_area); //test /* * Mat mask2 = img.LessThan(230); * for (int i = 0; i < img.Cols; i++) { * for (int j = 0; j < img.Rows; j++) * if(mask2.At<bool>(i, j)==false) * Console.Write(mask2.At<bool>(i,j)+ " "); * * Console.Write("\n"); * * } */ //neighbor double[] mean_neighbor = { 255, 255, 255, 255 }; double[] min_neighbor = { 255, 255, 255, 255 }; for (int i = 0; i < 4; i++) { //先把 img > 230 的變成 0,再餵進 shift 裡面 //先把 mask 乘上另一個mask(>230的mask) //Mat mask_neighbor_img = neighbor_img[i].GreaterThan(0); //Console.WriteLine(mask_neighbor_img.At<int>(0,1)); // create final mask Mat mask2 = neighbor_img[i].LessThan(225).ToMat(); mask2.ConvertTo(mask2, MatType.CV_8U, 1.0 / 255.0); Mat mask_final = Mat.Zeros(img.Size(), MatType.CV_8UC1); mask_img.CopyTo(mask_final, mask2); //mask_final.SaveImage("./mask" + i + ".jpg"); mean_neighbor[i] = neighbor_img[i].Mean(mask_final)[0]; //compute min: //neighbor_img[i].MinMaxLoc(out min_neighbor[i], out _, out _, out _, mask_img); //Console.WriteLine(min_neighbor[i] + " " + mean_neighbor[i]); } int vote = 0; for (int i = 0; i < 4; i++) { if (mean_in_area > mean_neighbor[i]) { vote++; } } if (vote > 2 || min_in_area > 100 || mean_in_area > 130) { //Debug //Console.WriteLine(vote + " " + min_in_area + " ", min_in_area); continue; } else { //Cv2.Polylines(img_rgb, temp, true, new Scalar(0, 0, 255), 1); //Console.WriteLine("--"); final_area.Add(temp); } } else { //Console.WriteLine("--"); //Cv2.Polylines(img_rgb, temp, true, new Scalar(0, 0, 255), 1); final_area.Add(temp); } } Console.WriteLine(final_area.Count); return(final_area); }
private int CppStyleMSER(Mat gray, Mat dst) { MSER mser = MSER.Create(); Point[][] contours; Rect[] bboxes; mser.DetectRegions(gray, out contours, out bboxes); foreach (Point[] pts in contours) { Scalar color = Scalar.RandomColor(); foreach (Point p in pts) { dst.Circle(p, 1, color); } } //what will happen if you draw the box, fei List <Rect> Lboxes = new List <Rect>(); foreach (Rect rt in bboxes) { //此处可加一个算法,排除相似的box int length = Lboxes.Count(); if (length != 0) { bool iUpdate = false; int iCompare = 0; Rect x = new Rect(); foreach (Rect rtl in Lboxes) { iCompare = CompareRect(rtl, rt); if (iCompare == 2) { iUpdate = true; x = rtl; break; } } if (iCompare == 0) { Lboxes.Add(rt); } else if (iCompare == 2) { Lboxes.Remove(x); Lboxes.Add(rt); } } else { Lboxes.Add(rt); } } foreach (Rect rt in Lboxes) { Scalar color = Scalar.RandomColor(); dst.Rectangle(rt, color); } return(Lboxes.Count()); }
static int Main(string[] args) { int result = 0; //성공 여부 0:실패 1:성공 string resultOCR = ""; //Tesseract 결과 //string numeric = ""; //필터링된 숫자 List <string> resultTesser = new List <string>(); Mat mtSrc = new Mat(); try { int.TryParse(ConfigurationManager.AppSettings["RunMaximum"], out int runMaximum); int.TryParse(ConfigurationManager.AppSettings["DetectWidth"], out int detectWidth); int.TryParse(ConfigurationManager.AppSettings["DetectHeight"], out int detectHeight); int.TryParse(ConfigurationManager.AppSettings["ThresholdValue"], out int thresholdValue); int.TryParse(ConfigurationManager.AppSettings["DeviceNumber"], out int deviceNumber); int.TryParse(ConfigurationManager.AppSettings["DeleteWidth"], out int delWidth); if (runMaximum < 1 || detectWidth < 1 || detectHeight < 1 || thresholdValue < 1 || string.IsNullOrEmpty(ConfigurationManager.AppSettings["PathResult"]) || string.IsNullOrEmpty(ConfigurationManager.AppSettings["PathSuccess"]) || string.IsNullOrEmpty(ConfigurationManager.AppSettings["PathFail"]) || string.IsNullOrEmpty(ConfigurationManager.AppSettings["PathException"]) ) { throw new ConfigurationErrorsException("config 파일 설정값 오류"); } //OpenCV 캡처 초기화 VideoCapture capture = VideoCapture.FromCamera(CaptureDevice.Any, deviceNumber); DirectoryInfo diResult = new DirectoryInfo(ConfigurationManager.AppSettings["PathResult"]); if (diResult.Exists == false) { diResult.Create(); } //result 폴더 하위 파일 지우기 foreach (var file in diResult.GetFiles()) { File.Delete(string.Format("{0}\\{1}", diResult.Name, file)); } for (int i = 1; i <= runMaximum; i++) { resultOCR = ""; //화상을 Matrix 에 로드 capture.Read(mtSrc); //디바이스 문제 if (mtSrc.Width < 3) //최소 3*3 { throw new Exception("ERROR_DEVICE"); } //영역 검출 MSER mser = MSER.Create(); OpenCvSharp.Point[][] contours; OpenCvSharp.Rect[] bboxes; mser.DetectRegions(mtSrc, out contours, out bboxes); //DetectRegion 은 Canny 가 무용지물 //Smoothing Cv2.MedianBlur(mtSrc, mtSrc, 3); //색 변환 Cv2.CvtColor(mtSrc, mtSrc, ColorConversionCodes.BGR2GRAY); //검출 결과 필터링 var filteredBboxes = bboxes.Where( r => r.Width >= detectWidth - 3 && r.Width <= detectWidth + 5 && r.Height >= detectHeight - 5 && r.Height <= detectHeight + 5 ); if (isDebugMode) { Console.WriteLine(filteredBboxes.Count()); } //var orderedBboxes = filteredBboxes.OrderBy(r => r.Width); foreach (var rect in filteredBboxes) { resultOCR = ""; Rect rectTemp = rect; rectTemp.X = rect.X + delWidth; rectTemp.Width = rect.Width - delWidth; //rect 영역 crop Mat mtCrop = mtSrc[rectTemp]; if (isDebugMode) { using (new Window(mtCrop)) { Window.WaitKey(0); Window.DestroyAllWindows(); } } resultOCR = Recognize(mtCrop, thresholdValue, rectTemp); //재시도 ( 앞부분 크롭 영역 -1 조정) if (resultOCR.Length < 6 || resultOCR.Contains("_")) { rectTemp.X = rect.X + delWidth - 1; rectTemp.Width = rect.Width - delWidth + 1; mtCrop = mtSrc[rectTemp]; resultOCR = Recognize(mtCrop, thresholdValue, rectTemp); } //3차시도 ( 앞부분 크롭 영역 +1 조정) if (resultOCR.Length < 6 || resultOCR.Contains("_")) { rectTemp.X = rect.X + delWidth + 1; rectTemp.Width = rect.Width - delWidth - 1; mtCrop = mtSrc[rectTemp]; resultOCR = Recognize(mtCrop, thresholdValue, rectTemp); } //4차 if (resultOCR.Length < 6 || resultOCR.Contains("_")) { rectTemp.X = rect.X + delWidth - 2; rectTemp.Width = rect.Width - delWidth + 2; mtCrop = mtSrc[rectTemp]; resultOCR = Recognize(mtCrop, thresholdValue, rectTemp); } //5차시도 ( 앞부분 크롭 영역 +2 조정) if (resultOCR.Length < 6 || resultOCR.Contains("_")) { rectTemp.X = rect.X + delWidth + 2; rectTemp.Width = rect.Width - delWidth - 2; mtCrop = mtSrc[rectTemp]; resultOCR = Recognize(mtCrop, thresholdValue, rectTemp); } if (resultOCR.Length == 6 && resultOCR.Contains("_") == false) { result = 1; //성공 Console.WriteLine(string.Format("{0}\t({1})", resultOCR, i)); if (isDebugMode) { //Console.WriteLine(string.Format("width : {0} height : {1}", rect.Width, rect.Height)); //Cv2.ImShow("mtCrop", mtCrop); //Cv2.WaitKey(0); //Cv2.DestroyWindow("seg"); } break; } } // foreach if (result == 1) { break; } //if (numeric.Length == 0) //{ // foreach (var rect in bboxes) // { // Scalar color = Scalar.RandomColor(); // mtSrc.Rectangle(rect, color); // } //} //Cv2.ImShow(filename, mtSrc); //Cv2.ImShow("clone", mtSrc); //Cv2.WaitKey(0); //Thread.Sleep(300); } //for runMaximum if (result == 1) { //result = 1; //성공 여부 //이미지 저장 mtSrc.SaveImage(string.Format("{0}\\{1}.png", diResult.Name, resultOCR)); //이미지 사본 복사 DirectoryInfo diSuccess = new DirectoryInfo(ConfigurationManager.AppSettings["PathSuccess"]); if (diSuccess.Exists == false) { diSuccess.Create(); } string filename = resultOCR; if (File.Exists(string.Format("{0}\\{1}.png", diSuccess.Name, filename))) { filename = resultOCR + "_" + DateTime.Now.ToString("yyMMddHHmmss"); } File.Copy(string.Format("{0}\\{1}.png", diResult.Name, resultOCR), string.Format("{0}\\{1}.png", diSuccess.Name, filename)); //Console.WriteLine(numeric); } else { //실패 이미지 저장 DirectoryInfo diFail = new DirectoryInfo(ConfigurationManager.AppSettings["PathFail"]); if (diFail.Exists == false) { diFail.Create(); } mtSrc.SaveImage(string.Format("{0}\\{1}.png", diFail.Name, DateTime.Now.ToString("yyMMddHHmmss"))); } } catch (Exception ex) { //Exception 저장 DirectoryInfo diEx = new DirectoryInfo(ConfigurationManager.AppSettings["PathException"]); if (diEx.Exists == false) { diEx.Create(); } File.WriteAllText(string.Format("{0}\\{1}.txt", diEx.Name, DateTime.Now.ToString("yyMMddHHmmss")), ex.ToString()); //담당자에게 alert 전송 if (isDebugMode) { //Console.WriteLine(result); Console.WriteLine(ex); } } finally { } //Console.ReadKey(); return(result); }