如何让plt.imshow显示负坐标区域的变换后图像
图像变换后负坐标区域无法显示的解决方法
问题说明
我正在用线性代数方法拼接两张图像成全景图,其中一张图像经变换后大部分内容处于小于0的坐标区域,导致plt.imshow无法显示这部分内容。想知道能不能扩展绘图范围展示负坐标区域,或者整体右移图像来呈现更多内容?试过expand和origin参数,但没成功。代码如下:
from PIL import Image import matplotlib.pyplot as plt import numpy as np img1 = Image.open("gwint1.png") coeffs=np.array([0.207879489,0.1122809023,496.629559,-0.341172122,0.908759060,53.1000028,-0.000964805704,0.000223378490]).reshape(4,2) plt.imshow(img1.transform((width,height),Image.PERSPECTIVE, coeffs, fill=0, fillcolor='black'),alpha=1);
三种可行解决方案
方案一:调整Matplotlib坐标轴范围,直接显示负坐标区域
plt.imshow默认只展示(0,0)到输出图像尺寸的坐标范围,你可以手动设置坐标轴的显示边界,把负坐标区域包含进来:
from PIL import Image import matplotlib.pyplot as plt import numpy as np img1 = Image.open("gwint1.png") width, height = img1.size # 补全原代码中缺失的尺寸定义 coeffs=np.array([0.207879489,0.1122809023,496.629559,-0.341172122,0.908759060,53.1000028,-0.000964805704,0.000223378490]).reshape(4,2) # 生成变换后的图像 transformed_img = img1.transform((width, height), Image.PERSPECTIVE, coeffs, fill=0, fillcolor='black') plt.imshow(transformed_img, alpha=1) # 根据你图像的实际负坐标范围调整数值,比如这里假设x最小到-500,y最小到-200 plt.xlim(-500, width) plt.ylim(-200, height) plt.show()
方案二:修改变换矩阵,整体偏移图像到正坐标区域(推荐用于全景拼接)
先计算图像变换后的边界,然后修改透视变换矩阵,把整个图像平移到正坐标区域,这样后续拼接更方便:
from PIL import Image import matplotlib.pyplot as plt import numpy as np img1 = Image.open("gwint1.png") width, height = img1.size coeffs = np.array([0.207879489, 0.1122809023, 496.629559, -0.341172122, 0.908759060, 53.1000028, -0.000964805704, 0.000223378490]).reshape(4, 2) # 定义函数计算单个点的透视变换结果 def transform_point(point, coeffs): x, y = point a, b, c = coeffs[0], coeffs[1], coeffs[2] d, e, f = coeffs[3], coeffs[4], coeffs[5] g, h = coeffs[6], coeffs[7] denom = g * x + h * y + 1 return (a*x + b*y + c)/denom, (d*x + e*y + f)/denom # 计算原图像四个角变换后的坐标 corners = [(0,0), (width,0), (width,height), (0,height)] transformed_corners = [transform_point(p, coeffs) for p in corners] # 找到变换后最小的x和y值,计算需要偏移的量 min_x = min(p[0] for p in transformed_corners) min_y = min(p[1] for p in transformed_corners) offset_x = -min_x offset_y = -min_y # 修改变换矩阵的常数项,实现平移 new_coeffs = coeffs.copy() new_coeffs[2] += offset_x # 调整x方向的平移参数 new_coeffs[5] += offset_y # 调整y方向的平移参数 # 计算新的输出尺寸,确保容纳整个图像 max_x = max(p[0] for p in transformed_corners) + offset_x max_y = max(p[1] for p in transformed_corners) + offset_y new_width = int(np.ceil(max_x)) new_height = int(np.ceil(max_y)) # 应用新变换 transformed_img = img1.transform((new_width, new_height), Image.PERSPECTIVE, new_coeffs, fill=0, fillcolor='black') plt.imshow(transformed_img, alpha=1) plt.show()
方案三:正确使用PIL的expand参数
你之前可能没正确用对expand参数,设置expand=True后,PIL会自动扩展输出图像尺寸,容纳变换后的全部内容:
from PIL import Image import matplotlib.pyplot as plt import numpy as np img1 = Image.open("gwint1.png") width, height = img1.size coeffs=np.array([0.207879489,0.1122809023,496.629559,-0.341172122,0.908759060,53.1000028,-0.000964805704,0.000223378490]).reshape(4,2) # 添加expand=True参数,自动扩展图像尺寸 transformed_img = img1.transform((width, height), Image.PERSPECTIVE, coeffs, fill=0, fillcolor='black', expand=True) plt.imshow(transformed_img, alpha=1) plt.show()
内容的提问来源于stack exchange,提问作者Tymoteusz Dziejma
相关产品推荐
相关产品推荐

