【摄影】如何矫正Olympus 9mm F8 Fisheye

前言

奥林巴斯9mm F8鱼眼镜头是一个很有趣的玩具镜头,其小巧的体积,搭配不错的中心画质,成为M43相机中的最强镜头盖。

鱼眼效果虽然有趣,在一些情况下我们还是想要一个标准的广角画面,因此对画面进行矫正就成为“一鱼两吃”的好选择。

但是由于这枚镜头没有触点,因此我们在松下机身拍摄之后,只能通过电脑对照片进行后处理。问题来了,LR中没有该镜头的对应配置文件,该如何矫正图片?

这里结合互联网信息,提供三种解决方式:

1、LR中采用适马镜头配置文件。

2、使用开源软件——Hugin。

3、采用一个日本摄影师提供的Python脚本。

以上方案都可以高效解决矫正问题,得到不错的成片。

方法一:LR中采用适马镜头配置文件

采用适马10mm F2.8 EX DC FISHEYE的矫正文件,可以取得不错的矫正效果。

要注意此操作需要在LR中进行,Ps的Camera Raw插件里的镜头矫正文件不全,效果会有问题。

方法二:开源软件Hugin

步骤:

(1)安装Hugin,打开需要矫正的图片。

(2)选择全帧鱼眼,9mm,2x倍率。

(3)在全景缝合中使用直线预测,先进界面下对输出内容进行优化,导出即可。

方法三:Python脚本自动矫正

该方法来自一个日本摄影师,我在python3.13下进行了一些调整,目前该代码创建一个GUI,可以实现拖动图片到GUI自动运行。

存在的问题:边角畸变矫正还是存在一些问题,可以对一些数值进行调整,实现更好的畸变矫正结果。

import numpy as np
import cv2
from PIL import Image
import piexif
import tkinter as tk
from tkinterdnd2 import DND_FILES, TkinterDnD

def process_image(file_path):
    # 定数
    scale = 0.95
    fsave = file_path.replace(".JPG", "_1.JPG").replace(".jpg", "_1.jpg")
    
    # 画像を開く
    image = Image.open(file_path)
    img = np.array(image, dtype=np.uint8)
    h, w = img.shape[:2]
    
    # 収差補正(Greenを拡大)
    green = cv2.resize(img[:,:,1], None, fx=1.0005, fy=1.0005, interpolation=cv2.INTER_CUBIC)
    difx = (green.shape[1] - w) // 2
    dify = (green.shape[0] - h) // 2
    img[:,:,1] = green[dify:dify+h, difx:difx+w]
    
    # 周辺減光補正
    size = max([h, w])  # 幅、高の大きい方を確保
    x = np.linspace(-w/size, w/size, w)
    y = np.linspace(-h/size, h/size, h)  # 長い方の辺が1になるように正規化
    xx, yy = np.meshgrid(x, y)
    r = np.sqrt(xx**2 + yy**2) 
    gain = 0.4 * r + 1   # 減光補正パラメータ(固定値)
    gainmap = np.dstack([gain, gain, gain])    # RGB同じゲイン
    img = np.clip(img * gainmap, 0., 255).astype(np.uint8)
    
    # 歪み補正
    f = max([h, w])
    mtx = np.array([[f,    0.,  w / 2],
                    [0.,   f,   h / 2],
                    [0.,   0.,  1    ]])
    
    # 歪み補正パラメータ(固定値) 
    dist = np.array([-0.63, -0.2, 0, 0, 0.8])
    
    n_mtx = cv2.getOptimalNewCameraMatrix(mtx, dist, (img.shape[1], img.shape[0]), 1)[0]
    map = cv2.initUndistortRectifyMap(mtx, dist, np.eye(3), n_mtx, (img.shape[1], img.shape[0]), cv2.CV_32FC1)
    
    # 拡大+shift
    mapx = map[0] * scale + (1 - scale) * w / 2
    mapy = map[1] * scale + (1 - scale) * h / 2
    img = cv2.remap(img, mapx, mapy, cv2.INTER_CUBIC)
    
    # 4:3 -> 3:2比率への変換 (高さを 8/9する)
    strt_y = h * 1 // 18
    end_y = h * 17 // 18
    img = img[strt_y:end_y, :, :]
    
    # Exif付与
    exif_dict = piexif.load(file_path)
    exif_dict["0th"][piexif.ImageIFD.ImageWidth]  = img.shape[1]
    exif_dict["0th"][piexif.ImageIFD.ImageLength] = img.shape[0]
    
    exif_dict["Exif"][piexif.ExifIFD.FocalLength] = (90, 10)
    exif_dict["Exif"][piexif.ExifIFD.FNumber] = (80, 10)
    exif_dict["Exif"][piexif.ExifIFD.FocalLengthIn35mmFilm] = 18
    exif_dict["Exif"][piexif.ExifIFD.PixelXDimension] = img.shape[1]
    exif_dict["Exif"][piexif.ExifIFD.PixelYDimension] = img.shape[0]
    
    exif_bytes = piexif.dump(exif_dict)
    
    # 保存
    im = Image.fromarray(img)
    im.save(fsave, "JPEG", exif=exif_bytes)

    # 显示保存路径和 EXIF 信息
    print(f"图像处理完成,文件已保存到: {fsave}")

    # 提取并显示特定 EXIF 信息
    exif_info = exif_dict["Exif"]
    aperture = exif_info.get(piexif.ExifIFD.FNumber, "未知")
    shutter_speed = exif_info.get(piexif.ExifIFD.ExposureTime, "未知")
    iso = exif_info.get(piexif.ExifIFD.ISOSpeedRatings, "未知")

    print("\n照片的主要 EXIF 信息:")
    print(f"光圈 (Aperture): {aperture}")
    print(f"快门速度 (Shutter Speed): {shutter_speed}")
    print(f"感光度 (ISO): {iso}")

def drop(event):
    file_paths = event.data.strip('{}').split()  # 处理多个文件
    for file_path in file_paths:
        process_image(file_path)

# 创建主窗口
root = TkinterDnD.Tk()
root.title("图片处理")
root.geometry("400x200")

# 提示信息
label = tk.Label(root, text="将图片拖放到这里进行处理", padx=10, pady=10)
label.pack(expand=True, fill=tk.BOTH)

# 注册拖放事件
root.drop_target_register(DND_FILES)
root.dnd_bind('<<Drop>>', drop)

# 启动 Tkinter 主循环
root.mainloop()

【施工中、、、】

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注