{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "%matplotlib inline" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Later shifted image\n\nIn this demo the lateral image shift is determined. \n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import numpy as np\nimport scipy\nimport scipy.misc\nimport scipy.ndimage\nimport matplotlib.pyplot as plt\nfrom numpy.typing import ArrayLike\n\n\ndef plotImage(image: ArrayLike, cmap: str=\"gray\"):\n plt.figure()\n plt.gray()\n plt.imshow(image, cmap=cmap)\n plt.show()\n\n\nif scipy.__version__ <= \"0.14.0\":\n # removed due to licensing reasons\n image = scipy.misc.lena()\nelse:\n image = scipy.misc.face()\n # Convert the image\n R = image[:, :, 0]\n G = image[:, :, 1]\n B = image[:, :, 2]\n image = R * 299. / 1000 + G * 587. / 1000 + B * 114. / 1000\n\nplotImage(image)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Amount of pixel shift in x- and y-direction\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "xPixelShift = 16\nyPixelShift = -7" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Determine the ROI size: relative (centered) size of original image (relativeSize=1: original size).\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "row, col = image.shape\nrelativeSize = np.floor(min(1 - abs(xPixelShift) / col, 1 - abs(yPixelShift) / row) * 10) / 10\n\nx0 = int((col - col * relativeSize) / 2)\nx1 = col - x0 + 1\ny0 = int((row - row * relativeSize) / 2)\ny1 = row - y0 + 1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "not shifted ROI\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "image1 = image[y0:y1, x0:x1].copy()\nplotImage(image1)\n\n# Shifted ROI\nimage2 = image[y0 + yPixelShift : y1 + yPixelShift, x0 + xPixelShift : x1 + xPixelShift].copy()\nplotImage(image2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Determine the pixel shift using discrete fast fourier transformation and complex conjugation of ``image2``.\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "image1FFT = np.fft.fft2(image1)\nimage2FFT = np.conjugate(np.fft.fft2(image2))\n\n# inverse fourier transformation of product -> equal to cross correlation\nimageCCor = np.real(np.fft.ifft2((image1FFT * image2FFT)))\n\n# Shift the zero-frequency component to the center of the spectrum\nimageCCorShift = np.fft.fftshift(imageCCor)\nplotImage(imageCCorShift, \"hot\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Determine the distance of the maximum from the center\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "row, col = image1.shape\n\nyShift, xShift = np.unravel_index(np.argmax(imageCCorShift), (row, col))\n\nyShift -= int(row / 2)\nxShift -= int(col / 2)\n\nprint(\"shift of image1 in x-direction [pixel]: \" + str(xShift))\nprint(\"shift of image1 in y-direction [pixel]: \" + str(yShift))" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.10" } }, "nbformat": 4, "nbformat_minor": 0 }