sábado, 29 de diciembre de 2018

DEMOSTRACION DE COLORES RGB


EXTRACTOR DE CANALES RGB




Este es un programa para extraer los canales RGB de una imagen. El prorgama genera las imagenes de cada canal y las guarda como imagenes de mapa de bits (.bmp) además genera las matrices de intensidad de color y los guarda como  archivos separados por coma (.csv).


Este programa fué probado en windows 7 con python 3.7
Para correrlo debe tener instaladas las librerías conocidas como pil y wxpython.

Copie el código fuente mostrado más abajo

Si le interesa saber más sobre adquisición de imagenes digitales, visite mi otro post: 

ADQUISICION DE UNA IAGEN DIGITAL


Aplicacion: Carga la imagen y genera los resultados mostrados
 
Puede usar mi otro programa para convertir el script de python en ejecutable y poder usar el ejecutable en otras máquinas sin tener que instalar de nuevo python y todas las demás dependencias:
 

from PIL import Image
import wx
import os

class MainFrame(wx.Frame):   
    def __init__(self, parent, title ="Extractor"):
        super().__init__(parent, title = title , size = (500,130))
        self.locale = wx.Locale(wx.LANGUAGE_ENGLISH) # Arreglar el error de locale
        self.SetMinSize(size = (500,130))            # Tamaño minimo de la ventana
        # ----------------------------------
        #             VARIABLES
        #-----------------------------------
        self.ImageDir = ""
        self.SaveDir  = ""
        self.currentDirectory = os.getcwd()
        # ----------------------------------
        #             WIDGETS
        #-----------------------------------
        MainPanel  = wx.Panel(self)
        
        BtnOpenImg = wx.Button(MainPanel, wx.ID_ANY, 'Abrir Img', wx.DefaultPosition)
        self.TxtDirOpen = wx.TextCtrl(MainPanel, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
        self.TxtDirOpen.SetEditable(False)
        SizrSlecImg = wx.BoxSizer(wx.HORIZONTAL)
        SizrSlecImg.Add(BtnOpenImg,     0, wx.ALL,2)
        SizrSlecImg.Add(self.TxtDirOpen,1, wx.ALL,2)

        BtnSaveDir = wx.Button(MainPanel, wx.ID_ANY, 'Guardar en', wx.DefaultPosition)
        self.TxtDirSave = wx.TextCtrl(MainPanel, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
        self.TxtDirSave.SetEditable(False)
        SizSaveDir = wx.BoxSizer(wx.HORIZONTAL)
        SizSaveDir.Add(BtnSaveDir,     0, wx.ALL,2)
        SizSaveDir.Add(self.TxtDirSave,1, wx.ALL,2)
        
        
        BtnProcesar = wx.Button(MainPanel, wx.ID_ANY, 'Procesar', wx.DefaultPosition)
        #-----------------------------------
        #             BINDS
        #-----------------------------------
        BtnOpenImg .Bind(wx.EVT_BUTTON, self.SelecIMG,BtnOpenImg )
        BtnProcesar.Bind(wx.EVT_BUTTON, self.procesar,BtnProcesar)
        BtnSaveDir .Bind(wx.EVT_BUTTON, self.savedir, BtnSaveDir )
        #-----------------------------------
        #             LAYOUT
        #-----------------------------------
        MainSizer   = wx.BoxSizer(wx.VERTICAL)
        
        MainSizer.Add(SizrSlecImg,0, wx.ALL|wx.EXPAND)
        MainSizer.Add(SizSaveDir, 0, wx.ALL|wx.EXPAND)
        MainSizer.Add(BtnProcesar,0, wx.ALL|wx.EXPAND)
        MainPanel.SetSizer(MainSizer)
        MainPanel.Layout()

    def SelecIMG(self, event):
        wildcard = "jpg, png, tiff o bmp|*.jpg;*.png;*.tiff;*.bmp"

        dlg = wx.FileDialog(
            self, message="Abrir archivo de imagen",
            defaultDir=self.currentDirectory, 
            defaultFile="",
            wildcard=wildcard,
            style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)

        if dlg.ShowModal() == wx.ID_OK:
            self.ImageDir = dlg.GetPath()
            self.TxtDirOpen.SetValue(self.ImageDir)
        dlg.Destroy()

    def savedir(self, event):
        dlg = wx.DirDialog(self, "Elija el directorio:",
                           style=wx.DD_DEFAULT_STYLE)
        if dlg.ShowModal() == wx.ID_OK:
            self.SaveDir = dlg.GetPath()
            self.TxtDirSave.SetValue(self.SaveDir)
        dlg.Destroy()
    
    def procesar(self, event):
        #-----------------------------------
        #     COMPROBAR CAMPOS REQUERIDOS
        #-----------------------------------
        continuar = True
        mensajes = ''
        if self.ImageDir == '':
            continuar = False
            mensajes+= '* No ha elegido la imagen.\n'
        if self.SaveDir == '':
            continuar = False
            mensajes+= '* No ha elegido donde guardar los archivos resultantes.\n'
        #-----------------------------------
        if continuar == True:
            #-----------------------------------
            #         GENERAR ARCHIVOS
            #-----------------------------------
            try:
                self.ExtraerCnal('R')
                self.ExtraerCnal('G')
                self.ExtraerCnal('B')
                self.ExtraerCnalenIMG('R')
                self.ExtraerCnalenIMG('G')
                self.ExtraerCnalenIMG('B')
            except:
                mensaje = 'Ocurrieron errores al crearlos archivos\n'\
                          'la imagen podría estar dañada.'
                wx.MessageBox(message=mensaje,
                        caption='Aviso', style=wx.OK | wx.ICON_INFORMATION)     
        else:
            wx.MessageBox(message = mensajes,
                        caption='Aviso', style=wx.OK | wx.ICON_INFORMATION)
    
    def ExtraerCnal (self, color):
        im = Image.open(self.ImageDir) # Puede ser jpg, png, tiff, gif
        pix = im.load()
        size = im.size  # Obtener el manaño de la imagen para iterar
        #print(size)
        filename = ''
        chanel = 0
        if color == 'R':
            filename = self.SaveDir+'\Rojo.csv'
            chanel = 0
        if color == 'G':
            filename = self.SaveDir+'\Verde.csv'
            chanel = 1
        if color == 'B':
            filename = self.SaveDir+'\Azul.csv'
            chanel = 2  
        file = open(filename,"w")
        Line = ""
        for x in range(size[1]):
            if Line != '':
                file.write(Line+"\n")
                #print(Line) # esta linea es para debugear
                Line = ""
            for y in range(size[0]):
                Line +=  str(pix[y,x][chanel])+','  # 0 = R, 1 = G, 2 = B 
        file.close() 
        print('TERMINADO')


    def ExtraerCnalenIMG (self, color):
        im = Image.open(self.ImageDir) # Puede ser jpg, png, tiff, gif
        pix = im.load()
        size = im.size  # Obtener el manaño de la imagen para iterar
        #print(size)
        filename = ''
        chanel = 0
        if color == 'R':
            filename = self.SaveDir+'\Rojo.bmp'
            chanel = 0
        if color == 'G':
            filename = self.SaveDir+'\Verde.bmp'
            chanel = 1
        if color == 'B':
            filename = self.SaveDir+'\Azul.bmp'
            chanel = 2 
        for x in range(size[1]):
            for y in range(size[0]):
                extrColor = pix[y,x][chanel]  # 0 = R, 1 = G, 2 = B
                if color == 'R':
                    newcolor = (extrColor,0,0)
                if color == 'G':
                    newcolor = (0,extrColor,0)
                if color == 'B':
                    newcolor = (0,0,extrColor)
                pix[y,x]  = newcolor
        im.save(filename)
        print('TERMINADO')

app = wx.App(0)
frame = MainFrame(None)
app.SetTopWindow(frame)
frame.Show()
app.MainLoop()

VISOR DE PIXELES RGB

Este otro programa muestra cada color de pixel en una cuadricula. Tal como se vería cada LED RGB si estuviésemos muy cerca del monitor. Se distingue la imagen original al alejarse del monitor. Se recomienda cargar imágenes pequeñas (menos de 200 X 200 pixeles) para que no tarde demasiado.


Copie el código fuente mostrado más abajo y corralo en el IDE de python (IDLE)

Puede usar estas imágenes que re-dimensione para este ejemplo.





#!/usr/bin/env python3
#-*- coding: utf-8 -*-
#------------------------------------------------------
#  Desarrollado por: Carlos Alberto Rodriguez Martinez
#  http://mecatroncharly.blogspot.com/
#
#  Este es un Demuestra la composicion de colores RGB
#------------------------------------------------------
import wx
import os
import wx.grid as gridlib
from PIL import Image

class MyForm(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, parent=None, title="Visor de pixeles RGB")
        # ----------------------------------
        #             VARIABLES
        #-----------------------------------
        self.ImageDir = ""
        self.currentDirectory = os.getcwd()
        self.image   = None
        self.Pixels  = None
        self.ImgSize = None
        # ----------------------------------
        #             GUI
        #-----------------------------------
        MainPanel = wx.Panel(self)

        BtnProcesar = wx.Button(MainPanel, wx.ID_ANY, 'Procesar', wx.DefaultPosition)

        BtnOpenImg = wx.Button(MainPanel, wx.ID_ANY, 'Abrir Img', wx.DefaultPosition)
        self.TxtDirOpen = wx.TextCtrl(MainPanel, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
        self.TxtDirOpen.SetEditable(False)
        SizrSlecImg = wx.BoxSizer(wx.HORIZONTAL)
        SizrSlecImg.Add(BtnOpenImg,     0, wx.ALL,2)
        SizrSlecImg.Add(self.TxtDirOpen,1, wx.ALL,2)

        self.ChkBxGrdLnes = wx.CheckBox(MainPanel, label = 'Mostrar lineas en la cuadricula')
        self.ChkBxGrdLnes.SetValue(True)
 
        self.MyGrid = gridlib.Grid(MainPanel)
        self.MyGrid.CreateGrid(0, 0)

        self.MyGrid.SetRowLabelSize(0) # hide the rows
        self.MyGrid.SetColLabelSize(0) # hide the columns
        #-----------------------------------
        #             BINDS
        #-----------------------------------
        BtnOpenImg       .Bind(wx.EVT_BUTTON, self.SelecIMG,BtnOpenImg )
        BtnProcesar      .Bind(wx.EVT_BUTTON, self.procesar,BtnProcesar)
        self.ChkBxGrdLnes.Bind(wx.EVT_CHECKBOX,self.onShowLines) 
        #-----------------------------------
        #             LAYOUT
        #-----------------------------------
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(SizrSlecImg,      0, wx.EXPAND|wx.ALL,5)
        sizer.Add(self.ChkBxGrdLnes,0, wx.EXPAND|wx.ALL,5)
        sizer.Add(BtnProcesar,      0, wx.EXPAND|wx.ALL,5)
        sizer.Add(self.MyGrid,      1, wx.EXPAND|wx.ALL,5)
        MainPanel.SetSizer(sizer)

        infoTxt = 'Cargue imagenes pequeñas no más ' \
                  'de 200 X 200 pixeles. De lo contrario' \
                  'el programa podria demorarse o bloquearse.'
        wx.MessageBox(infoTxt, 'Info', wx.OK | wx.ICON_INFORMATION)

    def resetGrid(self):
        Cols = self.MyGrid.GetNumberCols()
        Rows = self.MyGrid.GetNumberRows()
        if Cols > 0:
            self.MyGrid.DeleteCols(0,Cols)
        if Rows > 0:
            self.MyGrid.DeleteRows(0,Rows)

    def onShowLines(self, event):
        checkbox = event.GetEventObject()
        if checkbox.GetValue():
            self.MyGrid.EnableGridLines(True)
        else:
            self.MyGrid.EnableGridLines(False)

    def procesar(self, event):
        if self.ImageDir != "":
            bi = wx.BusyInfo("Procesandio, por favor espere", self)
            self.resetGrid()
            #-------------------------------------------------
            #     Preparar la cuadricula para la imagen
            #-------------------------------------------------
            #self.MyGrid.EnableGridLines(False)
            self.MyGrid.SetRowLabelSize(0) #esconder indices
            self.MyGrid.SetColLabelSize(0) #esconder indices
        
            sizeX = self.ImgSize[0]*3 #Ancho = Numero de pixelesX * 3
            sizeY = self.ImgSize[1]   #Largo = Numero de pixelesY

            self.MyGrid.AppendCols(sizeX) # Agregar columnas Nesesarias
            self.MyGrid.AppendRows(sizeY) # Agregar Filas Nesesarias
            #-------------------------------------------------
            #   Ajustar tamano de celdas para conservar
            #   la relacion de aspecto
            #-------------------------------------------------
            for x in range(sizeX):              #ajustar tamano de Filas a 15 px
                self.MyGrid.SetColSize(x,15)

            for x in range(sizeY):              #ajustar tamano de Columnas a 15px * 3 = 45px
                self.MyGrid.SetRowSize(x,45)
            #-------------------------------------------------
            #   Colorear las celdas dependiendo del
            #   Valor RGB de cada pixel
            #-------------------------------------------------
            for x in range(self.ImgSize[0]):
                for y in range(sizeY):
                
                    color = wx.Colour(self.Pixels[x,y][0], 0, 0) 
                    self.MyGrid.SetCellBackgroundColour(y,x*3,color)

                    color = wx.Colour(0, self.Pixels[x,y][1], 0) 
                    self.MyGrid.SetCellBackgroundColour(y,(x*3)+1,color)

                    color = wx.Colour(0, 0,self.Pixels[x,y][2]) 
                    self.MyGrid.SetCellBackgroundColour(y,(x*3)+2,color)
            del bi
        else:
            wx.MessageBox("No has elegido ninguna imagen.", 'Info', wx.OK | wx.ICON_INFORMATION)
        
    def SelecIMG(self, event):
        wildcard = "jpg, png, tiff o bmp|*.jpg;*.png;*.tiff;*.bmp"

        dlg = wx.FileDialog(
            self, message="Abrir archivo de imagen",
            defaultDir=self.currentDirectory, 
            defaultFile="",
            wildcard=wildcard,
            style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)

        if dlg.ShowModal() == wx.ID_OK:
            self.ImageDir = dlg.GetPath()
            self.TxtDirOpen.SetValue(self.ImageDir)

            self.image = Image.open(self.ImageDir) # Puede ser jpg, png, tiff, gif
            self.Pixels  = self.image.load()
            self.ImgSize = self.image.size  # Obtener el manaño de la imagen para iterar
        dlg.Destroy()
 
if __name__ == "__main__":
    app = wx.App()
    frame = MyForm().Show()
    app.MainLoop()

No hay comentarios.:

Publicar un comentario