Pythonでの魚眼フィルター

目次

1. 魚眼フィルター
2. 実験:
_2.1 画像の読み込む
_2.2 魚眼フィルターの関数
_2.3 結果

 

1. 魚眼フィルター(fisheye)

魚眼フィルターとは、魚眼レンズを通して見たかのように、イメージを歪めます。結果は、樽型歪曲という、超広角の歪みのエフェクトになります。下記のような画像の加工になります。

2. 実験:

環境: google colab

入力データ:ウィキメディアの画像データ

モデル:魚眼フィルターの関数

Gil-Mor/iFish

 

Imageioのライブラリをインストールします。

!pip3 install numpy imageio

 

ライブラリをインポートします。

# 画像をロード

import urllib

import urllib.request

import sys

import fish

import imutils

from IPython.display import Image

 

fishのモジュールをインストールします。

#  Import scripts

sys.path.append(”)

py_src = “https://raw.githubusercontent.com/Gil-Mor/iFish/master/fish.py”

py_file = ‘fish.py’

urllib.request.urlretrieve(py_src, py_file)

import fish

 

2.1 画像の読み込む

# 画像をロード

img_src = “https://upload.wikimedia.org/wikipedia/commons/thumb/a/a7/Chess_board_blank.svg/472px-Chess_board_blank.svg.png”

img_file = ‘image1.png’

urllib.request.urlretrieve(img_src, img_file)

img_file = ‘image1.png’

Image(img_file)

 

2.2 魚眼フィルターの関数

 

img_file = ‘image1.png’

imgobj = imgobj = imageio.imread(img_file)

 

output_img = fish.fish(imgobj, distortion_coefficient=1)

 

outpath = ‘image2.jpg’

imageio.imwrite(outpath, output_img, format=’png’)

 

2.3 結果

img_file = ‘image2.jpg’

Image(img_file)

fish.pyのスクリプトです。

https://github.com/Gil-Mor/iFish

##fish.py

 

def get_fish_xn_yn(source_x, source_y, radius, distortion):

“””

Get normalized x, y pixel coordinates from the original image and return normalized

x, y pixel coordinates in the destination fished image.

:param distortion: Amount in which to move pixels from/to center.

As distortion grows, pixels will be moved further from the center, and vice versa.

“””

 

if 1 – distortion*(radius**2) == 0:

return source_x, source_y

 

return source_x / (1 – (distortion*(radius**2))), source_y / (1 – (distortion*(radius**2)))

 

def fish(img, distortion_coefficient):

“””

:type img: numpy.ndarray

:param distortion_coefficient: The amount of distortion to apply.

:return: numpy.ndarray – the image with applied effect.

“””

 

# If input image is only BW or RGB convert it to RGBA

# So that output ‘frame’ can be transparent.

w, h = img.shape[0], img.shape[1]

if len(img.shape) == 2:

# Duplicate the one BW channel twice to create Black and White

# RGB image (For each pixel, the 3 channels have the same value)

bw_channel = np.copy(img)

img = np.dstack((img, bw_channel))

img = np.dstack((img, bw_channel))

if len(img.shape) == 3 and img.shape[2] == 3:

print(“RGB to RGBA”)

img = np.dstack((img, np.full((w, h), 255)))

 

# prepare array for dst image

dstimg = np.zeros_like(img)

 

# floats for calcultions

w, h = float(w), float(h)

 

# easier calcultion if we traverse x, y in dst image

for x in range(len(dstimg)):

for y in range(len(dstimg[x])):

 

# normalize x and y to be in interval of [-1, 1]

xnd, ynd = float((2*x – w)/w), float((2*y – h)/h)

 

# get xn and yn distance from normalized center

rd = sqrt(xnd**2 + ynd**2)

 

# new normalized pixel coordinates

xdu, ydu = get_fish_xn_yn(xnd, ynd, rd, distortion_coefficient)

 

# convert the normalized distorted xdn and ydn back to image pixels

xu, yu = int(((xdu + 1)*w)/2), int(((ydu + 1)*h)/2)

 

# if new pixel is in bounds copy from source pixel to destination pixel

if 0 <= xu and xu < img.shape[0] and 0 <= yu and yu < img.shape[1]:

dstimg[x][y] = img[xu][yu]

 

return dstimg.astype(np.uint8)

 

def parse_args(args=sys.argv[1:]):

“””Parse arguments.”””

 

parser = argparse.ArgumentParser(

description=”Apply fish-eye effect to images.”,

prog=’python3 fish.py’)

 

parser.add_argument(“-i”, “–image”, help=”path to image file.”

” If no input is given, the supplied example ‘grid.jpg’ will be used.”,

type=str, default=”grid.jpg”)

 

parser.add_argument(“-o”, “–outpath”, help=”file path to write output to.”

” format: <path>.<format(jpg,png,etc..)>”,

type=str, default=”fish.png”)

 

parser.add_argument(“-d”, “–distortion”,

help=”The distoration coefficient. How much the move pixels from/to the center.”

” Recommended values are between -1 and 1.”

” The bigger the distortion, the further pixels will be moved outwars from the center (fisheye).”

” The Smaller the distortion, the closer pixels will be move inwards toward the center (rectilinear).”

” For example, to reverse the fisheye effect with –distoration 0.5,”

” You can run with –distortion -0.3.”

” Note that due to double processing the result will be somewhat distorted.”,

type=float, default=0.5)

 

return parser.parse_args(args)

 

if __name__ == “__main__”:

args = parse_args()

try:

imgobj = imageio.imread(args.image)

except Exception as e:

print(e)

sys.exit(1)

if os.path.exists(args.outpath):

ans = input(

args.outpath + ” exists. File will be overridden. Continue? y/n: “)

if ans.lower() != ‘y’:

print(“exiting”)

sys.exit(0)

 

 

担当者:KW
バンコクのタイ出身 データサイエンティスト
製造、マーケティング、財務、AI研究などの様々な業界にPSI生産管理、在庫予測・最適化分析、顧客ロイヤルティ分析、センチメント分析、SaaS、PaaS、IaaS、AI at the Edge の環境構築などのスペシャリスト