python和c#的 opencv文字區域識別
阿新 • • 發佈:2020-11-27
//var filename = @"E:\test\amap-binary.bmp"; //讀取灰度圖 using (Mat src = new Mat(filename, ImreadModes.Grayscale)) { //Cv2.ImShow("Demo", src); //1.Sobel運算元,x方向求梯度 Mat sobel = new Mat(); Cv2.Sobel(src, sobel, MatType.CV_8U, 1, 0, 3); //2.二值化 Mat binary = new Mat(); Cv2.Threshold(sobel, binary, 0, 255, ThresholdTypes.Otsu | ThresholdTypes.Binary);//3. 膨脹和腐蝕操作的核函式 Mat element1 = new Mat(); Mat element2 = new Mat(); OpenCvSharp.Size size1 = new OpenCvSharp.Size(30, 9); OpenCvSharp.Size size2 = new OpenCvSharp.Size(24, 6); element1 = Cv2.GetStructuringElement(MorphShapes.Rect, size1); element2 = Cv2.GetStructuringElement(MorphShapes.Rect, size2);//4. 膨脹一次,讓輪廓突出 Mat dilation = new Mat(); Cv2.Dilate(binary, dilation, element2); //5. 腐蝕一次,去掉細節,如表格線等。注意這裡去掉的是豎直的線 Mat erosion = new Mat(); Cv2.Erode(dilation, erosion, element1); //6. 再次膨脹,讓輪廓明顯一些 Mat dilation2 = new Mat(); Cv2.Dilate(erosion, dilation2, element2, null, 2); OpenCvSharp.Point[][] contours; HierarchyIndex[] hierarchly; Cv2.FindContours(dilation2,out contours, out hierarchly, RetrievalModes.Tree, ContourApproximationModes.ApproxSimple, new OpenCvSharp.Point(0, 0)); //Mat dst_Image = Mat.Zeros(src.Size(), src.Type()); Mat dst_Image = src.Clone(); string pts = ""; for (int i = 0; i < contours.Length; i++) { Scalar color = new Scalar(0, 255, 255);// //Cv2.DrawContours(dst_Image, contours, i, color, 1, LineTypes.Link8, hierarchly); double area = Cv2.ContourArea(contours[i]); if (area < 1000) continue; var epsilon = 0.001 * Cv2.ArcLength(contours[i], true); var approx = Cv2.ApproxPolyDP(contours[i], epsilon, true); //找到最小矩形,可能有方向 var rect2 = Cv2.MinAreaRect(contours[i]); var box = rect2.Points(); //篩選那些太細的矩形,留下扁的 var height = Math.Abs(box[0].Y - box[2].Y); var width = Math.Abs(box[0].X - box[2].X); if (height > width * 1.2) continue; pts += rect2.Center.X.ToString() + "," + rect2.Center.Y.ToString() + ";"; Cv2.DrawContours(dst_Image, contours, i, color, 1, LineTypes.Link8, hierarchly); } Cv2.ImShow(pts, dst_Image); Cv2.WaitKey(0);
#coding=utf-8 import sys import cv2 import numpy as np # img = cv2.imread(r'E:\test\amap-binary.bmp') # cv2.namedWindow("Image") # cv2.imshow("Image", img) # cv2.waitKey (0) # cv2.destroyAllWindows() def preprocess(gray): # 1. Sobel運算元,x方向求梯度 sobel = cv2.Sobel(gray, cv2.CV_8U, 1, 0, ksize = 3) # 2. 二值化 ret, binary = cv2.threshold(sobel, 0, 255, cv2.THRESH_OTSU+cv2.THRESH_BINARY) # 3. 膨脹和腐蝕操作的核函式 element1 = cv2.getStructuringElement(cv2.MORPH_RECT, (30, 9)) element2 = cv2.getStructuringElement(cv2.MORPH_RECT, (24, 6)) # 4. 膨脹一次,讓輪廓突出 dilation = cv2.dilate(binary, element2, iterations = 1) # 5. 腐蝕一次,去掉細節,如表格線等。注意這裡去掉的是豎直的線 erosion = cv2.erode(dilation, element1, iterations = 1) # 6. 再次膨脹,讓輪廓明顯一些 dilation2 = cv2.dilate(erosion, element2, iterations = 2) # 7. 儲存中間圖片 cv2.imwrite("binary.png", binary) cv2.imwrite("dilation.png", dilation) cv2.imwrite("erosion.png", erosion) cv2.imwrite("dilation2.png", dilation2) return dilation2 def findTextRegion(img): region = [] # 1. 查詢輪廓 contours, hierarchy = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # 2. 篩選那些面積小的 for i in range(len(contours)): cnt = contours[i] # 計算該輪廓的面積 area = cv2.contourArea(cnt) # 面積小的都篩選掉 if(area < 1000): continue # 輪廓近似,作用很小 epsilon = 0.001 * cv2.arcLength(cnt, True) approx = cv2.approxPolyDP(cnt, epsilon, True) # 找到最小的矩形,該矩形可能有方向 rect = cv2.minAreaRect(cnt) print "rect is: " print rect # box是四個點的座標 box = cv2.cv.BoxPoints(rect) box = np.int0(box) # 計算高和寬 height = abs(box[0][1] - box[2][1]) width = abs(box[0][0] - box[2][0]) # 篩選那些太細的矩形,留下扁的 if(height > width * 1.2): continue region.append(box) return region def detect(img): # 1. 轉化成灰度圖 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 2. 形態學變換的預處理,得到可以查詢矩形的圖片 dilation = preprocess(gray) # 3. 查詢和篩選文字區域 region = findTextRegion(dilation) # 4. 用綠線畫出這些找到的輪廓 for box in region: cv2.drawContours(img, [box], 0, (0, 255, 0), 2) cv2.namedWindow("img", cv2.WINDOW_NORMAL) cv2.imshow("img", img) # 帶輪廓的圖片 cv2.imwrite("contours.png", img) cv2.waitKey(0) cv2.destroyAllWindows() if __name__ == '__main__': # 讀取檔案 imagePath = r'E:\test\amap-binary.bmp' img = cv2.imread(imagePath) detect(img)