暔嫱 2024-02-07 20:27 采纳率: 0%
浏览 7

利用python代码对图片进行柱面投影操作,为什么投影结果是向外弯曲,而不是向内弯曲?

利用python代码对图片进行柱面投影操作,为什么投影结果是向外弯曲,而不是向内弯曲?

下图是向内弯曲的效果:

img

而我的效果是向外弯曲,并且边缘像素都被裁掉了

img


img

我的代码如下:

image_path = ‘...\1.png'
image = cv2.imread(image_path)  # BGR/(h,w,c)

def cylindrical_projection(image, f):
    height = image.shape[0]
    width = image.shape[1]

    blank = np.zeros_like(image)
    centerX = width / 2  # 图像中心横坐标
    centerY = height / 2  # 图像中心纵坐标
    alpha = math.pi / 4

    for y in range(height):
        for x in range(width):
            theta = math.atan((x - centerX) / f)
            arc_w = 2 * f * math.atan(width / (2 * f))
            pointx = int(arc_w / 2 + f * theta)
            pointy = int((f * (y - centerY)) / math.sqrt((x-centerX)**2 + f**2) + centerY)

            if pointx >= width or pointx <= 0 or pointy >= height or pointy <= 0:
                pass
            else:
                blank[y, x, :] = image[pointy, pointx, :]
    return blank

outimg = cylindrical_projection(image, 800)
  • 写回答

4条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-02-07 20:28
    关注

    引自免费微信小程序:皆我百晓生

    在柱面投影中,图像通常是从矩形平面(笛卡尔坐标系)转换到圆柱体表面,然后展开为二维图像。你提供的代码实现了一个基于中心点的柱面投影变换,但存在一些问题导致了向外弯曲的效果和边缘像素被裁剪。

    1. 几何解释

      • 你的代码通过计算每个像素点(x, y)对应的柱面上的新坐标(pointx, pointy),但由于theta = math.atan((x - centerX) / f)中的atan函数,当你从图像中心向右移动时(即x增大),theta会单调增加,从而pointx也会单调增加,这将导致图像右侧部分被拉伸并沿着垂直方向向上弯曲。
      • 同理,左侧部分会被拉伸并向下弯曲,形成“向外”的效果。
    2. 边缘像素丢失

      • 在计算新坐标的逻辑中,使用了条件判断来避免坐标越界,当新的点坐标超出原图像范围时,直接跳过了该点赋值操作,因此边缘像素没有正确映射,被裁剪掉了。
    3. 修正方法

      • 柱面投影的实现需要确保角度theta随着x轴正负方向的变化而取值在-π到π之间,并且在映射过程中对超出边界的点进行合适的处理,比如循环映射或镜像映射等,以保留所有像素信息。

    由于缺少实际图片,无法直观展示问题所在。不过,以下是修改后的示例代码,它采用了一种更标准的柱面投影方式,可能会产生向内弯曲的效果,同时尽量避免像素丢失:

    import cv2
    import numpy as np
    import math
    
    def cylindrical_projection(image, f):
        height, width, _ = image.shape
        centerX, centerY = width // 2, height // 2
        output = np.zeros_like(image)
    
        for y in range(height):
            for x in range(width):
                # 调整theta的计算以适应向内弯曲效果
                theta = (x - centerX) * 2 * math.pi / width
                rho = (y - centerY) / f
    
                # 将柱面坐标转换回直角坐标
                projected_x = int(centerX + f * np.cos(theta) * np.abs(rho))
                projected_y = int(centerY + f * np.sin(theta) * np.sign(rho))
    
                # 处理边界情况,使像素环绕映射
                if projected_x < 0:
                    projected_x += width
                elif projected_x >= width:
                    projected_x -= width
                if projected_y < 0 or projected_y >= height:
                    pass  # 或者考虑使用某种填充策略
                else:
                    output[y, x, :] = image[projected_y, projected_x, :]
    
        return output
    
    image_path = '...\1.png'
    image = cv2.imread(image_path)
    outimg = cylindrical_projection(image, 800)
    
    # 保存输出图像
    cv2.imwrite('cylindrical_projected.png', outimg)
    

    请注意,上述修正后的代码仍然可能不完全符合您的需求,因为柱面投影的具体实现方式取决于您期望的具体变形效果。您可能需要进一步调整参数和坐标映射逻辑来达到理想中的向内弯曲效果。

    评论

报告相同问题?

问题事件

  • 创建了问题 2月7日

悬赏问题

  • ¥15 远程访问linux主机超时
  • ¥15 odoo17存货管理优势于中国国内该行业传统ERP或MES的详细解读和举例
  • ¥15 CPU卡指令整合指令数据都在图片上
  • ¥15 火车票关联12306问题
  • ¥15 odoo17处理受托加工产品
  • ¥15 如何用MATLAB编码图三的积分
  • ¥15 圆孔衍射光强随孔径变化
  • ¥15 MacBook pro m3max上用vscode运行c语言没有反应
  • ¥15 ESP-PROG配置错误,ALL ONES
  • ¥15 结构功能耦合指标计算