Python程序报UnicodeDecodeError: 'utf8' codec can't decode byte 0xd0 in position 0: invalid continuation

本文由Markdown语法编辑器编辑完成。

由于对博客标题的长度有限制,为了能够更准确地说明要解决的问题,和问题的适用范围,该文章的副标题如下:
Python解析DICOM图像后,调用Json.dumps或request.post时报"nicodeDecodeError: ‘utf8’ codec can’t decode byte 0xd0 in position的错误的解决方案

1. 错误出现背景

该程序的大致逻辑是,运用Python的第三方库pydicom, 读取某一张DICOM影像的一些TAG值(如Studyuid, SeriesUID, Modality, Image Instance Number, Protocol Name等等),然后将读取出的这些tag值构建出一个study的json,再将这个json值通过HTTP的post方法推送到一个定义好的url中。

但是在构建json和发送json数据时,程序会提示:
“UnicodeDecodeError: ‘utf8’ codec can’t decode byte 0xd0 in position 0: invalid continuation”的错误。后来用dicom浏览软件查看原图的时候,发现这个图像的protocol name的值是中文而引起的。

2. 错误的一种解决方案

经过和同事的讨论,后来知道,DICOM图像的Specific Character Set的tag值会存放这个图像的编码方式(但这个tag不是必填项,也有可能是None)。用pydicom读取图像时,如果可以读出这张图像的编码格式,然后显式地调用一下decode函数。这样再进行后续处理时,就可以正常地进行解码了。如果无法读出这张图像的编码格式,而这张图像又确实存在中文的tag值而导致后续出错时,可以指定赋一种编码方式(如GB18030或GB2312)给SpecificCharacterSet这个属性,然后再调用decode的函数,也是可以实现的。

后来通过实际测试时,发现有的片子的SpecificCharacterSet这个值的数据格式:
Value Multiplicity: 1-n, Value Representation: Code String(CS)。即这个值有可能是一个数组。因此在处理时,还需要增加数组时的判断。

实际的测试代码如下:

from pydicom.filereader import read_file

def test_decode_func():
	file_path = '/data/001.dcm'
	GB18030 = 'GB18030'
	GB_2312 = 'GB2312'
	
	dataset = read_file(file_path)
	charset = dataset.SpecificCharacterSet
	# 为了解决当dicom的某些tag值为中文时,导致解析为乱码的问题.
	if not charset:
	    dataset.SpecificCharacterSet = GB18030
	elif isinstance(charset, list):
	    for i in charset:
	        if i == GB_18030 or i.startswith(GB_2312):
	            dataset.decode()
	elif charset and (charset == GB_18030 or charset.startswith(GB_2312)):
	    dataset.decode()

3. 由这个错误想到的…

发布了188 篇原创文章 · 获赞 416 · 访问量 131万+

猜你喜欢

转载自blog.csdn.net/inter_peng/article/details/85119603