Eliminación de anomalías de la imagen

 Noisy 'Lena' image. The noise is AWGN with standard deviation 35. |  Download Scientific Diagram

 

Resumen ejecutivo
El presente documento expone la aproximación de la investigación respecto a la aplicación, detección y eliminación de anomalías en imágenes. En este caso, desde una perspectiva práctica y directa, utilizando el lenguaje de programación Python y Jupyter Notebooks.
 

El tipo de anomalía para la cual implementamos las técnicas de tratamiento es el
ruido blanco, el cual consta de una técnica aleatoria de aplicación de píxeles
blancos sobre las imágenes. Y para su eliminación implementamos la técnica de
aplicación de media.

Introducción
El ruido en una imagen es la alteración arbitraria de sus valores en brillo y color que
distorsiona la percepción visual de la misma. Esto puede ocurrir en distintos niveles,
desde un leve ‘polvo’, ‘rayado’, ‘oscilado’ u otro efecto de daño el cual puede dejar
irreconocible el concepto que la imagen proyectaba originalmente.
Las técnicas de eliminación de anomalías, en este sentido, pretenden corregir el
ruido que se presente en dichas imágenes con apoyo de tecnología digital.
 

Implementación
La implementación de la solución incorpora dos funciones generales: agregar_ruido
y medianizar_imagen. La función de agregar_ruido aplica ruido blanco
aleatoriamente en la imagen procesada, y la función medianizar_imagen aplica la
media en bloques de 3x3 píxeles para intentar eliminar el efecto del ruido. Los otros
bloques de código consumen estas funciones para generar la salida en imágenes.

Librería

Descripción de uso

Random

Acceso a funciones aleatorias para aplicación de ruido

cv2

Acceso a funciones propias para tratamiento de imágenes

numpy

Acceso a funciones y tipos de datos para manipular arreglos

matplotlib

Proyección -ploteo- de resultados

Tab. 1) Librerías utilizadas en la solución 

Código


 import random   
 import cv2   
 import numpy as np  
 from matplotlib import pyplot as plt  
 import os  
 #Función de ruido blanco  
 #en esta función aplicamos aleatoriamente pixeles blancos  
 #sobre toda la superficie de la imagen. Esto lo definimos como "ruido".  
 def agregar_ruido(img, cant_pixels):  
   #Obtenemos las dimensiones de la imagen  
   row , col = img.shape  
   #Aplicamos el ruido -blanco- a la cantidad de pixels deseada  
   for i in range(cant_pixels):      
     # Elegimos una coordenada al azar en Y  
     y_coord=random.randint(0, row - 1)       
     # Elegimos una coordenada al azar en X  
     x_coord=random.randint(0, col - 1)       
     # Aplicamos el ruido en la posición encontrada  
     img[y_coord][x_coord] = 255  
   return img  
 #Función en la que aplicamos la media a la imagen  
 #para difuminar defectos o anomalías  
 def medianizar_imagen(img_conruido):  
   #Obtenemos la composición de la imagen  
   #interpretada en un array de renglones y columnas  
   row, col = img_conruido.shape  
   #Se recorre la imágen, para cada area de 3x3  
   #buscamos la media en pixels y se reemplaza el pixel   
   #central con la media.  
   img_nueva = np.zeros([row, col])  
   for i in range(1, row-1):  
     for j in range(1, col-1):  
       temp = [img_conruido[i-1, j-1],  
           img_conruido[i-1, j],  
           img_conruido[i-1, j + 1],  
           img_conruido[i, j-1],  
           img_conruido[i, j],  
           img_conruido[i, j + 1],  
           img_conruido[i + 1, j-1],  
           img_conruido[i + 1, j],  
           img_conruido[i + 1, j + 1]]  
       temp = sorted(temp)  
       img_nueva[i, j]= temp[4]  
   return img_nueva.astype(np.uint8)  
 #Sección de manejo de imágenes  
 #Utilizamos variables auxiliares para almacenar los valores de las imágenes  
 #desde la inicial original, continuamos por la adición de ruido pasando a escala  
 #de grises y medianizamos. El filtro salt-and-pepper solo puede aplicarse a  
 #imagenes en escala de grises, por ello primero transformamos la imagen.  
 img = cv2.imread('diente.jpg')  
 imgGray = cv2.imread('diente.jpg', cv2.IMREAD_GRAYSCALE)   
 cv2.imwrite('noise.jpg', agregar_ruido(imgGray,3000))  
 imgRuido = cv2.imread('noise.jpg', 0)   
 imgMedian = medianizar_imagen(imgRuido)  
 #Imprimimos la comparativa con matplotlib  
 #En este caso nos apoyamos con cv2.cvtColor especificando que estamos usando  
 #escala de grises para proyectar de nuevo la imagen  
 plt.figure(figsize=(18,18))  
 plt.subplot(231),plt.imshow(img),plt.title('Original')  
 plt.xticks([]), plt.yticks([])  
 plt.subplot(232),plt.imshow(cv2.cvtColor(imgRuido, cv2.IMREAD_GRAYSCALE)),plt.title('Ruido')  
 plt.xticks([]), plt.yticks([])  
 plt.subplot(233),plt.imshow(cv2.cvtColor(imgMedian, cv2.IMREAD_GRAYSCALE)),plt.title('Medianizado')  
 plt.xticks([]), plt.yticks([])  
 plt.show()  


Principales conclusiones
La aplicación de media para la eliminación de este tipo de anomalía en imágenes ha resultado ser suficientemente efectiva, pero debemos tener siempre en cuenta que el resultado final es una imagen totalmente distinta a lo que hubiera sido su original. Por esto diferentes técnicas de eliminación podrían ayudar a asimilar más el efecto de un original que la presente en casos de fotografías más detalladas o con mayores dimensiones, lo cual también implica mayor capacidad de procesamiento para abarcar todo el lienzo de la imagen. 



Fig. 1) Proyección de resultados en original, con ruido y aplicada la media




Referencias y bibliografía
 
Median Filter Implementation In Python. (2018, 13 abril). Code Review Stack Exchange. Recuperado 22 de enero de 2022, de https://codereview.stackexchange.com/questions/191974/median-filter-implementation-in-python


GeeksforGeeks. (2021, 27 octubre). Add a «salt and pepper» noise to an image with Python. Recuperado 22 de enero de 2022, de https://www.geeksforgeeks.org/add-a-salt-and-pepper-noise-to-an-image-with-python/


Technologies, I., & Technologies, M. P. B. I. (2019, 26 junio). Image Processing Series #3 : Noise Removal From Image Using Python OpenCV – Instrovate. Instrovate Technologies. Recuperado 22 de enero de 2022, de https://instrovate.com/2019/06/26/image-processing-series-3-noise-removal-from-image-using-python-opencv/


GeeksforGeeks. (2021b, noviembre 9). Spatial Filters - Averaging filter and Median filter in Image Processing. Recuperado 22 de enero de 2022, de https://www.geeksforgeeks.org/spatial-filters-averaging-filter-and-median-filter-in-image-processing/




La 1ª. Declaración de Derechos Humanos en el Ciberespacio

 

 4ª Generación DD HH | DERECHOS HUMANOS

 El presente post es inspirado por algunos sitios que sobreviven como piezas de museo de geocities, al rededor del 2006 cuando aún era algo aventurado crear un sitio web propio y existían comunidades de "hackers" que buscaban explotar la capacidad de las telecomunicaciones vía internet. Algunos nos reuníamos en salas de chat durante horas y era emocionante ver cuando aparecía un "nick" de algún conocido de forma espontánea.

En ese entonces existía cierto espíritu de comunidad que a algunos nos impulsaba a compartir la mayor cantidad de conocimiento informático en lo que respecta a sistemas, código, scripts, y programas ejecutables hechos en casa: desde bromas que manipulaban los puertos I/O del ordenador afectado, clientes de chat, hacks de messenger, hasta peligrosos virus informáticos. El leer esta primera declaración de derechos humanos en el ciberespacio, la cual data de aquella época, me hace revivir aquel sentimiento, aunque para la época actual muchos de estos artículos suenen cuestionables.

No podíamos imaginar la forma en la cual el acceso a la red transformaría nuestras vidas y la forma en la cual nos comunicamos. Mucho menos podíamos haber imaginado que en algún momento todas las personas de todos los perfiles se conectarían.

En aquel entonces la mayoría de personas que nos conectábamos gozábamos de cierto ritual: obstruir el teléfono de casa en ciertos horarios para curiosear por la red, hacer amistades y compartir conocimientos. Los más afortunados: quienes tenían acceso como dueños o empleados de un ciber en el cual podían experimentar con multitud de equipos y después compartir sus resultados.

 

 Extractos de la 1ª. Declaración de Derechos Humanos en el Ciberespacio

Artículo 1º:
Las ideas y opiniones de todos los seres humanos merecen una oportunidad igual para poder expresarse, considerarse y compartirse con otras, según la voluntad del emisor o el receptor, voluntariamente.


Artículo 2º:
Todas las personas tienes sus derechos y libertades expuestos en esta declaración, sin distinciones de ningún tipo, tales como la raza, el color, la lengua, las opiniones políticas o de otro tipo, el origen social o nacional, el estatus económico, el nacimiento o de otra clase. Además no se realizará ninguna distinción a base de jurisdicciones políticas o físicas, o del método de acceso a la red.


Artículo 3º:

Toda persona tiene derecho a la privacidad, anonimato y seguridad, en las transacciones de la línea.


Artículo 4º:

No se obligará a la revelación de información personal por parte de los proveedores de servicios ni por los sitios, y cuando sea requerida deberá realizarse con el consentimiento informado de la persona afectada.


Artículo 5º:

Nadie debe ser sometido, sin acuerdo previo a envíos masivos de correo electrónico no solicitado, de archivos vinculados u otras correspondencias masivas.


Artículo 6º:

Todas las personas tienen derecho a preservar la intimidad de sus datos de carácter personal que revelen la ideología, religión creencias, salud, origen racial, estatus social o vida sexual. Y a revelarlos cuando consideren o estipulen necesario.
En ningún momento pueden ser publicados o utilizados por terceras personas sin autorización previa y consciente del afectado. Así mismo se protegen la privacidad de los datos relativos a los menores de edad, independientemente de la autorización previa de los mismos.

 

Referencias:

SUÑÉ LLINÁS, Emilio. DECLARACIÓN DE DERECHOS DEL CIBERESPACIO, Universidad Complutense de Madrid. Madrid España. 2008, pp.15 y ss.

Conectarse por XRDP a LUbuntu desde Mac

 

Conectarse por XRDP a LUbuntu desde Mac

 XRDP es una implementación gratuita y de código abierto del servidor Microsoft RDP que permite que los sistemas operativos distintos de Microsoft Windows proporcionen una experiencia de escritorio remoto compatible con RDP completamente funcional. Resulta bastante útil cuando tenemos escenarios en los que la revisión por medio de interfaz gráfica sea más ágil que la terminal de comandos. Aunque muchos preferimos tratar nuestros servicios remotos por SSH es un hecho que en algún punto, por algún motivo, necesitaremos acceder a la interfaz gráfica, y para evitarnos el traslado en físico está XRDP.

 En el caso de LUbuntu no basta con simplementa instalar XRDP para lograr una conexión exitosa, en un caso por default en LUbuntu 18.04 LTS al lograr la conexión no hay transmisión de gráficos, es decir, nos quedamos con una pantalla en negro sin poder interactuar.

Para configurar una conexión remota con interfaz gráfica a LUbuntu utilizando el servicio XRDP desde Mac hay que seguir los siguientes pasos:

  • Instalar xrdp server:
    sudo apt install xrdp
    sudo systemctl enable xrdp

  • En el archivo /etc/xrdp/startwm.sh, comentaremos (#) las últimas dos líneas, y añadiremos la siguiente:
    lxsession -s Lubuntu -e LXDE

    Vista de como queda la configuración de xrdp en lubuntu

  • Finalmente reiniciamos xrdp:
    sudo /etc/init.d/xrdp restart

El cliente que utilizamos en esta ocasión es Microsoft Remote Desktop desde Mac (Gratuito). Agregamos la conexión de forma normal a la IP, en el caso de ser necesario, configura también el gateway según tu configuración de red.



❣️Fuente(s): https://lasplo.hu/xrdp-on-lubuntu-without-black-srceen/



Iniciar MacMini con Linux después de fallo de energía

Rain Showers Bring Lightning and Ruined Computers - Yellowstone Computing

Una Mac Mini no se reiniciará automáticamente después de un corte de energía sin la configuración correcta.  

Típicamente MacOS tiene la opción de alternar esta opción (en Preferencias del sistema> Ahorro de energía> "Iniciar automáticamente después de un corte de energía").

A bajo nivel, esta opción establece un registro en el controlador de administración de energía (generalmente el Southbridge que actúa como host de la Interfaz de energía y configuración avanzada (ACPI). MacOS establece este registro después de cada arranque, ya que la configuración no es persistente entre los reinicios
. 

Al utilizar Linux en una Mac no tenemos esta opción visible, y tampoco la podemos alterar desde BIOS.  Por lo tanto, debemos encontrar el tipo de southbridge en la Mac y crear un script de inicio que establezca el bit correcto en el registro de su dispositivo para detonar el autoarranque y persistirlo entre reinicios.

 

 1. Encontrar el Southbridge 

Utilizaremos lspci para encontrar el Southbridge de la mac:

 lspci   


Es probable que la salida contenga uno de los siguientes:

Para un Mac Mini de principios de 2006 / MacMini1,1 / A1176:

 00:1f.0 ISA bridge: Intel Corporation 82801GBM (ICH7-M) LPC Interface Bridge (rev 02)  


Para un Mac Mini de principios de 2009 / MacMini3,1 / A1283:
 00:03.0 ISA bridge: NVIDIA Corporation MCP79 LPC Bridge (rev b2) 


Para un Mac Mini de principios de 2010 / MacMini4,1 / A1347:
 00:03.0 ISA bridge: NVIDIA Corporation MCP89 LPC Bridge (rev a2)


Para un Mac Mini Server 2011:
 00:1f.0 ISA bridge: Intel Corporation HM65 Express Chipset Family LPC Controller (rev 05)
 

 2. Configurar los registros 

 Ahora que sabemos qué hardware tenemos, el siguiente paso es encontrar qué registro determina qué modo (apagado, suspensión, encendido) se elige después de un corte de energía. 

Esto es menos trivial de lo que parece. La documentación del Southbridge es difícil de encontrar y, para los que se encuentran disponibles, no es particularmente legible.  

Afortunadamente, otros ya han determinado el registro correcto para algunos de los Southbridge.

Para PPC Mac Mini: 

 echo server_mode=1 > /proc/pmu/options

Para Mac Mini con
Southbridge Intel ICH7:
 sudo setpci -s 0:1f.0 0xa4.b=0

Para Mac Mini con nVidia MCP79
Southbridge (probablemente también funcionará en MCP89):
 sudo setpci -s 00:03.0 0x7b.b=0x19


3. Configuración de bits en lugar de bytes  

Ten en cuenta que los códigos anteriores establecen todo el byte del registro.
P.ej.
setpci -s 0: 1f.0 0xa4.b = 0 establece los 8 bits de 0xa4 en 00000000. En realidad, solo nos preocupamos por establecer el primer bit en 0 y no nos importan los últimos 7 bits. El código adecuado para hacer esto es: setpci -s 0: 1f.0 0xa4.b = 0: 1. Esto solo establecerá el bit cero en cero (0 = valor: 1 = máscara).

Si deseas verificar el valor existente de los registros, usa el argumento lspci -vvvxxx, así: lspci -vvvxxx -s 00: 03.0

 

4. Script de inicio

Recuerda que estos registros deben configurarse después de cada arranque.


En nuestro caso generaremos primero un archivo shell (.sh) ejecutable que contenga: 

restart_service.sh

#!/bin/sh
setpci -s 0:1f.0 0xa4.b=0

Y nuestro servicio de arranque se configurará de forma:

reboot_on_power_failure.service

 [Unit]  
 Description=Reboot after power failure  
 [Service]  
 Type=oneshot  
 ExecStart=/home/euclides/restart_service.sh  
 [Install]  
 WantedBy=sysinit.target  
 #Use lspci to find the southbridge in your Mac.   
 #Reboot register for Mac Mini with nVidia ISA bridge  
 #For PPC Mac Mini  
 #echo server_mode=1 > /proc/pmu/options  
 #For Mac Mini with Intel ICH7 south-bridge:  
 #sudo setpci -s 0:1f.0 0xa4.b=0  
 #For Mac Mini with nVidia MCP79 south-bridge:  
 #sudo setpci -s 00:03.0 0x7b.b=0x19  

 

Conservo mediante comentarios la configuración adicional en mi servicio en caso de que deba cambiarla por el tipo de mac mini donde la instale ;)

 Finalmente ejecutamos enable --now reboot_on_power_failure.service

 Y listo tendremos nuestro daemon service a prueba de fallos de energía en nuestra Mac Mini con Linux.


 

💙Fuente: http://www.macfreek.nl/ 

Conciencia Artificial (I)

The nature of consciousness | Wall Street International Magazine

La conciencia artificial o conciencia de la máquina es un campo relacionado con la robótica cognitiva que tiene como objetivo probar diferentes tipos de enfoques filosóficos relacionados con el estudio de la conciencia.

La conciencia en sí misma ha sido un tema de estudio y debate a lo largo de los siglos. Diferentes ramas de la ciencia y la filosofía han estado luchando por determinar dónde se origina la conciencia y qué características deben considerarse para llamar a un ser 'consciente'.

Uno de los más interesantes es el concepto de "awareness" que es un concepto en inglés que conforma la conciencia. La conciencia como una característica de un ser consciente es la capacidad de ser consciente de sí mismo en ciertos criterios (conciencia de agencia, conciencia de objetivo y conciencia sensoriomotora). En el cerebro ubicamos esta característica como una frecuencia medible (Alfa y Beta) (1). En cuanto a las ondas delta (0 a 3 Hrtz) son incompatibles con funciones conscientes como el aprendizaje o la memoria. Las cosas inanimadas no pueden tener conciencia, porque sólo los seres conscientes pueden ser inconscientes. (2)

Neuropsicología de la conciencia


La conciencia y todos los demás fenómenos mentales son el resultado de una serie de reacciones neurobiológicas dentro del cerebro. Cada estímulo externo o interno tiene que ser procesado dentro del cerebro en forma de sinapsis y estructuras neuronales para convertirse en parte de nuestra experiencia-conciencia viva. En este punto dejaremos claro que a la fecha no existe una teoría científica aprobada de dónde se origina la conciencia o cuáles son las características base del concepto, sino muchos enfoques que intentan explicar los fenómenos de la misma. Lo que está claro es qué tipos de seres son y no son seres conscientes y a qué nivel aproximado.

 Joynes (1990) señala la posibilidad de la existencia de un género humano capaz de hablar, juzgar, razonar e incluso capaz de resolver problemas con la falta de conciencia.


Inteligencia artificial y conciencia


 Podemos considerar una entidad como consciente si posee algún tipo de sistema de percepción de alto nivel que le permita supervisar los estados y procesos cognitivos de dicha entidad. Los procesos de supervisión pueden incluir: creencias, recuerdos, deseos, necesidades, metas, miedos y mucho más.

Armstrong (1968) indica que los procesos son conscientes si la entidad crea la creencia de tenerlo como resultado de la supervisión de primera mano en lugar de como reflejo de su propia conducta.

Nava-Rivera (2001) afirma que la inteligencia artificial deberá abordar la autopercepción para construir un yo capaz de autopercepción.

El juego de la vida: una hipótesis para continuar


The Game of Life es un autómata celular diseñado por el matemático británico John Horton Conway en 1970. Consiste en un mecanismo independiente, una vez iniciada su ejecución el juego se desarrollará por sí solo dependiendo de su estado inicial. No requiere mayor interacción. Los elementos del juego son 'células' que 'nacen' y 'mueren' dependiendo de unidades de tiempo discretas que pueden considerarse turnos. Están actualizando siguiendo estas reglas:

🔘Una célula muerta con exactamente 3 células vecinas vivas "nace" (es decir, en el próximo turno estará viva).
🔘Una célula viva con 2 o 3 células vecinas vivas sigue viva, de lo contrario muere (por "soledad" o "superpoblación").

El Juego de la Vida podría ser un experimento potencial para agregar mecanismos de conciencia de forma pasiva, no tanto como la visión por computadora o la robótica, sino más bien de una manera filosófico-matemática agregando mecanismos de IA para recolectar información de cada 'turno' en el juego y el computadora en sí (calor, nivel de potencia, hilos en ejecución) podríamos tener un experimento mínimo de un ser consciente básico.
 
 
 

1) Brain Waves - an overview | ScienceDirect Topics. (s. f.). Sciencedirect. Recovered 30 of july 2021, from https://www.sciencedirect.com/topics/agricultural-and-biological-sciences/brain-waves

 2)  Nava-Rivera, A. (2001). Neuropsicología de la conciencia (1.a ed., Vol. 1). Programa de Psicofisiología, Facultad de Psicología. U.N.A.M.

3) Armstrong, D.M. (1968). A Material Theory of Mind. Londres Routlidge Kijan Paul.  

4) Joynes, J. (1990) The origin of Consciousness of the bicameral Mind 2nd Ed. Boston Hougton Miffin.

 

Daemons de unix y casos prácticos con NetCore

How to make a UNIX/Linux 'daemon' - GIGAZINE

Menos que dioses (Sistema operativo, Kernel) pero más como mortales (programas), los Daemons de Unix, mal llamados demonios en español, son procesos/servicios en segundo plano que no requieren de interacción directa del usuario de sistema para ejecutarse, es decir no requieren indicaciones desde ninguna interfaz ni terminal. 

Los Daemons nos sirven cuando necesitamos un proceso recurrente que trabaje en silencio en nuestro ordenador. 

Algunos ejemplos prácticos podrían ser crear un programa que nos envíe un recordatorio o alerta de algún tema en específico cada tanto tiempo, o algo mas complejo como replicar datos locales de una base de datos a otra.

De igual forma podemos configurar los Daemons para que se ejecuten al arranque de sistema incluyéndolos en systemd.

Los Daemons trabajan a nivel sistema operativo, pudiendo ejecutar cualquier tipo de programa o instrucción que deseemos. En el presente caso utilizaremos NetCore para generar breves ejemplos.

NetCore es lo mejor de Microsoft para Linux, en el tiempo que lo he utilizado me ha parecido un esquema muy agradable para trabajar.

Para todo esto tendremos que haber configurado nuestro ordenador para poder ejecutar entornos NetCore.

 

1. Generar el programa  

Abrimos Visual Studio y el tipo de proyecto que elegiremos para crear es "Aplicación de Consola", verificando que tenga la opción de compatibilidad con Linux:

 Fig. 1) Proyecto a elegir en Visual Studio (Aplicación de consola multiplataforma)

En nuestro programa principal (Program.cs) tendremos una sencilla función cuyo propósito será escribir en un archivo al estilo log:

     private static void WriteLog(string msg)  
     {  
       Console.WriteLine(msg);  
         System.IO.Directory.CreateDirectory("/home/euclides/Replicator/Logs");  
         string strFile = "/home/euclides/Replicator/Logs/ReplicaLog-" + DateTime.Now.Date.ToString("dd-MM-yyyy") + ".txt";  
         bool fileExists = File.Exists(strFile);  
         if (fileExists)  
         {  
           using (StreamWriter sw = new StreamWriter(File.Open(strFile, FileMode.Append)))  
           {  
             sw.WriteLine(msg);  
           }  
         }  
         else  
         {  
           using (StreamWriter sw = new StreamWriter(File.Open(strFile, FileMode.OpenOrCreate)))  
           {  
             sw.WriteLine(msg);  
           }  
         }  
     }  



De igual forma añadiremos un temporizador para controlar los tiempos en los cuales se ejecute nuestra función:

     private Timer _tmEscritura = null;  
     private AutoResetEvent _autoEvent = null;  
     private void StartTimer()  
     {  
       try  
       {  
         WriteLog("Configurando temporizador");  
         //dueTime muestra cuando se realizará la primera ejecución (1000 MS),  
         //period es después de ello cada cuanto tiempo (timespan.fromminutes)  
         _autoEvent = new AutoResetEvent(true);  
         _tmEscritura = new Timer(WriteLog("La hora es: " + DateTime.Now.ToString()), _autoEvent, 1000, (int)TimeSpan.FromMinutes(5).TotalMilliseconds);  
         WriteLog("Fin de configuracion de temporizador");  
         while (true) ; //Instrucción para que prevalezca en ejecución  
       }  
       catch (Exception ex)  
       {  
         WriteLog("ERROR DE EJECUCIÓN: " + ex.Message);  
       }  
     }  



Finalmente, nuestro hilo principal quedaría así con el temporizador:


     private static void Main(string[] args)  
     {  
       WriteLog("INICIO DE EJECUCIÓN");  
       Program p = new Program();  
       p.StartTimer();  
     }  



Una vez hecho esto compilamos en Release, y publicamos con compatibilidad Linux. Lo cargamos por FTP al directorio que deseemos y le damos permisos de escritura, lectura y ejecución.



2. Crear el Daemon

Para crear el Daemon escribiremos un archivo de texto con extensión .service en el cual indicaremos la ubicación de nuestro programa ejecutable y la descripción del mismo, así como el nombre mediante el cual lo identificaremos y el usuario o grupo de usuarios que tienen permiso de manipularlo.

 [Unit]  
 Description=Programa de escritura de logs de hora con temporizador  
 [Service]  
 # systemd will run this executable to start the service  
 ExecStart=/home/euclides/WriteLog/WriteLog  
 # to query logs using journalctl, set a logical name here  
 SyslogIdentifier=WriteLog  
 # Use your username to keep things simple.  
 # If you pick a different user, make sure dotnet and all permissions are set correctly to run the app  
 # To update permissions, use 'chown yourusername -R /srv/HelloWorld' to take ownership of the folder and files,  
 #    Use 'chmod +x /srv/HelloWorld/HelloWorld' to allow execution of the executable file  
 User=euclides 
 [Install]  
 WantedBy=multi-user.target  


Este archivo deberá almacenarse en la ruta /etc/systemd/system/ 

Los últimos pasos para tener nuestro Daemon en ejecución son recargar la pila de daemons y habilitarlo al arranque del sistema operativo mediante los siguientes comandos:


 //Recarga la pila de daemons  
 sudo systemctl daemon-reload  
 //Habilita la ejecución al arranque del sistema   
 sudo systemctl enable WriteLog.service  
 //Inicia el daemon  
 sudo systemctl start WriteLog.service  


Listo, hemos creado un Daemon de Unix en NetCore con un temporizador y función para escritura de archivos al estilo log.


Patrones de diseño: Singleton + Ejemplos en C#

Que son los patrones de diseño


Los patrones de diseño formalmente resultan ser una solución a problemas propensos a tratarse de forma similar. Es decir, que una solución fija les puede calzar. No es obligatorio utilizar un patrón de diseño para resolver una problemática dada, pero en algunos casos resulta ser lo más sensato ya que acorta el tiempo o los recursos necesarios para ejecutar la solución deseada.


Singleton

Singleton es un patrón que garantiza la existencia de una instancia única para determinada clase, es decir, que en memoria no existirá otra del mismo tipo hasta que la primera haya finalizado su ejecución. Esto nos ayuda cuando no deseamos permitir a nuestros usuarios ejecutar más de una vez el mismo programa.

Utilizando singleton restringimos el numero de instancias del mismo tipo en memoria activas a solo una. 

Ejemplo en C#

 Singleton tradicional

En el siguiente ejemplo generamos un candado para conocer el estatus de la ejecución y creamos formalmente la clase singleton para detectar y obtener el estatus de la instancia.

 public sealed class Singleton  
 {  
   private static volatile Singleton instance;  
   private static object syncRoot = new Object();  
   private Singleton()  
   {  
     System.Windows.Forms.MessageBox.Show("Nuevo Singleton");  
   }  
   public static Singleton GetInstance  
   {  
     get  
     {  
       if (instance == null)  
       {  
         lock(syncRoot)  
         {  
           if (instance == null)  
           instance = new Singleton();  
         }  
       }  
       return instance;  
     }  
   }  
 }  

 

 Validación en memoria mediante Mutex

En este caso modificamos la clase Program.cs de una solución de Winforms en visual studio. Mediante la clase Mutex buscamos si ya existe en memoria una instancia del mismo programa y denegamos una nueva ejecución

     [STAThread]  
     private static void Main()  
     {  
       bool instanceCountOne = false;  
       using (Mutex mtex = new Mutex(true, "Mi Programa", out instanceCountOne))  
       {  
         if (instanceCountOne)  
         {  
           Application.EnableVisualStyles();  
           Application.SetCompatibleTextRenderingDefault(false);  
           Application.Run(new FrmPrincipal());  
         }  
         else  
         {  
           MessageBox.Show("Ya se está ejecutando.", "Mi Programa");  
         }  
       }  
     }  

 

Conclusión

Hemos visto dos formas de implementar un mecanismo singleton en C# así como su utilidad básica: solo permitir una instancia de la misma clase.

Clonezilla y GParted - Respaldando y restaurando en ISO tu sistema LINUX

CloneZilla Live: clona tu disco o partición de forma gratuita 

Clonezilla es un software libre de recuperación de una imagen creada de un sistema operativo, tiene diversas funcionalidades como crear una imagen del sistema o eliminarla o por ejemplo eliminar una partición. Clonezilla está diseñado por Steven Shaiu y desarrollado por el NCHC Labs en Taiwán.

En el presente artículo veremos cómo realizar un respaldo completo de sistema en formato ISO y restaurarlo en otro ordenador con la ayuda de Clonezilla. 

En nuestro caso las características de cada ordenador fueron las siguientes:

Origen:  Acer Laptop Aspire E1-432-C622 1Tb HDD Intel Celeron
Destino: MacMini 2010 Intel Core2Duo 300Gb HDD

S/O: LUbuntu con servicios instalados (Apache Server, MySQL)

Herramientas:

Descargar Clonezilla

Descargar GParted

Descargar LiLi - LinuxLive

Para realizar el respaldo en ISO del S/O de origen es necesario utilizar 2 memorias USB: la primera para albergar la herramienta Clonezilla y otra para almacenar el ISO - clon de la instalación.

Como podrán observar en las características de los discos duros destaca la diferencia en tamaño de origen (1Tb) y destino (300Gb). Es importante mencionar que Clonezilla no puede determinar por si mismo, a partir de la diferencia en tamaños, que espacio se está utilizando o no. Por esto hay que apoyarnos con Gparted para reparticionar y liberar el espacio que no se encuentre en uso. Clonezilla solamente puede restaurar cuando la capacidad del disco duro de destino es igual o mayor al tamaño de las particiones respaldadas.

Paso 0: Crear Live USB - GParted
Una vez descargado el ISO de GParted, abrimos LiLi e instalamos la herramienta en una USB.

Paso 0.1: Reparticionar
Este paso es importante cuando el disco de origen es de mayor capacidad al de destino. De no realizarlo no será posible restaurar la copia de seguridad, nos dará el error: "destination disk is too small" y por mas que intentemos configurar la restauración en modo avanzado esta no será satisfactoria.

How to resize a partition on Windows 10 using GParted • Pureinfotech

Fig. 1) Disminuyendo el tamaño de la partición con GParted

Una vez que hemos iniciado nuestro ordenador con el Live USB que preparamos con GParted elegimos la partición a la cual reduciremos su tamaño. El tamaño que se presenta está en MiB. En nuestro caso lo redujimos a 100000MiB (104.8Gb) de un original de 886917MiB (929.9Gb) en nuestra partición. Esto nos dejará con ~120Gb y el resto como espacio libre - not allocated en nuestro ISO clon por lo cual podremos indicarle posteriormente a Clonezilla que ajuste los tamaños como disponga respetando la información que si se encuentra almacenada.

Paso 1: Crear Live USB - Clonezilla
Una vez descargado el ISO de Clonezilla, abrimos LiLi e instalamos la herramienta en una USB.

Paso 1.1: Preparar USB para ISO de Respaldo de Origen
Realizar un formato simple en el USB donde almacenaremos nuestro respaldo.

Paso 2: Generar ISO - Clon de Origen
Arrancamos con el Live USB de Clonezilla en el ordenador de origen. Yo configuré la herramienta con las opciones de idioma por defecto (Inglés). Una vez hecho esto las opciones a utilizar para generar el clon son las siguientes:

disk_to_local_disk: Disco local(HDD) a disco local (USB).
save_disk: Guardar disco local como imagen.
Elegir disco de destino (USB) y origen (HDD), dar nombre al archivo.

Continuar con Beginner Mode y las opciones por defecto. Si tu información no es demasiada este proceso podría ser breve.

Paso 3: Restaurar ISO en Destino

Arrancamos con el Live USB de Clonezilla en el ordenador de destino. Las opciones a utilizar son las siguientes:

disk_to_local_disk: Disco local(HDD) a disco local (USB).

restoredisk: Restaurar imagen a disco local.

Elegir disco dónde se encuentra el clon (USB) y destino (HDD)

Importante: Elegir Expert Mode al restaurar.

En expert mode es necesario configurar dos cosas: activar -icds en el menú múltiple y elegir -k1 en el de opciones siguientes, las siguientes configuraciones son opcionales. Con -icds indicamos que no deseamos que Clonezilla revise los tamaños y con -k1 que los ajuste dinamicamente. Este proceso fallará si no reducimos el tamaño reparticionando como en el paso 0.1.


¡Listo! Hemos creado y restaurado un clon completo de sistema.

:)