OpenCVsharp实现提取文本区域检测 来提取图片中的文本区域坐标
OpenCVOpenCVSharp文本检测文本区域检测文本区域坐标提取文本区域
OpenCVSharp
662
OpenCVsharp实现提取文本区域检测 来提取图片中的文本区域坐标
早前从事医疗自助打印系统的时候 ,胶片自助打印这一块时很核心的一块,胶片这块业务流程有两大难点
- 一、 对接各类放射打印设备(不多说 有这块烦恼的又想偷懒买成品的可以看看)
# FO-DICOM胶片C-PrintSCP 虚拟打印服务端实现源码
- 二、业务流程最核心的功能 自动化ocr识别系统
# TKOCR - 一款简化离线文字OCR识别的辅助集成工具 本工具在windows上离线识别部署使用对接十分方便
对于整个系统来说最大的利益点就是胶片打印,基本软件系统就是附赠品 耗材费用才是盈利点,但胶片打印识别这块也是最麻烦的,不同设备, 不同医院 ,不同医生,甚至于不同患者都有可能导致胶片上的字体位置、大小、字体的变化。最终就可能导致识别失败
为了解决这个问题,围绕着谷歌的开源ocr组件tesseract-ocr做了一系列辅助ocr识别的工具 ,文本区域检测工具就是其中一项 节省了胶片整张识别的效率问题 核心代码也是抄网络大神的
文本区域检测的逻辑就是 通过对图片二值化处理再通过反复腐蚀膨胀得到一个接近矩形的方块 然后将这些矩形框选出来就得到了文本所在区域 再根据一系列过滤规则提取到我们所需要的区域 进行识别减少不必要的图像识别 以提升系统整体效率
核心代码步骤如下:
- 文字区域处理
public void FindText(string imgPath)
{
Mat dilation2 = new Mat();
//读取灰度图
using (Mat src = new Mat(imgPath, ImreadModes.Grayscale))
{
Cv2.ImShow("原始图像", 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(20, 20);
OpenCvSharp.Size size2 = new OpenCvSharp.Size(16, 10);
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. 再次膨胀,让轮廓明显一些
Cv2.Dilate(erosion, dilation2, element2, null, 3);
Cv2.ImShow("文本处理效果", dilation2);
}
this.FindTextRegion(dilation2, imgPath);
}
- 将处理过的图像里的文字区域框选出来
public void FindTextRegion(Mat dilation,string film)
{
Mat mat = new Mat(film);
// 1. 查找轮廓
OpenCvSharp.Point[][] contours;
HierarchyIndex[] hierarchly;
Rect biggestContourRect = new Rect();
Cv2.FindContours(dilation, out contours, out hierarchly, RetrievalModes.Tree, ContourApproximationModes.ApproxSimple);
// 2. 筛选那些面积小的
int i = 0;
foreach (OpenCvSharp.Point[] contour in contours)
{
double area = Cv2.ContourArea(contour);
//面积小的都筛选掉
if (area < 1000)
{
continue;
}
//轮廓近似,作用很小
double epsilon = 0.001 * Cv2.ArcLength(contour, true);
//找到最小的矩形
biggestContourRect = Cv2.BoundingRect(contour);
if (biggestContourRect.Height > (biggestContourRect.Width * 1.2))
{
continue;
}
//画线
mat.Rectangle(biggestContourRect, new Scalar(0, 255, 0), 2);
}
Cv2.ImShow("文字区域框选", mat);
}
- 调用方法得到文本区域结果
string film = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "测试胶片.jpg");
FindText(film);
代码运行效果示例图片
面对不同大小或者间隔不同的图片需要针对性的设置算子参数 来提升准确度,这样就拿到了文字区域的具体位置然后配合ocr做识别效果还是挺不错的
问题反馈/学习建议
1. 文明上网,理性表达,营造舒适的学习氛围
2. 请不要反馈提交与本页主题无关内容