如何避免pycocotools解码RLE时出现段错误及相关问题
关于pycocotools解码损坏RLE的问题及解决思路
错误复现
使用pycocotools 2.0.2版本解码损坏的RLE时,会触发段错误:
from pycocotools import mask # pycocotools version is 2.0.2 mask.decode({'size': [1024, 1024], 'counts': "OeSOk0[l0VOaSOn0kh0cNmYO'"})
实际运行输出:
Python 3.6.15 (default) [GCC 9.4.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> >>> from pycocotools import mask >>> mask.decode({'size': [1024, 1024], 'counts': "OeSOk0[l0VOaSOn0kh0cNmYO'"}) Segmentation fault (core dumped)
问题解答
1. 解码前验证RLE有效性的方法
可以通过以下步骤提前验证RLE的有效性,避免触发段错误:
- 检查基础结构:确保RLE字典包含
size和counts键,size是两个正整数组成的列表(对应图像高、宽),counts是非空字符串/字节流。 - 利用pycocotools内置函数前置验证:
mask.frPyObjects和mask.area函数在处理无效RLE时会抛出Python异常(而非段错误),可以通过捕获异常判断有效性:
from pycocotools import mask def validate_rle(rle_dict): try: h, w = rle_dict['size'] if h <=0 or w <=0: return False # 转换为内部格式 mask_obj = mask.frPyObjects(rle_dict, h, w) # 验证游程总长度匹配图像总像素数 total_pixels = h * w return mask.area(mask_obj) == total_pixels except Exception: return False
调用mask.decode前先执行validate_rle(rle_dict),返回True再进行解码。
2. 处理SIGSEGV信号并让代码继续执行的方法
段错误(SIGSEGV)源于pycocotools的C扩展访问非法内存,Python层面的信号处理无法保证稳定性,子进程隔离是更可靠的方案:将解码逻辑放到独立子进程中执行,主进程监控子进程状态,即使子进程崩溃,主进程仍可继续运行。示例代码:
from multiprocessing import Process, Queue from pycocotools import mask def _decode_rle(rle_dict, result_queue): try: decoded = mask.decode(rle_dict) result_queue.put(('ok', decoded)) except Exception as e: result_queue.put(('error', str(e))) def safe_decode(rle_dict): q = Queue() p = Process(target=_decode_rle, args=(rle_dict, q)) p.start() p.join(timeout=3) # 设置超时防止子进程卡死 if p.exitcode == -11: # Linux下段错误的退出码为-11 return ('crash', 'Segmentation fault') if p.is_alive(): p.terminate() return ('error', 'Decode timeout') return q.get() if not q.empty() else ('error', 'Unknown error') # 使用示例 rle = {'size': [1024, 1024], 'counts': "OeSOk0[l0VOaSOn0kh0cNmYO'"} print(safe_decode(rle))
内容的提问来源于stack exchange,提问作者Yuriy Leonov
相关产品推荐
相关产品推荐

