{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#hide\n", "#skip\n", "! [ -e /content ] && pip install -Uqq fastai # upgrade fastai on colab" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#default_exp vision.core\n", "#default_cls_lvl 3" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "from fastai.torch_basics import *\n", "from fastai.data.all import *\n", "\n", "from PIL import Image" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from fastai.data.external import *" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#hide\n", "from nbdev.showdoc import *" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "_all_ = ['Image','ToTensor']" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#It didn't use to be necessary to add ToTensor in all but we don't have the encodes methods defined here otherwise.\n", "#TODO: investigate" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Core vision\n", "> Basic image opening/processing functionality" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Helpers" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "imagenet_stats = ([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])\n", "cifar_stats = ([0.491, 0.482, 0.447], [0.247, 0.243, 0.261])\n", "mnist_stats = ([0.131], [0.308])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "im = Image.open(TEST_IMAGE).resize((30,20))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "if not hasattr(Image,'_patched'):\n", " _old_sz = Image.Image.size.fget\n", " @patch(as_prop=True)\n", " def size(x:Image.Image): return fastuple(_old_sz(x))\n", " Image._patched = True" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "@patch(as_prop=True)\n", "def n_px(x: Image.Image): return x.size[0] * x.size[1]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### `Image.n_px`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> `Image.n_px` (property)\n", "\n", "Number of pixels in image" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "test_eq(im.n_px, 30*20)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "@patch(as_prop=True)\n", "def shape(x: Image.Image): return x.size[1],x.size[0]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### `Image.shape`\n", "\n", "> `Image.shape` (property)\n", "\n", "Image (height,width) tuple (NB: opposite order of `Image.size()`, same order as numpy array and pytorch tensor)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "test_eq(im.shape, (20,30))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "@patch(as_prop=True)\n", "def aspect(x: Image.Image): return x.size[0]/x.size[1]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### `Image.aspect`\n", "\n", "> `Image.aspect` (property)\n", "\n", "Aspect ratio of the image, i.e. `width/height`" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "test_eq(im.aspect, 30/20)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "@patch\n", "def reshape(x: Image.Image, h, w, resample=0):\n", " \"`resize` `x` to `(w,h)`\"\n", " return x.resize((w,h), resample=resample)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "
Image.reshape
[source]Image.reshape
(**`x`**:`Image`, **`h`**, **`w`**, **`resample`**=*`0`*)\n",
"\n",
"`resize` `x` to `(w,h)`"
],
"text/plain": [
"Image.to_bytes_format
[source]Image.to_bytes_format
(**`im`**:`Image`, **`format`**=*`'png'`*)\n",
"\n",
"Convert to bytes, default to PNG format"
],
"text/plain": [
"Image.to_thumb
[source]Image.to_thumb
(**`h`**, **`w`**=*`None`*)\n",
"\n",
"Same as `thumbnail`, but uses a copy"
],
"text/plain": [
"Image.resize_max
[source]Image.resize_max
(**`x`**:`Image`, **`resample`**=*`0`*, **`max_px`**=*`None`*, **`max_h`**=*`None`*, **`max_w`**=*`None`*)\n",
"\n",
"`resize` `x` to `max_px`, or `max_h`, or `max_w`"
],
"text/plain": [
"