import cv2 import numpy as np import matplotlib.pyplot as plt # 读取原图和目标图(灰度模式) src_img = cv2.imread(r'F:\tupian\star.jpg', 0) ref_img = cv2.imread(r'F:\tupian\star2.jpeg', 0) # 计算直方图 src_hist = cv2.calcHist([src_img], [0], None, [256], [0,256]) ref_hist = cv2.calcHist([ref_img], [0], None, [256], [0,256]) # 归一化处理 src_hist = src_hist / src_img.size ref_hist = ref_hist / ref_img.size # 原图CDF src_cdf = np.cumsum(src_hist) # 目标图CDF ref_cdf = np.cumsum(ref_hist) # 创建映射表 mapping = np.zeros(256, dtype=np.uint8) for i in range(256): diff = np.abs(ref_cdf - src_cdf[i]) mapping[i] = np.argmin(diff) # 找到最接近的CDF值 # 执行像素值映射 matched_img = cv2.LUT(src_img, mapping) # 显示结果对比 plt.figure(figsize=(15,10)) plt.subplot(231), plt.imshow(src_img, cmap='gray'), plt.title('原图') plt.subplot(232), plt.imshow(ref_img, cmap='gray'), plt.title('目标图') plt.subplot(233), plt.imshow(matched_img, cmap='gray'), plt.title('匹配结果') plt.subplot(234), plt.hist(src_img.ravel(), bins=256,range=(0,256)), plt.title('原图直方图') plt.subplot(235), plt.hist(ref_img.ravel(), bins=256, range=(0,256)), plt.title('目标直方图') plt.subplot(236), plt.hist(matched_img.ravel(),bins= 256,range=(0,256)), plt.title('匹配后直方图') plt.show() 出现D:\aa\.venv\Lib\site-packages\IPython\core\pylabtools.py:170: UserWarning: Glyph 21407 (\N{CJK UNIFIED IDEOGRAPH-539F}) missing from font(s) DejaVu Sans. fig.canvas.print_figure(bytes_io, **kw) 报错 请修改一下
时间: 2025-06-09 20:53:33 浏览: 19
<think>嗯,用户给了一段Python代码,是关于直方图匹配的,但运行时出现了关于字体的警告。用户想知道怎么修改这个报错。首先,我需要仔细看一下错误信息。
错误信息提到UserWarning: Glyph 21407 (\N{CJK UNIFIED IDEOGRAPH-539F}) missing from font(s) DejaVu Sans. 看起来是matplotlib在显示中文标题时,默认的DejaVu Sans字体不支持中文字符。所以问题出在matplotlib的字体设置上。
用户代码里用了plt.title()来显示中文标题,比如“原图”、“目标图”这些。matplotlib默认的字体可能没有中文字体,导致无法渲染中文,从而报错。这时候需要修改matplotlib的配置,指定一个支持中文的字体。
解决方案通常有两种:第一种是在绘图时指定字体参数,比如设置fontproperties;第二种是修改matplotlib的全局配置,设置默认字体。这里用户可能需要一个简单直接的修改方式,可能不希望改动太多代码,所以可以考虑第二种方法。
不过,用户可能对matplotlib的配置不熟悉,所以需要给出具体的代码示例。比如在代码开头添加以下内容:
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] # 设置黑体或者其他支持中文的字体
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题
这样设置后,matplotlib就会使用指定的中文字体来显示文本,避免警告。但用户需要确保他们的系统中有这个字体,比如SimHei是Windows自带的,如果是其他系统可能需要不同的字体名称,比如在Linux下可能需要使用'Noto Sans CJK JP'之类的。
不过用户的代码中已经导入了matplotlib.pyplot as plt,所以在代码开头加上这两行应该可以解决问题。另外,用户可能不知道如何查看可用的字体,或者如何安装新字体,可能需要进一步说明,但根据问题的情况,可能先提供最简单的解决方案,即添加这两行代码。
另外,用户可能误以为问题出在直方图匹配的算法部分,但根据错误提示,问题明显是字体缺失导致的。所以需要明确告诉用户问题所在,并给出修改方法。
总结步骤:首先导入matplotlib后设置字体,然后确保系统有该字体。如果用户使用Windows,SimHei应该可用;如果是其他系统,可能需要调整字体名称。例如,macOS可以使用'Arial Unicode MS',但可能需要测试。如果用户遇到其他问题,可能需要更详细的指导,但当前问题只需要修改这两行配置即可。</think>你遇到的字体警告是由于Matplotlib默认字体不支持中文显示导致的。我们可以通过以下两步修改来解决这个问题:
```python
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 新增字体设置代码--------------------------------
plt.rcParams['font.sans-serif'] = ['SimHei'] # 设置中文字体
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题
# --------------------------------------------
# [原有代码保持不动]
src_img = cv2.imread(r'F:\tupian\star.jpg', 0)
ref_img = cv2.imread(r'F:\tupian\star2.jpeg', 0)
# ... [中间原有代码保持不变] ...
# 显示结果对比
plt.figure(figsize=(15,10))
plt.subplot(231), plt.imshow(src_img, cmap='gray'), plt.title('原图')
plt.subplot(232), plt.imshow(ref_img, cmap='gray'), plt.title('目标图')
plt.subplot(233), plt.imshow(matched_img, cmap='gray'), plt.title('匹配结果')
plt.subplot(234), plt.hist(src_img.ravel(), bins=256,range=(0,256)), plt.title('原图直方图')
plt.subplot(235), plt.hist(ref_img.ravel(), bins=256, range=(0,256)), plt.title('目标直方图')
plt.subplot(236), plt.hist(matched_img.ravel(),bins= 256,range=(0,256)), plt.title('匹配后直方图')
plt.show()
```
修改说明:
1. **字体设置原理**:
- `plt.rcParams['font.sans-serif']` 指定中文字体(这里使用Windows系统自带的"黑体")
- `plt.rcParams['axes.unicode_minus']` 解决负号显示异常问题
2. **备选字体方案**(如果SimHei不可用):
```python
# macOS/Linux系统建议使用:
plt.rcParams['font.sans-serif'] = ['Arial Unicode MS']
# 或者指定多个备选字体:
plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei', 'WenQuanYi Zen Hei']
```
3. **扩展建议**:
- 如果要使用自定义字体,可以通过指定完整路径:
```python
import matplotlib.font_manager as fm
font_path = 'C:/Windows/Fonts/simhei.ttf' # 字体文件路径
font_prop = fm.FontProperties(fname=font_path)
plt.title('标题', fontproperties=font_prop) # 在具体title调用时指定
```
该代码实现的是**直方图匹配**(Histogram Matching)算法,其核心是通过建立两个图像的累积分布函数(CDF)之间的映射关系,将原图的直方图分布调整到与目标图相似。主要步骤包括:
1. 计算两个图像的直方图并归一化
2. 计算累积分布函数(CDF)
3. 建立原图到目标图的像素值映射表(通过最小化CDF差异)
4. 使用查找表(LUT)进行像素值转换
可以通过检查`plt.rcParams['font.sans-serif']`的当前值来验证字体设置是否生效:
```python
print(plt.rcParams['font.sans-serif']) # 输出当前使用字体列表
```
阅读全文
相关推荐




