From d7384c05de386158767c6dd56ec1053cac1ad420 Mon Sep 17 00:00:00 2001 From: Carla Elena Gomez Alvarado <10-11266@usb.ve> Date: Tue, 18 May 2021 23:49:05 +0000 Subject: [PATCH] BPF --- ...samiento_digital_imagenes_bordes_BPF.ipynb | 430 ++++++++++++++++++ 1 file changed, 430 insertions(+) create mode 100644 Procesamiento_digital_imagenes_bordes_BPF.ipynb diff --git a/Procesamiento_digital_imagenes_bordes_BPF.ipynb b/Procesamiento_digital_imagenes_bordes_BPF.ipynb new file mode 100644 index 0000000..6c523d4 --- /dev/null +++ b/Procesamiento_digital_imagenes_bordes_BPF.ipynb @@ -0,0 +1,430 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import cv2\n", + "import numpy as np\n", + "from matplotlib import pyplot as plt\n", + "from PIL import Image\n", + "from PIL.ExifTags import TAGS\n", + "from numpy import asarray\n", + "from numpy.fft import fft2, fftshift, fftfreq, ifft2 #Python DFT\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#imagename = \"Data/crateres.jpg\"\n", + "#imagename = \"Data/Perseverance_ZR0_0074.png\" -codigo adicional para recorte de bordes negros.\n", + "#imagename = \"Data/mastcamz_2_prints.jpg\"\n", + "imagename = \"Data/Data_Mars_Mars8.png\"\n", + " \n", + "# read the image data using PIL\n", + "image = Image.open(imagename)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "display (image)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "crateres.jpg : Image downloaded from : https://mars.nasa.gov/mars2020-raw-images/pub/ods/surface/sol/00000/ids/edr/browse/edl/ELM_0000_0666952859_600ECM_N0000030LVS_04000_0000LUJ00_800.jpg\n", + "\n", + "Perseverance_ZR=_0074.png : Image downloaded from : " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "img = cv2.imread(imagename, 0) # load an image\n", + "\n", + "#3 = np.asarray(imagename, dtype = np.float32) # Image class instance, I1, to float32 Numpy array, a\n", + "\n", + "img_float32 = np.float32(img)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Para procesar la imagen se lee como cv2.imread y luego se le aplica la DFT \n", + "\n", + "DFT: Discrete Fourier Transform. \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "hist =cv2.calcHist([img],[0],None,[256],[0,256])\n", + "plt.plot(hist,color='blue')\n", + "plt.xlabel('Intensidad de Iluminacion')\n", + "plt.ylabel('Pixels Bins')\n", + "plt.show()\n", + "\n", + "plt.hist(np.concatenate((img),axis=0),bins=250)\n", + "plt.xlabel('Intensidad de Iluminacion')\n", + "plt.ylabel('Pixels Bins')\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#transform,ar el array de la imagen en punto flotante para ser procesado. \n", + "dft = cv2.dft(np.float32(img), flags=cv2.DFT_COMPLEX_OUTPUT)\n", + "dft_shift =np.fft.fftshift(dft)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# convert image to numpy array \n", + "data = asarray(image)\n", + "print(type(data))\n", + "# caracteristicas de la imagen\n", + "print(data.shape)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#Muestra cada valor de cada pixel de la imagen como array en Numpy\n", + "#print(data)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#imagen en el espacio de las frecuencias : \n", + "\n", + "f = np.fft.fft2(img) #fft2 para 2 dimensiones\n", + "fshift = np.fft.fftshift(f) # para centrar las frecuencias bajas.\n", + "# fft2 tiene valors imaginarios por ello se saca el espectro real o de magnitud. \n", + "magnitude_sprectrum = 20*np.log(np.abs(fshift)) " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "f.shape" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "fft2(f)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#Matplotlib para crear 2 subplots en la misma linea para comparar la imagen original y \n", + "#la imagen transformada en el espectro de frecuencias. \n", + "plt.subplot(121),plt.imshow(img , cmap = 'gray')\n", + "plt.title('Original Image'), plt.xticks([]),plt.yticks([])\n", + "plt.subplot(122),plt.imshow(magnitude_sprectrum , cmap = 'gray')\n", + "plt.title('Magnitude Spectrum'), plt.xticks([]),plt.yticks([])\n", + "plt.show\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#Filtro pasa alto HPF en el dominio de las frencuencias para demarcar contornos: \n", + "\n", + "\n", + "rows, cols = img.shape\n", + "crow, ccol = int(rows/2), int(cols/2)\n", + "\n", + "#remover las frecuencias bajas usando una plantilla circular \n", + "\n", + "mask=np.ones((rows,cols,2),np.uint8)\n", + "r = 40\n", + "center = [crow, ccol]\n", + "x, y = np.ogrid[:rows, :cols]\n", + "mask_area = (x - center[0]) ** 2 + (y - center[1]) ** 2 <= r*r\n", + "mask[mask_area] = 1\n", + "\n", + "fshift=dft_shift*mask\n", + "\n", + "fshift_mask_mag=2000*np.log(cv2.magnitude(fshift[:,:,0],fshift[:,:,1]))\n", + "\n", + "f_ishift =np.fft.ifftshift(fshift)\n", + "img_back =cv2.idft(f_ishift)\n", + "img_back =cv2.magnitude(img_back[:,:,0],img_back[:,:,1])\n", + "\n", + "#fshift[crow-30:crow+30,ccol-30:ccol+30]=0\n", + "\n", + "\n", + "f_ishift = np.fft.ifftshift(fshift)\n", + "\n", + "img_back = np.fft.ifft2(f_ishift)\n", + "\n", + "img_back = np.abs(img_back)\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#Filtro pasa Banda BPF aplicando dos circulos concentricos\n", + "\n", + "rows, cols = img.shape\n", + "crow, ccol = int(rows/2), int(cols/2) # circulo centro\n", + "\n", + "\n", + "#remover las frecuencias bajas usando una plantilla circular \n", + "\n", + "rows, cols = img.shape\n", + "crow, ccol = int(rows/2), int(cols/2)\n", + "\n", + "mask=np.zeros((rows,cols,2),np.uint8)\n", + "r_out = 40\n", + "r_in = 4\n", + "center = [crow, ccol]\n", + "x, y = np.ogrid[:rows, :cols]\n", + "\n", + "mask_area = np.logical_and(((x-center[0])**2 +(y-center[1])**2>= r_in**2),\n", + " ((x-center[0])**2 +(y-center[1])**2<= r_out**2))\n", + " \n", + " \n", + "mask[mask_area] = 1\n", + "\n", + "fshift=dft_shift*mask\n", + "\n", + "fshift_mask_mag= 2000 * np.log(cv2.magnitude(fshift[:, :, 0], fshift[:, :, 1]))\n", + "\n", + "f_ishift =np.fft.ifftshift(fshift)\n", + "img_back =cv2.idft(f_ishift)\n", + "img_back =cv2.magnitude(img_back[:,:,0],img_back[:,:,1])\n", + "\n", + "#fshift[crow-30:crow+30,ccol-30:ccol+30]=0\n", + "\n", + "fig = plt.figure(figsize=(20,20))\n", + "\n", + "fig.add_subplot(2, 2, 1), plt.imshow(img, cmap='gray')\n", + "plt.title('Input Image'), plt.xticks([]), plt.yticks([])\n", + "fig.add_subplot(2, 2, 2), plt.imshow(magnitude_sprectrum,cmap='gray')\n", + "plt.title('After FFT'), plt.xticks([]), plt.yticks([])\n", + "fig.add_subplot(2, 2, 3), plt.imshow(fshift_mask_mag, cmap='gray')\n", + "plt.title('FFT + Mask'), plt.xticks([]), plt.yticks([])\n", + "fig.add_subplot(2, 2, 4), plt.imshow(img_back, cmap='gray')\n", + "plt.title('After FFT Inverse'), plt.xticks([]), plt.yticks([])\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#Filtro pasa Banda BPF aplicando dos circulos concentricos\n", + "\n", + "rows, cols = img.shape\n", + "crow, ccol = int(rows/2), int(cols/2) # circulo centro\n", + "\n", + "\n", + "#remover las frecuencias bajas usando una plantilla circular \n", + "\n", + "rows, cols = img.shape\n", + "crow, ccol = int(rows/2), int(cols/2)\n", + "\n", + "mask=np.zeros((rows,cols,2),np.uint8)\n", + "\n", + "#con diferentes radios tal que sean mayor que la zona central, tapando la mayor cantidad de bajas frencuencias. \n", + "r_out = 80\n", + "r_in = 4\n", + "center = [crow, ccol]\n", + "x, y = np.ogrid[:rows, :cols]\n", + "\n", + "mask_area = np.logical_and(((x-center[0])**2 +(y-center[1])**2>= r_in**2),\n", + " ((x-center[0])**2 +(y-center[1])**2<= r_out**2))\n", + " \n", + " \n", + "mask[mask_area] = 1\n", + "\n", + "fshift=dft_shift*mask\n", + "\n", + "fshift_mask_mag= 2000 * np.log(cv2.magnitude(fshift[:, :, 0], fshift[:, :, 1]))\n", + "\n", + "f_ishift =np.fft.ifftshift(fshift)\n", + "img_back =cv2.idft(f_ishift)\n", + "img_back =cv2.magnitude(img_back[:,:,0],img_back[:,:,1])\n", + "\n", + "\n", + "\n", + "\n", + "fig = plt.figure(figsize=(20,20))\n", + "\n", + "fig.add_subplot(121),plt.imshow(img , cmap = 'gray')\n", + "plt.title('Original Image'), plt.xticks([]),plt.yticks([])\n", + "fig.add_subplot(122),plt.imshow(img_back , cmap = 'gray')\n", + "plt.title('AFTER FFT Inverse image'), plt.xticks([]),plt.yticks([])\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "plt.subplot(131),plt.imshow(img, cmap='gray')\n", + "plt.title('Input Image'), plt.xticks([]), plt.yticks([])\n", + "plt.subplot(132),plt.imshow(img_back , cmap = 'gray')\n", + "plt.title('Imagen con HPF'), plt.xticks([]),plt.yticks([])\n", + "plt.subplot(133),plt.imshow(img_back)\n", + "plt.title('Imagen Final'), plt.xticks([]),plt.yticks([])\n", + "plt.show" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "fig = plt.figure(figsize=(20,20))\n", + "\n", + "fig.add_subplot(121),plt.imshow(img , cmap = 'gray')\n", + "plt.title('Original Image'), plt.xticks([]),plt.yticks([])\n", + "fig.add_subplot(122),plt.imshow(img_back , cmap = 'gray')\n", + "plt.title('HPF image'), plt.xticks([]),plt.yticks([])\n", + "plt.show\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#Comparativa para la foto de las rocas \n", + "#recortado de foto \n", + "#Recortar una imagen\n", + "crop= img[200:400,200:500]\n", + "\n", + "\n", + "cv2.imshow('Seccion Imagen',crop)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#filtro Pasa bajos: LPF\n", + "\n", + "dft_shift= np.fft.fftshift(dft)\n", + "\n", + "rows, cols = img.shape\n", + "\n", + "crow , ccol = int(rows/2), int(cols/2) \n", + "\n", + "mask= np.zeros((rows,cols,2),np.uint8)\n", + "mask[crow-30:crow+30,ccol-30:ccol+30]=1\n", + "\n", + "\n", + "fshift = dft_shift*mask\n", + "f_ishift=np.fft.ifftshift(fshift)\n", + "img_back=cv2.idft(f_ishift)\n", + "img_back=cv2.magnitude(img_back[:,:,0],img_back[:,:,1])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "fig = plt.figure(figsize=(20,20))\n", + "\n", + "fig.add_subplot(121),plt.imshow(img , cmap = 'gray')\n", + "plt.title('Original Image'), plt.xticks([]),plt.yticks([])\n", + "fig.add_subplot(122),plt.imshow(img_back , cmap = 'gray')\n", + "plt.title('LPF image'), plt.xticks([]),plt.yticks([])\n", + "plt.show\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "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.7.3" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} -- GitLab