Archive

Archive for the ‘Tutoriais’ Category

OpenCV - tutorial deteção de blobs e movimento - parte 3

May 24th, 2010

… Continuando dos posts anteriores …

Agora com a captação a imagem da câmera funcionando, e fazendo a leitura dos blobs, cabem algumas considerações sobre os resultados obtidos do sistema. A primeira coisa que se nota é que, a deteção de blobs ocorre em todos os frames da captação de vídeo. Isso não é, necessariamente, o ideal, dependendo do projeto. Afinal na minha idéia, só me interessa verificar o que se move. Com esse comportamento da deteção de blobs, repara-se que mesmo algumas variações de iluminação são o suficiente para o OpenCV ler novos blobs.

Lendo um pouco a documentação do OpenCV e vendo alguns exemplos, reparei na função absDiff(), que trabalha em conjunto com a função remember(). O que elas fazem é “lembrar” ( remember() ) o frame anterior, calcular a diferença ( absDiff() ) para o frame atual, e gerar uma imagem com essa diferença. Ótimo, esse seria um grande passo para facilitar a deteção, exclusiva, de movimentos.

Para estudar exclusivamente esse recurso, fiz o seguinte código:

//importar biblioteca OpenCV

import hypermedia.video.*;

//Instanciar um objeto OpenCV

OpenCV opencv;

//Imagem que captura o "Movimento"

PImage movement;

//Configurar a tela do nosso programa

void setup(){

size(640,480); //tamanho da tela

opencv = new OpenCV(this); //construir objeto OpenCV

opencv.capture(640,480); //inicia captura de vídeo

}

//Execução do software

void draw(){

opencvAction();

}

//Ações do OpenCV

void opencvAction(){

opencv.read();

opencv.absDiff();

movement = opencv.image();

image( movement, 0, 0 );

opencv.remember();

}

O resultado foi esse:

Só um comentário sobre o código em sí: Eu coloquei o trabalho do OpenCV em uma função, chamada opencvAction(), para organizar melhor o código, porque daqui em diante, o código vai crescer em tamanho, e já é bom fazer as coisas organizadinhas para facilitar correções futuras.

Mas o fato realmente “empolgante”, é que com o uso desses recursos obtemos uma imagem que possui apenas a informação de modificações entre o frame anterior e o atual! Vejamos a função opencvAction():

  • Na primeira linha da função: lemos o conteúdo da câmera.
  • Na segunda linha, chamamos a função absDiff(), para calcular a diferença entre os frames.
  • Na terceira linha, guardamos a imagem resultante da diferença no objeto “movement” - observar que esse é um objeto da classe PImage
  • Na quarta linha, desenhamos a imagem da diferença (movement) na tela.
  • Na quinta linha, chamamos a função remember(), para que no próximo frame, o OpenCV, tenha essa imagem para comparar com a próxima.

Com isso feito, fiz o próximo teste, que seria, fazer a deteção de blobs, apenas na imagem resultante da deteção de movimentos, veja o código abaixo: (Obs: apenas acrescentei a função detetarBlobs() )

//importar biblioteca OpenCV
import hypermedia.video.*;
//Instanciar um objeto OpenCV
OpenCV opencv;
//Imagem que captura o "Movimento"
PImage movement;
//Configurar a tela do nosso programa
void setup(){
    size(640,480); //tamanho da tela
    opencv = new OpenCV(this); //construir objeto OpenCV
    opencv.capture(640,480); //inicia captura de vídeo
}

//Execução do software
void draw(){
    opencvAction();
    detetarBlobs();
}

//Ações do OpenCV
void opencvAction(){
    opencv.read();
    //opencv.convert(OpenCV.GRAY);
    opencv.absDiff();
    movement = opencv.image();
    image( movement, 0, 0 );
    opencv.remember();
}

void detetarBlobs(){
    opencv.threshold(100); //tratamento da imagem
    Blob[] blobs = opencv.blobs(200, width*height/2, 10, false, OpenCV.MAX_VERTICES/4);
    //desenhar os blobs existentes
    for( int i=0; i<blobs.length; i++ ) {
        //desenho dos contronos dos blobs<
        beginShape();
        for( int j=0 ; j&lt;blobs[i].points.length ; j++){
            vertex( blobs[i].points[j].x, blobs[i].points[j].y );
        }
        endShape(CLOSE);
        //desenho dos centroids
        fill(200,50,10);
        ellipse(blobs[i].centroid.x, blobs[i].centroid.y, 5,5);
        fill(255);
    }
}

O resultado foi este:

Com essa base, já é possível fazer uma deteção de movimento bem melhor. Temos a imagem “resultante” do movimento; fazendo a deteção de blobs conseguimos isolar dessa imagem as “coisas” que se movem em frente a câmera; Com os blobs calculados, podemos gerar um ponto médio desse deslocamento, fazendo uma média aritmética simples dos pontos “centroids” de cada blob: soma-se os ‘centroid’ de cada blob, e divide-se pela quantidade de blobs.

Bem, é claro que essa última sugestão - na verdade todas as sugestões que dei aqui - dependem do seu projeto, da sua idéia.

Basicamente esse post meio tutorial, meio relato, acaba aqui. Vou escrever um próximo, falando da classe BlobDetection, que chamou muito minha atenção, pela qualidade da deteção de blobs que ela oferece. Ao menos para o meu projeto é melhor que a opção disponível padrão do OpenCV. Mas vale dizer que ambas fazem a mesma coisa, da mesma forma.

até mais.

Processing, Tutoriais , ,

OpenCV - tutorial deteção de blobs e movimento - parte 2

May 24th, 2010

Continuando o meu relato de pesquisa com o OpenCV e Processing…

Depois de testar e constatar que o OpenCV estava capturando corretamente a imagem da minha webcam, chagou a hora de ver como interpretar as imagens. Logo de início fui atrás de como capturar Blobs via OpenCV. Blobs? O que são blobs?… Bem, pelo que entendi, são chamados “blobs” áreas da imagem que se destacam pelo contraste de cores, geralmente contraste entre pontos claros, e escuros (brilho e sombra), mas também é possível fazer seleção por cores específicas.

Com uma rápida consultada na documentação da biblioteca OpenCV para o Processing (veja os itens na coluna à esquerda), há um bom exemplo de como os blobs funcionam. Pelo exemplo o que acontece é o seguinte; Quando chamada a função blobs(), do objeto opencv, o resultado é um array de objetos tipo Blob, que por sua vez, possuem lá seus recursos. Então eu fui xeretar; E a partir do último código comecei a fazer o seguinte (após a função image(), dentro da função draw()):

//Iniciar captura de blobs

opencv.threshold(50);

Blob[] blobs = opencv.blobs(20, width*height/2, 10, true, OpenCV.MAX_VERTICES);

println(blobs.length);

O que fiz foi pedir a detecção de Blobs, que ficaram armazenados no array ‘blobs’, e na seqüencia apenas imprimo no console a quantidade de blobs detetados ( detetados: nova forma de detectados, após o acordo ortográfico =P). Logo de cara, reparei que para a deteção de blobs é necessário um certo tratamento na imagem, no caso o “threshold”. Para quem não conhece tratamento de imagens, esse efeito reduz a quantidade de cores de uma imagem por aproximação, e com isso aumenta os contrastes, veja:

imagem sem aplicação de threshold imagem com aplicação de filtro threshold

Imagens sem, e com, aplicação de filtro “threshold”. Essa configuração é importante para adequar sua captação de blobs à iluminação da sua “cena”.

[…]

Sem a aplicação desse tratamento parece que a deteção de Blobs, não funciona. =P Não gostei disso.

Continuando, fui fazer como no exemplo da documentação e desenhar os blobs na tela para vê-los. E isso é possível se fazer com diferentes informações contidas nos blobs. Para começar mais simples, decidi desenhar na tela o centro do blob, veja na documentação que cada blob possui um ponto chamado ‘centroid’. Então vou usá-lo para desenhar uma elipse no centro de cada blob:

//Iniciar captura de blobs

opencv.threshold(100); //tratamento da imagem

Blob[] blobs = opencv.blobs(20, width*height/2, 10, true, OpenCV.MAX_VERTICES);

//desenhar os blobs existentes

for( int i=0; i&lt;blobs.length; i++ ) {

fill(200,50,10);

ellipse(blobs[i].centroid.x, blobs[i].centroid.y, 5,5);

fill(255);

}

Repare que, obviamente, temos que iterar (com o loop for) por cada blob que está na lista de “blobs”, para desenhar cada um dos “centroids”. Outra opção possível, é fazer como no exemplo, desenhar o contorno de cada blob. Veja abaixo, como fazer isso junto com o desenho dos “centroids”, apenas alterando o loop ‘for’:

for( int i=0; i&lt;blobs.length; i++ ) {

//desenho dos contronos dos blobs

beginShape();

for( int j=0 ; j&lt;blobs[i].points.length ; j++){

vertex( blobs[i].points[j].x, blobs[i].points[j].y );

}

endShape(CLOSE);

//desenho dos centroids

fill(200,50,10);

ellipse(blobs[i].centroid.x, blobs[i].centroid.y, 5,5);

fill(255);

}

Novamente na documentação há a descrição dos ‘points’, que é uma lista dos pontos de compõe o contorno do blob, assim podemos usar essa informação para criar um segundo loop onde desenhamos os pontos como um ’shape’ de fundo branco. Veja como deve ficar:

Além disso outros pontos devem ser observados, em especial as opções para a função blobs(). Naqueles parâmetros é onde se pode configurar melhor a captura desses blobs, lembre-se: SEMPRE OLHE E LEIA A DOCUMENTAÇÃO! Fazendo algumas alterações os resultados podem lhe ser mais interessantes.

Devo confessar que não fiquei muito feliz com a forma do OpenCV fazer a deteção de blobs, e me lembrei da biblioteca BlobDetection, que me trouxeram resultados melhores (em minha opinião). Logo, optei por utilizá-la para esse trabalho. Futuramente vamos falar sobre ela, mas antes vamos falar sobre deteção de movimentos via OpenCV. Mas fica para os próximos textos.

Até.

PS: O código completo é

//importar biblioteca OpenCV

import hypermedia.video.*;

//Instanciar um objeto OpenCV

OpenCV opencv;

//Configurar a tela do nosso programa

void setup(){

size(640,480); //tamanho da tela

opencv = new OpenCV(this); //construir objeto OpenCV

opencv.capture(640,480); //inicia captura de vídeo

}

void draw(){

opencv.read(); //faz a leitura das imagens da câmera

image(opencv.image(), 0,0);//desenha a imagem na tela

//Iniciar captura de blobs

opencv.threshold(100); //tratamento da imagem

Blob[] blobs = opencv.blobs(200, width*height/2, 10, false, OpenCV.MAX_VERTICES/4);

//desenhar os blobs existentes

for( int i=0; i&lt;blobs.length; i++ ) {

//desenho dos contronos dos blobs

beginShape();

for( int j=0 ; j&lt;blobs[i].points.length ; j++){

vertex( blobs[i].points[j].x, blobs[i].points[j].y );

}

endShape(CLOSE);

//desenho dos centroids

fill(200,50,10);

ellipse(blobs[i].centroid.x, blobs[i].centroid.y, 5,5);

fill(255);

}

}

Processing, Tutoriais , ,

OpenCV - tutorial detecção de blobs e movimento - parte 1

May 24th, 2010

Olá,

Recentemente me envolvi em um projeto de uma pequena instalação (quase) artística, que consiste basicamente em controlar a exibição de vídeos, e slideshows, de acordo com a movimentação de quem está vendo o material.

Para isso comecei a estudar conceitos de ‘computer vision’ , detecção de faces, blobs e movimentos em vídeos. Porquê? Porque quem vai detectar o movimento do espectador é uma câmera! Logo, é necessário interpretar, de alguma forma, as imagens captadas pela câmera.

Seguindo comprovações científicas sobre o processo de aprendizado, estou escrevendo esse tutorial, para me ajudar a fixar o que estou aprendendo. Logo, vale ressaltar que, eu não sou um especialista no assunto, estou aprendendo o mesmo. E se o relato desse processo lhe for tão útil quando será para mim, ótimo!

Para esses primeiros estudos vou usar o Processing, a biblioteca OpenCV, e uma biblioteca para o Processing chamada Blob Detection. Se até o final o resultado se mostrar bom o suficiente, vou ficar no Processing mesmo, caso contrário vou para um C++ ou ObjectiveC. Estou desenvolvendo esse projeto em Linux e Mac OSX. Caso você esteja no Windows, sei lhe dizer que tudo isso vai funcionar da mesma forma, porém caso ocorra algum problema, ou você tenha alguma dúvida, que esteja diretamente relacionada as especificidades do Windows, NÃO PODEREI TE AJUDAR! Faz muito tempo que não trabalho no Windows, e confessor que perdi completamente a transição para o Vista e para o 7. E nesse caso o melhor lugar para pedir ajuda é nos fóruns do Processing.

Preparação

Para começar a brincadeira são necessárias algumas instalações, que dependem da plataforma que vc está utilizando, além das instalações básicas (Processing, OpenCV, biblioteca OpenCV para o Processing):

Mac: Essa é a plataforma em que você terá menos trabalho, basta instalar a biblioteca BlobDetection, alem das instalações básicas (Processing, OpenCV, biblioteca OpenCV para o Processing).

Linux: Aqui vc terá mais trabalho. Mas nada sobre humano… Para o Linux você terá que instalar uma biblioteca para que o Processing leia e renderize as imagens da câmera: A GSVideo, que utilizará o Gstreamer para isso (No Mac e no Windows geralmente o Processing usa o Quicktime). E claro você precisará de um driver para que o GStreamer acesse a câmera, nesse caso usei o V4l (video4linux) e foi o suficiente. Além, claro, das instalações básicas (Processing, OpenCV, biblioteca OpenCV para o Processing).. ah… não se esqueça da biblioteca BlobDetection.

Windows: Além das instalações básicas (Processing, OpenCV, biblioteca OpenCV para o Processing), você precisará, assim como no Linux, de uma biblioteca para renderização de vídeo, você pode optar pelo QuickTime, ou pelo GStreamer. Eu recomendaria usar o Quicktime, porque o Processing já é tudo integrado com ele. E… não se esqueça da biblioteca BlobDetection.

Eu não vou explicar aqui os detalhes de instalação dos softwares e bibliotecas, porque nos sites de cada um dos projetos, e internet adentro, já existem tais informações.

Agora o próximo passo é abrir o Processing e fazer um teste. Vejamos.

Veja na imagem abaixo, o código básico para um primeiro teste:

programa de teste

Olha como isso deve funcionar:

Agora a próxima etapa é Começar a analizar as imagens e interpretá-las. Ainda bem que a biblioteca OpenCV faz bastante coisa para agente. :)

Abraço e até mais.

Processing, Tutoriais , ,

Aulas de Processing - Inteligência Artificial

March 26th, 2010

Nesta semana que passou, eu ministrei umas aulas no SESC Carmo sobre uma técnica de inteligência artificial chamada de “swarm behavior” ou flocking. As aulas que estão no Youtube não são exatamente para iniciantes absolutos, são necessários alguns conhecimentos prévios de programação e do Processing, porém toda a turma era de iniciantes… mas o curso já estava na sua terceira semana, quando essas aulas começaram a ser gravadas.

Caso você seja um iniciante completo, aconselho a dar uma olhada nos tutoriais que escrevi aqui. E assistir esses vídeos para ver no geral como a coisa funciona.

Nessa última semana tivemos cinco aulas, e os vídeos estão listados abaixo. Por algumas questões técnicas, os vídeos estão “fatiados”. Em cada “fatia” damos um passo em direção ao objetivo final.

Espero que seja de alguma ajuda.

abraços.

Aula 1 ———————————– Lista de reprodução do Youtube

Aula 2 ———————————– Lista de reprodução do Youtube

Aula 3 ———————————– Lista de reprodução do Youtube

Aula 4 ———————————– Lista de reprodução do Youtube

Aula 5 ———————————– Lista de reprodução do Youtube

Processing, Tutoriais , ,

Desligar terminais Ubuntu de uma LAN

December 12th, 2009

Olá,

Neste post vou relatar uma solução que encontrei para um problema que eu tinha. Eu atualmente estou trabalhando em um local que é basicamente uma LAN com 20 terminais com Ubuntu, e de quando em quando, eu tenho que desligar os computadores e …. puta preguiça de fazer isso um por um. Então pensei, isso é ridículo!! Deve haver uma forma de automatizar isso! Dei uma pesquisada pela net mas não achei nada… não procurei tanto assim… :)

Então tomei a decisão de fazer alguma coisa… tipo um script (em Python) que mandasse um sinal via rede, e do outro lado, um programa que desse a ordem de desligar. Depois de uma certa odisseia, cheguei a uma solução, e o melhor, aprendi uma coisa incrível: a possibilidade de editar os perfis de usuário do Linux, editando o arquivo sudoers.

Depois que eu tinha tudo pronto o Raidicar, me deu uma outra chance de solução bem legal no fórum do Ubuntu-Br, que se complementaria perfeitamente com parte desse tutorial. Veja o link.

Vou explicar a coisa toda de forma sucinta, para maiores detalhes visite os links sugeridos.

Idéia & Problema

Então a idéia inicial era a seguinte, um script em python que recebesse via rede um sinal e executasse o comando shutdown, ou init. O problema que apareceu logo de cara foi que, ambos os comandos shutdown e init, exigem por padrão a execução em modo de super usuário (sudo), e isso conseqüentemente exige a senha do usuário. E como se não bastasse, os micros em questão, rodam 90% do tempo em usuário sem privilégio administrativos, e dessa forma os comandos shutdown e init, por padrão, não funcionam! :S

Então depois de uma pesquisa nos fóruns do Ubuntu achei uma dica, a possibilidade de se personalizar as ações de usuário com perfis distintos editando o arquivo sudoers. Neste link, há uma explicação muito bacana sobre como se editar o arquivo sudoers (em inglês)

Seguindo as instruções do link, eu fiz uma configuração no arquivo sudoers, que não exige senha para a execução dos comandos shutdown, init e reboot nos usuários sem privilégios administrativos. Então segue abaixo o tutorial para isso:

O arquivo sudoers está localizado na pasta /etc, e para editá-lo você precisa fazê-lo como root, e MUITO CUIDADO! Esse arquivo, por padrão tem apenas permissão de leitura, inclusive para o root, e se você mudar a permissão, o Ubuntu não roda mais o comando sudo, e aí você precisará reinstalar o sistema, então siga as instruções detalhadamente para não dar erro. SE VOCÊ FIZER MERDA, E VIER POSTAR PEDIDOS DE AJUDA, PQ VC FEZ MERDA, E NÃO SEGUIU O MEU TUTORIAL, EU VOU DAR UM TAPA NA TUA CARA, E DIZER EU EU EU VC SE FU***, ENTÃO SIGA MEU TUTORIAL TIM-TIM POR TIM-TIM!

1. Como usuário administrador, abra o Terminal, e digite o comando: sudo nautilus

Entre com sua senha e navegue para a pasta /etc: Sistema de Arquivos > etc, e encontre o arquivo sudoers

2. Clique-direito do mouse, vá em Permissões, e habilite Leitura e Escrita para o usuário root. ATENÇÃO: NÃO FECHE O NAUTILUS! SE O NAUTILUS FOR ENCERRADO, COM O ARQUIVO SUDOERS COM PERMISSÃO DE ESCRITA HABILITADO, O COMANDO SUDO NÃO VAI MAIS FUNCIONAR, E VC PRECISARÁ REINSTALAR SEU SISTEMA! Então apenas habilite o modo escrita, clique em ‘Fechar’ (canto direito inferior da telinha de Propriedades)

3. Clique-direito do mouse no arquivo sudoers, e “Abrir com Editor de Texto”, agora vamos editar o arquivo. Por padrão vc vai ver isso (Ubuntu 9.04)

Mas o arquivo deve ser editado assim (nesse caso vale ler a explicação detalhada abaixo da imagem)

OBS: ERRATA! Na linha 18, acima, está escrito ‘Cmnd_ALias’, o correto é ‘Cmnd_Alias’.

Aqui o que acontece na linha 13, é que primeiro criamos um grupo de usuários com perfis semelhantes, no caso, usuários sem privilégios administrativos (USER), que engloba apenas o usuario14. Poderiam haver mais usuários… bastaria colocá-los entre vírgulas, ex: User_Alias USER = usuario14, paulo, maira. Com isso os usuários paulo e maira, estariam no mesmo grupo.

Esse usuário14, é o nome do usuário no terminal 14, logo, em cada máquina da Lan, esse nome possivelmente será diferente.

Nas linhas 16, 17 e 18, são criados uma espécie de variáveis que representarão os comandos que eu quero configurar para o usuário14, no caso o comando shutdown, reboot e init. Os executáveis desses comandos estão na pasta /sbin do sistema, portanto devem ser declarados com o caminho completo.

Finalmente na linha 22, é onde o sudoers recebe a configuração desejada. Tentando traduzir aquilo para bom português, que é dito é mais ou menos o seguinte: O grupo USER, de qualquer terminal (leia-se console de comando), não mais precisará de senha para os comandos SHUTDOWN, REBOOT e INIT. Ou seja, a partir de agora os usuários sem privilégios administrativos, poderão executar os comandos de desligar ou reiniciar, vindos de algum console de comando sem solicitação de senhas, então o meu script passará a funcionar bonitinho! :) O script do Raidicar também! :)

4. Agora salve as alterações no arquivo e feche o Editor de Texto. E AGORA VOLTE ÀS PROPRIEDADES DO ARQUIVO sudoers E COLOQUE-O NOVAMENTE COM A PERMISSÃO DE “Apenas Leitura”.

Clique no botão ‘Fechar’.

E SÓ AGORA VOCÊ PODE FECHAR O NAUTILUS. NÃO FECHE O NAUTILUS SEM TER A CERTEZA DE QUE O ARQUIVO sudoers ESTÁ COM APENAS A PERMISSÃO PARA LEITURA CONFIGURADA PARA TODOS OS USUÁRIOS.

Agora essa etapa está encerrada, e falta apenas a instalação do programa.

SCRIPTS

Script para os Terminais

O sistema como um todo funciona com um pequeno script gravado nos terminais e configurado para ser iniciado com a sessão do usuário, e um outro que roda no computador central - no caso o meu computador :) - que dispara as ordens de desligar e reiniciar os terminais da LAN.

Começando pelo script dos terminais, você pode baixá-lo aqui. Não vou entrar em detalhes do script, mas usei como base para criá-lo uma receita do CookBook do comunidade Python Brasil, veja só.

A instalação e configuração do script é super simples. Primeiro eu recomendo que você crie uma pasta oculta dentro da pasta de usuário e colocar o script down.py nessa pasta. Para criar uma pasta oculta basta colocar um ponto(.) na frente do nome que vc quiser. Por exemplo, vou criar uma pasta oculta chamada ‘down’, abro o navegador de arquivos, vou até a Pasta de Usuário, clique-direito do mouse e “Criar nova Pasta”, e dar o nome de ‘.down’, e pronto, basta entrar na pasta e colocar o arquivo down.py dentro dela, e aqui vale uma observação importante, o arquivo down.py precisa ter permissão de execução como programa. Para fazer isso, clique-direito sobre o arquivo, vá em Propriedades >> Permissões >> Permitir execução do arquivo como programa.

Depois disso basta configurar a sessão de usuário para executar esse arquivo assim que a sessão for iniciada. Na sessão do usuário, vá em SISTEMA >> PREFERÊNCIAS >> APLICATIVOS DE SESSÃO (Ubuntu 9.04). Em Ubuntus mais antigos, veja isso em SISTEMA >> PREFERÊNCIAS >> SESSÕES.

Clique em Adicionar, então preencha as informações:

NOME: Down

COMANDO: /home/usuario14/.down/down.py

COMENTÁRIO: ah… qualquer coisa, se quiser.

No Comando, a pasta do usuário (usuário14 neste caso), fica dentro da pasta home, que geralmente está na raíz do sistema, mas isso pode variar. Dessa forma a cada sessão o programa que recebe o sinal via rede e executa o comando de desligar ou reiniciar, será automaticamente iniciado. :)

Script para a administração

O script para administração, ou seja, o micro que mandará as ordens para os terminais foi batizado de downComand.py, baixe-o aqui.

Há um detalhe importante para que você possa usar esse script e fazer algumas alterações para que ele te sirva perfeitamente. Como relatei no início tenho uma LAN com 20 máquinas, então nesse script, eu organizei uma tabela com os números dos computadores e seus respectivos ips dentro da LAN, e você pode adicionar, retirar, ou re-configurar esses ips, de acordo com a sua LAN.

O uso é super simples, você irá rodar o script escolhendo o micro e o que fazer, exemplo:

python downComand.py 10 desligar

Ou seja, micro 10: desligar

python downComand.py todos reiniciar

Ou seja, todos os micros: reiniciar

Há ainda uma pequena opção que fiz agrupando os micros, de acordo com sua posição ‘geográfica’. Na sala dessa LAN, temos duas mesas pequenas que chamamos de ilhas, e uma mesa maior que apelidamos de ferradura, e no script, também posso dizer: python downComand.py ferradura desligar ; e os micros da ferradura serão desligados.

Atualização: Aqui é possível baixar uma versão com interface gráfica, que só será interessante se vc souber editar scripts em Python, para personalizá-lo para seu caso.

Conclusão

Bem, o mais complicado mesmo é a configuração do usuário, o sudoers, e fazer isso micro por micro é um trabalhinho, mas depois, vale a pena. :) posso até sacanear alguém desligando/reiniciando o micro na surdina hahahaha. Mas o mais bacana nesse processo, para mim, foi aprender esse esquema de configuração do sudoers, que se você ler o link que indiquei anteriormente, vai ver que abre um monte de possibilidades bacanas, essa é só uma delas.

E Linux em geral é assim… pesquisando, lendo e aprendendo. Ele sempre exige uma postura ativa ante a tecnologia, que é um pouco menor quando se usa Mac, e quase nula quando se usa Windows. Um exemplo disso vi na minha pós-graduação (Produção de Games), meus colegas são, em sua maioria, formados em TI - eu sou formado em Desing Gráfico -, mas não usam Linux e em vários momentos do curso, eu tinha um conhecimento de várias bibliotecas e softwares livres para som ou gráficos, que eles não conheciam.

Tutoriais , , , ,