使用Parallel.For并行处理OCR时Bitmap锁定/被占用错误求助
问题:并行处理图像OCR时出现Bitmap锁定错误
我开发了一个对图像中选定文本行执行OCR的程序,原本用for循环运行正常,但串行处理耗时累积,所以尝试用Parallel.For并行处理最多5行文本。单条文本行时无报错,多文本行时出现以下错误:
System.InvalidOperationException: 'Bitmap region is already locked.' OR Bitmap is in use elsewhere
使用EMGU和Tesseract类的相关代码如下:
private void ocrmethod() { this.Invoke((MethodInvoker)delegate { Image<Gray, byte> temp = frame.Convert<Gray, byte>().Clone(); // for (int i = 0; i < imgcount; i++) Parallel.For(0, imgcount, i => { temp.ROI = LineRect[i]; // Selected text line region in the image OCR_Class doocr = new OCR_Class(); Image<Gray, byte> foundareafilter = temp.Copy(); bitmap2 = new Bitmap(foundareafilter.ToBitmap<Gray, byte>()); //OCR SECTION doocr.trainingdatapath(@"./OCRtraindata", "eng"); doocr.ProcessOCR(bitmap2, 1); string result = doocr.result().Replace(" ", "").Replace(" ", ""); // } }); }); }
问题根源
多个并行线程同时修改并访问同一个temp对象的ROI属性、调用Copy()方法,而EMGU的Image对象本身不是线程安全的,Bitmap对象也不支持多线程并发访问,导致资源锁定冲突。此外,共享变量bitmap2也会引发线程间的覆盖问题。
修复方案
- 每个线程独立创建图像副本:不在并行循环外创建共享的
temp对象,而是在每个线程内部单独克隆原始图像并设置ROI,彻底避免线程间的资源竞争。 - 使用局部变量替代共享变量:将
bitmap2改为线程内的局部变量,防止多个线程互相覆盖数据。 - 分离UI线程与并行计算:不要将整个
Parallel.For包裹在Invoke中,仅在需要更新UI时单独调用Invoke,避免阻塞并行处理。 - 及时释放资源:用
using语句包裹所有实现IDisposable的对象(如Image、Bitmap),确保资源及时释放,避免内存泄漏和锁定问题。
修改后的代码示例:
private void ocrmethod() { // 先在UI线程外获取原始图像的独立副本 Image<Gray, byte> originalFrame = frame.Convert<Gray, byte>().Clone(); Parallel.For(0, imgcount, i => { // 每个线程单独克隆图像,避免共享资源冲突 using (Image<Gray, byte> temp = originalFrame.Clone()) { temp.ROI = LineRect[i]; using (Image<Gray, byte> foundareafilter = temp.Copy()) using (Bitmap bitmap2 = foundareafilter.ToBitmap<Gray, byte>()) { OCR_Class doocr = new OCR_Class(); doocr.trainingdatapath(@"./OCRtraindata", "eng"); doocr.ProcessOCR(bitmap2, 1); string result = doocr.result().Replace(" ", "").Replace(" ", ""); // 仅在需要更新UI时调用Invoke this.Invoke((MethodInvoker)delegate { // 此处处理结果的UI更新逻辑,例如显示识别结果 }); } } }); }
额外优化建议
- 将
OCR_Class的初始化(包括trainingdatapath)移到并行循环外,创建线程安全的OCR实例池,或者让OCR_Class支持复用,减少重复加载训练数据的开销。
内容的提问来源于stack exchange,提问作者Alisha
相关产品推荐
相关产品推荐

