Skip to content

Instantly share code, notes, and snippets.

@tuffacton
Created July 1, 2020 22:37
Show Gist options
  • Select an option

  • Save tuffacton/f1c4005e56e13460370db0083c6ec70c to your computer and use it in GitHub Desktop.

Select an option

Save tuffacton/f1c4005e56e13460370db0083c6ec70c to your computer and use it in GitHub Desktop.

Revisions

  1. tuffacton revised this gist Jul 1, 2020. 1 changed file with 12 additions and 1 deletion.
    13 changes: 12 additions & 1 deletion hwmk4.ipynb
    Original file line number Diff line number Diff line change
    @@ -6,14 +6,25 @@
    "name": "hwmk4",
    "provenance": [],
    "collapsed_sections": [],
    "authorship_tag": "ABX9TyNw4Jmg6kd+pTlN9PEtQ6LP"
    "authorship_tag": "ABX9TyNw4Jmg6kd+pTlN9PEtQ6LP",
    "include_colab_link": true
    },
    "kernelspec": {
    "name": "python3",
    "display_name": "Python 3"
    }
    },
    "cells": [
    {
    "cell_type": "markdown",
    "metadata": {
    "id": "view-in-github",
    "colab_type": "text"
    },
    "source": [
    "<a href=\"https://colab.research.google.com/gist/tuffacton/f1c4005e56e13460370db0083c6ec70c/hwmk4.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
    ]
    },
    {
    "cell_type": "code",
    "metadata": {
  2. tuffacton created this gist Jul 1, 2020.
    405 changes: 405 additions & 0 deletions hwmk4.ipynb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,405 @@
    {
    "nbformat": 4,
    "nbformat_minor": 0,
    "metadata": {
    "colab": {
    "name": "hwmk4",
    "provenance": [],
    "collapsed_sections": [],
    "authorship_tag": "ABX9TyNw4Jmg6kd+pTlN9PEtQ6LP"
    },
    "kernelspec": {
    "name": "python3",
    "display_name": "Python 3"
    }
    },
    "cells": [
    {
    "cell_type": "code",
    "metadata": {
    "id": "GwoxGCt04nbE",
    "colab_type": "code",
    "colab": {}
    },
    "source": [
    "import numpy as np\n",
    "import cv2\n",
    "import time\n",
    "import scipy.ndimage as ndimg\n",
    "from sklearn.cluster import KMeans\n",
    "import matplotlib.pyplot as plt\n",
    "from google.colab.patches import cv2_imshow\n",
    "from IPython.display import Image\n",
    "%matplotlib inline"
    ],
    "execution_count": 60,
    "outputs": []
    },
    {
    "cell_type": "code",
    "metadata": {
    "id": "8lDvdGDMiHmT",
    "colab_type": "code",
    "colab": {}
    },
    "source": [
    "NROT = 6\n",
    "NPER = 8\n",
    "NFILT = NROT*NPER \n",
    "FILTSIZE = 35\n",
    "NCLUSTERS = 4\n",
    "TEXELSIZE = 4\n",
    "doMakeTexels = True"
    ],
    "execution_count": 2,
    "outputs": []
    },
    {
    "cell_type": "code",
    "metadata": {
    "id": "r-oFJyHeiTzP",
    "colab_type": "code",
    "colab": {}
    },
    "source": [
    "# Source from this code as permitted in the homework directions:\n",
    "# https://github.com/tonyjo/LM_filter_bank_python/blob/master/lm.py\n",
    "\n",
    "### LM Helper Functions ###\n",
    "\n",
    "# First-Order Gaussian Definition\n",
    "def gaussian1d(sigma, mean, x, ord):\n",
    " x = np.array(x)\n",
    " x_ = x - mean\n",
    " var = sigma**2\n",
    "\n",
    " # Gaussian Function\n",
    " g1 = (1/np.sqrt(2*np.pi*var))*(np.exp((-1*x_*x_)/(2*var)))\n",
    " \n",
    " if ord == 0:\n",
    " g = g1\n",
    " return g\n",
    " elif ord == 1:\n",
    " g = -g1*((x_)/(var))\n",
    " return g\n",
    " else:\n",
    " g = g1*(((x_*x_) - var)/(var**2))\n",
    " return g\n",
    "\n",
    "# Second-Order Gaussian Definition\n",
    "def gaussian2d(sup, scales):\n",
    " var = scales * scales\n",
    " shape = (sup,sup)\n",
    " n,m = [(i - 1)/2 for i in shape]\n",
    " x,y = np.ogrid[-m:m+1,-n:n+1]\n",
    " g = (1/np.sqrt(2*np.pi*var))*np.exp( -(x*x + y*y) / (2*var) )\n",
    " return g\n",
    "\n",
    "# Gaussian and Laplacian Logarithmic Definition\n",
    "def log2d(sup, scales):\n",
    " var = scales * scales\n",
    " shape = (sup,sup)\n",
    " n,m = [(i - 1)/2 for i in shape]\n",
    " x,y = np.ogrid[-m:m+1,-n:n+1]\n",
    " g = (1/np.sqrt(2*np.pi*var))*np.exp( -(x*x + y*y) / (2*var) )\n",
    " h = g*((x*x + y*y) - var)/(var**2)\n",
    " return h\n",
    "\n",
    "# Make a singular filter\n",
    "def makefilter(scale, phasex, phasey, pts, sup):\n",
    "\n",
    " gx = gaussian1d(3*scale, 0, pts[0,...], phasex)\n",
    " gy = gaussian1d(scale, 0, pts[1,...], phasey)\n",
    "\n",
    " image = gx*gy\n",
    "\n",
    " image = np.reshape(image,(sup,sup))\n",
    " return image\n",
    "\n",
    "# This function will compute and return the Leung-Malik filters\n",
    "# The filters are in a 3D array of floats, F(FILTSIZE, FILTSIZE, NFILT)\n",
    "def makeLMfilters():\n",
    " sup = 49\n",
    " scalex = np.sqrt(2) * np.array([1,2,3])\n",
    " norient = 6\n",
    " nrotinv = 12\n",
    "\n",
    " nbar = len(scalex)*norient\n",
    " nedge = len(scalex)*norient\n",
    " nf = nbar+nedge+nrotinv\n",
    " resF = np.zeros([sup,sup,nf])\n",
    " hsup = (sup - 1)/2\n",
    "\n",
    " x = [np.arange(-hsup,hsup+1)]\n",
    " y = [np.arange(-hsup,hsup+1)]\n",
    "\n",
    " [x,y] = np.meshgrid(x,y)\n",
    "\n",
    " orgpts = [x.flatten(), y.flatten()]\n",
    " orgpts = np.array(orgpts)\n",
    " \n",
    " count = 0\n",
    " for scale in range(len(scalex)):\n",
    " for orient in range(norient):\n",
    " angle = (np.pi * orient)/norient\n",
    " c = np.cos(angle)\n",
    " s = np.sin(angle)\n",
    " rotpts = [[c+0,-s+0],[s+0,c+0]]\n",
    " rotpts = np.array(rotpts)\n",
    " rotpts = np.dot(rotpts,orgpts)\n",
    " resF[:,:,count] = makefilter(scalex[scale], 0, 1, rotpts, sup)\n",
    " resF[:,:,count+nedge] = makefilter(scalex[scale], 0, 2, rotpts, sup)\n",
    " count = count + 1\n",
    " \n",
    " count = nbar+nedge\n",
    " scales = np.sqrt(2) * np.array([1,2,3,4])\n",
    "\n",
    " for i in range(len(scales)):\n",
    " resF[:,:,count] = gaussian2d(sup, scales[i])\n",
    " count = count + 1\n",
    " \n",
    " for i in range(len(scales)):\n",
    " resF[:,:,count] = log2d(sup, scales[i])\n",
    " count = count + 1\n",
    " \n",
    " for i in range(len(scales)):\n",
    " resF[:,:,count] = log2d(sup, 3*scales[i])\n",
    " count = count + 1\n",
    " \n",
    " return resF"
    ],
    "execution_count": 3,
    "outputs": []
    },
    {
    "cell_type": "code",
    "metadata": {
    "id": "lv4AE2VSlT9q",
    "colab_type": "code",
    "colab": {}
    },
    "source": [
    "def saveFilters(img):\n",
    " (height, width, depth) = img.shape\n",
    " count = 0\n",
    " for row in range(NPER):\n",
    " for col in range(NROT):\n",
    " tempImg = img[:, :, count]\n",
    " filename = \"Filters\\\\LM_\" + str(row) + \"_\" + str(col)\n",
    " normedFilter = normImg(tempImg)\n",
    " saveImage(normedFilter, filename)\n",
    " count = count + 1\n",
    " return"
    ],
    "execution_count": 4,
    "outputs": []
    },
    {
    "cell_type": "code",
    "metadata": {
    "id": "x79t47uTlgd-",
    "colab_type": "code",
    "colab": {}
    },
    "source": [
    "# This function will apply the filter bank in the 3D array filt to\n",
    "# the inputImg; the result is an array of results res(height, width, NFILT)\n",
    "def applyLMfilters(inputImg, filt):\n",
    " img = inputImg.astype(float)\n",
    " img_y = img.shape[0]\n",
    " img_x = img.shape[1]\n",
    " num_filters = filt.shape[2]\n",
    " res = np.zeros([img_y, img_x, num_filters])\n",
    " \n",
    " for i in range(filt.shape[2]):\n",
    " r = ndimg.convolve(img, filt[:,:,i])\n",
    " res[:,:,i] = r\n",
    " return res"
    ],
    "execution_count": 5,
    "outputs": []
    },
    {
    "cell_type": "code",
    "metadata": {
    "id": "b2DvTTbVmUgY",
    "colab_type": "code",
    "colab": {}
    },
    "source": [
    "def normImg(img):\n",
    " tempImg = np.zeros_like(img)\n",
    " tempImg = (cv2.normalize(img, tempImg, 0.0, 127.0, cv2.NORM_MINMAX))\n",
    " res = (tempImg + 128.0).astype(np.uint8)\n",
    " return res"
    ],
    "execution_count": 6,
    "outputs": []
    },
    {
    "cell_type": "code",
    "metadata": {
    "id": "tbT_309gmiJY",
    "colab_type": "code",
    "colab": {}
    },
    "source": [
    "def makeMosaic(img):\n",
    " (height, width, depth) = img.shape\n",
    " res = np.zeros((height*8, width*6), np.float64)\n",
    " count = 0\n",
    " for row in range(8):\n",
    " for col in range(6):\n",
    " res[row*height:(row+1)*height, col*width:(col+1)*width] = \\\n",
    " normImg(img[:,:,count])\n",
    " count = count + 1\n",
    " return res"
    ],
    "execution_count": 7,
    "outputs": []
    },
    {
    "cell_type": "code",
    "metadata": {
    "id": "1-PpJ54FnfwC",
    "colab_type": "code",
    "colab": {}
    },
    "source": [
    "def saveImage(img, name):\n",
    " cv2.imwrite(pathName + name + \".png\", img)\n",
    " return"
    ],
    "execution_count": 8,
    "outputs": []
    },
    {
    "cell_type": "code",
    "metadata": {
    "id": "l4KC6QipnnZ8",
    "colab_type": "code",
    "colab": {}
    },
    "source": [
    "# This function will take a 3D array of filter bank responses and form texels\n",
    "# by combining the feature vectors in nonoverlapping squares of size sz\n",
    "# the result newR is an array of floats the same size as R, but within\n",
    "# texels all feature vectors are identical\n",
    "def formTexels(R, sz):\n",
    " (ROWS, COLS, PLANES) = R.shape\n",
    " newR = np.int(np.ceil(ROWS/sz))\n",
    " newC = np.int(np.ceil(COLS/sz))\n",
    " res = np.zeros((newR, newC, PLANES), dtype=np.float64)\n",
    " for row in range(0, newR):\n",
    " for col in range(0, newC, sz):\n",
    " res[row:row+sz, col:col+sz,:] = \\\n",
    " np.median(R[(sz*row):(sz*row)+sz, (sz*col):(sz*col)+sz, :], (0,1))\n",
    " return res"
    ],
    "execution_count": 9,
    "outputs": []
    },
    {
    "cell_type": "code",
    "metadata": {
    "id": "byVW4-UzoUvu",
    "colab_type": "code",
    "colab": {}
    },
    "source": [
    "# This function will take an image-sized collection of filter bank responses\n",
    "# and use the KMeans algorithm to find the best segments\n",
    "# it returns a pseucolor rendition of the original image, where each color\n",
    "# corresponds to a separate cluster (a separate type of texture)\n",
    "\n",
    "## Influenced heavily by Dr. Creed Jone's python implementation on \n",
    "## slide 20 of ECE5554 Lecture 8a - Segmentation by Clustering\n",
    "def segmentKMeans(R, nclus):\n",
    " # reshape the image to be a list of pixels\n",
    " vecs = R.reshape((R.shape[0]*R.shape[1], NFILT))\n",
    " \n",
    " # Define and fit our K-Means Model\n",
    " clus = KMeans(nclus)\n",
    " clus.fit(vecs)\n",
    "\n",
    " newfeatures = np.uint8(clus.predict(vecs))\n",
    " newAugmentedImage = newfeatures.reshape((R.shape[0], R.shape[1]))\n",
    " pcolor = cv2.applyColorMap(cv2.equalizeHist(newAugmentedImage), cv2.COLORMAP_RAINBOW)\n",
    " return pcolor"
    ],
    "execution_count": 66,
    "outputs": []
    },
    {
    "cell_type": "code",
    "metadata": {
    "id": "awcl1Juyo1EM",
    "colab_type": "code",
    "colab": {
    "base_uri": "https://localhost:8080/",
    "height": 51
    },
    "outputId": "d69e0f9a-22a9-46fa-f13a-cb256e7a87d1"
    },
    "source": [
    "####### CODE EXECUTION #######\n",
    "# Pull Images from Github\n",
    "!wget \"https://github.com/tuffacton/ece5554/raw/master/hmwk4/aerial-houses.png\" -O aerial-houses.png -q\n",
    "!wget \"https://github.com/tuffacton/ece5554/raw/master/hmwk4/texture.png\" -O texture.png -q\n",
    "!wget \"https://github.com/tuffacton/ece5554/raw/master/hmwk4/selfie.png\" -O selfie.png -q\n",
    "\n",
    "pathName = \"/content/\"\n",
    "#fileName = \"aerial-houses.png\"\n",
    "fileName = \"texture.png\"\n",
    "#fileName = \"selfie.png\"\n",
    "\n",
    "currTime = time.time()\n",
    "# Call the make filter function\n",
    "F = makeLMfilters()\n",
    "saveFilters(F)\n",
    "saveImage(makeMosaic(F), \"allFilters\")\n",
    "\n",
    "# load an image\n",
    "inputImage = cv2.cvtColor(cv2.imread(pathName+fileName), cv2.COLOR_BGR2GRAY)\n",
    "\n",
    "# find filter responses\n",
    "rawR = applyLMfilters(inputImage, F)\n",
    "R = formTexels(rawR, TEXELSIZE)\n",
    "\n",
    "filterTime = time.time() - currTime\n",
    "print(\"Filter time = \", filterTime)\n",
    "\n",
    "# try segmenting\n",
    "pcolor = segmentKMeans(R, NCLUSTERS)\n",
    "saveImage(pcolor, fileName+\"_Seg_\"+str(NCLUSTERS))\n",
    "\n",
    "elapsedTime = time.time() - currTime\n",
    "print(\"Completed; elapsed time = \", elapsedTime)"
    ],
    "execution_count": 64,
    "outputs": [
    {
    "output_type": "stream",
    "text": [
    "Filter time = 38.52336096763611\n",
    "Completed; elapsed time = 38.84861421585083\n"
    ],
    "name": "stdout"
    }
    ]
    },
    {
    "cell_type": "code",
    "metadata": {
    "id": "p8hDXtU1ofAu",
    "colab_type": "code",
    "colab": {}
    },
    "source": [
    ""
    ],
    "execution_count": null,
    "outputs": []
    }
    ]
    }