当前位置:   article > 正文

OpenCV中读取中文路径、窗口命名中文、图片加中文乱码问题汇总

opencv 中文乱码

点击上方码农的后花园”,选择星标” 公众号

精选文章,第一时间送达

问题一:  

当我们在PyCharm环境,使用OpenCV的cv2.imread(filename)方法读取图像,发现imread无法读取中文文件,只能识别英文文件,就算执行成功也不会输出结果。

当图像保存文件夹filename 中的路径或者图像文件名包含汉字的时候,cv2.imread(filename)读取不到图像数据,导致后续一系列对读取的图像进行操作都会无法进行,报错。而我们需要支持读入中文文件,输出中文文件。

  1. #1.解决opencv读取中文路径报错的问题
  2. file_path1 = "D:\Project\Monet_traffic\图片\哈儿.jpg"
  3. image = cv2.imread(filename=file_path1)
  4. print(Image.shape[0]) # 报错
  5. cv2.imshow("1",image) #报错


原因分析: opencv的所有Python版本,cv2.imread(filename)方法都不支持中文路径的文件读入,所以说图像根本没有读到,所以无法对图像进行任何操作。

解决办法:使用OpenCV的cv2.imdecode(buf, flags)方法。

  1. file_path1 = "D:\Project\Monet_traffic\图片\哈儿.jpg"
  2. image = cv2.imread(filename=file_path1)
  3. # # print(Image.shape[0]) # 报错
  4. # cv2.imshow("1",image) #报错
  5. #读取图像,解决imread不能读取中文路径路径的问题
  6. def cv_imread(file_path):
  7. #imdedcode读取的是RGB图像
  8. cv_img = cv2.imdecode(np.fromfile(file_path,dtype=np.uint8),-1)
  9. return cv_img
  10. image = cv_imread(file_path1)
  11. print("图像的高度:",image.shape[0],"图像的宽度:",image.shape[1])
  12. cv2.imshow("image", image)

  1. # #2.输出中文文件,解决输出中文文件乱码的问题
  2. # # image1为图片对象,filepath为输出图片路径
  3. # file_path2 = "D:\Project\Monet_traffic\图片\苏菲.png"
  4. # cv2.imwrite(filename=file_path2,img=image) #执行成功,但是图片未保存成功到本地
  5. # cv2.imencode('.png', image)[1].tofile(file_path2) #执行保存成功

问题二:  

当我们使用cv2.namedWindow或者cv2.imshow显示图像窗口,将窗口显示为中文时,会出现乱码现象。

  1. cv2.namedWindow(winname="image", flags=cv2.WINDOW_AUTOSIZE) # 或者数字0
  2. # cv2.resizeWindow("window", 480, 320) #设置图片显示窗口大小
  3. # 读入图片
  4. image_path = r"D:\Project\Monet_traffic\data\photo\3.jpg"
  5. image = cv2.imread(image_path)
  6. print(image.shape) # 图片大小
  7. print(type(image))
  8. # 改变图片大小,fx代表对图片的长进行缩放尺寸系数
  9. # image = cv2.resize(image,None,fx=0.5,fy=0.5)
  10. # 显示图片:窗口名,显示图片
  11. # cv2.imshow(‘窗口标题’,image),如果前面没有cv2.namedWindow,自动先执行一个cv2.namedWindow()
  12. cv2.imshow(winname='image', mat=image)


解决办法:

  1. #读入图片
  2. image = cv2.imread(r"D:\Project\Monet_traffic\data\photo\3.jpg")
  3. #编码格式转换
  4. def zh_ch(string):
  5. return string.encode("gbk").decode('UTF-8', errors='ignore')
  6. cv2.namedWindow(winname=zh_ch('图片'))
  7. cv2.imshow(zh_ch('图片'), image)
  8. cv2.waitKey(0)


原因分析:因为namedWindow和imshow的窗口名采用gbk编码,而Python3默认UTF-8编码,所以应该将中文转成gbk编码的格式。但是这样转换并不完美,大部分中文都不能转换,无法显示,建议还是使用英文命名窗口

从根本上解决这一问题,目前有两种方案:

①改用Python 2版本,代码改为 cv.imshow(u'绘图', img),字符串前加u

②改用C++开发环境

问题三:  

在图片或者视频中添加中文汉字,在OpenCV添加文字的方法putText()时,添加英文没有问题,但是如果添加中文就会出现"???"的乱码现象

  1. cv2.namedWindow(winname="image", flags=cv2.WINDOW_AUTOSIZE) # 或者数字0
  2. # cv2.resizeWindow("window", 480, 320) #设置图片显示窗口大小
  3. # 读入图片
  4. image_path = r"D:\Project\Monet_traffic\data\photo\3.jpg"
  5. image = cv2.imread(image_path)
  6. print(image.shape) # 图片大小
  7. print(type(image))
  8. # 改变图片大小,fx代表对图片的长进行缩放尺寸系数
  9. # image = cv2.resize(image,None,fx=0.5,fy=0.5)
  10. # 显示图片:窗口名,显示图片
  11. # cv2.imshow(‘窗口标题’,image),如果前面没有cv2.namedWindow,自动先执行一个cv2.namedWindow()
  12. cv2.imshow(winname='image', mat=image)
  13. # 图片上画框
  14. cv2.rectangle(img=image, pt1=(285, 40), pt2=(350, 120), color=(0, 255, 0), thickness=2)
  15. # 图片上添加文字
  16. cv2.putText(img=image,text="哈儿", org=(275 , 60), fontFace=cv2.FONT_HERSHEY_PLAIN, fontScale=2.5, color=(0, 0, 255), thickness =2)
  17. cv2.imshow(winname='image', mat=image


PS1:OpenCV中putText方法支持的文字字体有:

原因分析:opencv在视频中通过putText函数能添加文字,但对于中文则无能为力,主要是因为编码问题。

解决办法:Python中将OpenCV格式的numpy.ndarray图片,转换成PIL格式的'PIL.Image.Image图片,使用PIL的图片绘制中文,PIL格式的图片可以指定字体文件,也就是说可以使用PIL实现中文的输出。

步骤:

  1. OpenCV图片格式转换成PIL的图片格式

  2. 使用PIL的ImageDraw.Draw.text绘制添加文字

  3. 将添加完文字的PIL格式图片转换为OpenCV格式图片进行展示

  1. cv2.namedWindow(winname="image", flags=cv2.WINDOW_AUTOSIZE) # 或者数字0
  2. # cv2.resizeWindow("window", 480, 320) #设置图片显示窗口大小
  3. # 读入图片
  4. image_path = r"D:\Project\Monet_traffic\data\photo\3.jpg"
  5. image = cv2.imread(image_path)
  6. print(image.shape) # 图片大小
  7. print(type(image))
  8. # 改变图片大小,fx代表对图片的长进行缩放尺寸系数
  9. # image = cv2.resize(image,None,fx=0.5,fy=0.5)
  10. # 显示图片:窗口名,显示图片
  11. # cv2.imshow(‘窗口标题’,image),如果前面没有cv2.namedWindow,自动先执行一个cv2.namedWindow()
  12. cv2.imshow(winname='image', mat=image)
  13. # 图片上画框
  14. cv2.rectangle(img=image, pt1=(285, 40), pt2=(350, 120), color=(0, 255, 0), thickness=2)
  15. # 添加中文
  16. # 转换为PIL的image图片格式,使用PIL绘制文字,再转换为OpenCV的图片格式
  17. def image_add_text(img1, text, left, top, text_color, text_size):
  18. # 判断图片是否为ndarray格式,转为成PIL的格式的RGB图片
  19. if isinstance(img1, np.ndarray):
  20. image = Image.fromarray(cv2.cvtColor(img1, cv2.COLOR_BGR2RGB))
  21. print(type(image))
  22. # 创建一个可以在给定图像上绘图的对象
  23. draw = ImageDraw.Draw(image)
  24. # 参数依次为 字体、字体大小、编码
  25. font_style = ImageFont.truetype("font/simsun.ttc", text_size, encoding='utf-8')
  26. # 参数依次为位置、文本、颜色、字体
  27. draw.text((left, top), text, text_color, font=font_style)
  28. return cv2.cvtColor(np.asarray(image), cv2.COLOR_RGB2BGR)
  29. image = image_add_text(image, "哈儿", 225, 50, (255, 0, 0), 40)
  30. cv2.imshow(winname='image', mat=image)

视频流中添加中文文字:

  1. # 转换为PIL的image图片格式,使用PIL绘制文字,再转换为OpenCV的图片格式
  2. def image_add_text(img1, text, left, top, text_color, text_size):
  3. # 判断图片是否为ndarray格式,转为成PIL的格式的RGB图片
  4. if isinstance(img1, np.ndarray):
  5. image = Image.fromarray(cv2.cvtColor(img1, cv2.COLOR_BGR2RGB))
  6. print(type(image))
  7. # 创建一个可以在给定图像上绘图的对象
  8. draw = ImageDraw.Draw(image)
  9. # 参数依次为 字体、字体大小、编码
  10. font_style = ImageFont.truetype("font/simsun.ttc", text_size, encoding='utf-8')
  11. # 参数依次为位置、文本、颜色、字体
  12. draw.text((left, top), text, text_color, font=font_style)
  13. return cv2.cvtColor(np.asarray(image), cv2.COLOR_RGB2BGR)
  14. video_path = r'D:\Project\Monet_traffic\data\video\test.mp4'
  15. capture = cv2.VideoCapture(video_path)
  16. # 判断VideoCaputre对象是否成功打开
  17. if capture.isOpened():
  18. print('已经打开了视频文件')
  19. while (True):
  20. fps = capture.get(cv2.CAP_PROP_FPS) # 返回视频的fps--帧率
  21. width = capture.get(cv2.CAP_PROP_FRAME_WIDTH) # 返回视频的宽
  22. height = capture.get(cv2.CAP_PROP_FRAME_HEIGHT) # 返回视频的高
  23. print('fps:', fps, 'width:', width, 'height:', height)
  24. # 检测图片的起始时间
  25. t1 = time.time()
  26. # 读取某一帧
  27. ret, frame = capture.read() # 如果正确读取帧,ret为True,否则ret为false
  28. if not ret:
  29. print("Can't receive frame (stream end?). Exiting ...")
  30. else:
  31. frame = image_add_text(frame, "哈儿", 225, 50, (255, 0, 0), 40)
  32. # 检测图片的结束时间
  33. t2 = time.time()
  34. fps = (fps + (1. / (t2 - t1))) / 2
  35. cv2.putText(img=frame, text=str(fps), org=(275, 60), fontFace=cv2.FONT_HERSHEY_PLAIN,fontScale=1.5, color=(0, 0, 255),thickness=2)
  36. cv2.imshow("frame", frame)
  37. if cv2.waitKey(1) & 0xff == ord('q'): # waitKey(0):
  38. break
  39. # 释放对象
  40. capture.release()
  41. cv2.destroyAllWindows()
  42. else:
  43. print('视频文件打开失败')

PS2: 推荐一个RGB和字体下载的网站

RGB 对应的颜色可以使用 https://www.sioe.cn/yingyong/yanse-rgb-16/进行查看。 

字体下载可以使用http://www.font5.com.cn/font_download.php?id=150&part=1237886897下载使用。

代码下载和环境设置

完整论文以及代码下载,后台回复关键字:OpenCV,即可获取数据集和源代码。

                                                     分享给更多朋友,转发,点赞,在看

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/代码探险家/article/detail/857783
推荐阅读
相关标签
  

闽ICP备14008679号