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:
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()