Blog C/C++ IA OPENCV OpenCV pós graduação Python
OpenCV em C

Em um artigo anterior fiz um exemplo de opencv em Python.

OpenCV em Python

Neste artigo irei apresentar um exemplo de código de opencv em C++.

Irei comentar traçando referencias entre o código do C e o código do python.

O Exemplo utililizado será fornecido pela própria biblioteca em python.

Aqui vemos o exemplo comentado do fonte

OpenCV em Python

Para traçar um paralelo usaremos os códigos do opencv, o programa chamado video_v4l2.py

Conforme apresentado abaixo:

#!/usr/bin/env python

'''
VideoCapture sample showcasing  some features of the Video4Linux2 backend

Sample shows how VideoCapture class can be used to control parameters
of a webcam such as focus or framerate.
Also the sample provides an example how to access raw images delivered
by the hardware to get a grayscale image in a very efficient fashion.

Keys:
    ESC    - exit
    g      - toggle optimized grayscale conversion

'''

# Python 2/3 compatibility
from __future__ import print_function

import numpy as np
import cv2 as cv

def main():

    def decode_fourcc(v):
        v = int(v)
        return "".join([chr((v >> 8 * i) & 0xFF) for i in range(4)])

    font = cv.FONT_HERSHEY_SIMPLEX
    color = (0, 255, 0)

    cap = cv.VideoCapture(0)
    cap.set(cv.CAP_PROP_AUTOFOCUS, 0)  # Known bug: https://github.com/opencv/opencv/pull/5474

    cv.namedWindow("Video")

    convert_rgb = True
    fps = int(cap.get(cv.CAP_PROP_FPS))
    focus = int(min(cap.get(cv.CAP_PROP_FOCUS) * 100, 2**31-1))  # ceil focus to C_LONG as Python3 int can go to +inf

    cv.createTrackbar("FPS", "Video", fps, 30, lambda v: cap.set(cv.CAP_PROP_FPS, v))
    cv.createTrackbar("Focus", "Video", focus, 100, lambda v: cap.set(cv.CAP_PROP_FOCUS, v / 100))

    while True:
        _status, img = cap.read()

        fourcc = decode_fourcc(cap.get(cv.CAP_PROP_FOURCC))

        fps = cap.get(cv.CAP_PROP_FPS)

        if not bool(cap.get(cv.CAP_PROP_CONVERT_RGB)):
            if fourcc == "MJPG":
                img = cv.imdecode(img, cv.IMREAD_GRAYSCALE)
            elif fourcc == "YUYV":
                img = cv.cvtColor(img, cv.COLOR_YUV2GRAY_YUYV)
            else:
                print("unsupported format")
                break

        cv.putText(img, "Mode: {}".format(fourcc), (15, 40), font, 1.0, color)
        cv.putText(img, "FPS: {}".format(fps), (15, 80), font, 1.0, color)
        cv.imshow("Video", img)

        k = cv.waitKey(1)

        if k == 27:
            break
        elif k == ord('g'):
            convert_rgb = not convert_rgb
            cap.set(cv.CAP_PROP_CONVERT_RGB, 1 if convert_rgb else 0)

    print('Done')


if __name__ == '__main__':
    print(__doc__)
    main()
    cv.destroyAllWindows()

A primeira informação importante é a carga das bibliotecas do opencv em python.

import cv2 as cvimport cv2 as cv

carga da lib em python

O proximo ponto importante é onde capturamos o vídeo.

cap = cv.VideoCapture(0)

Captura do vídeo

O Parametro 0, indica que o device de vídeo é o padrão do sistema.

O ponto importante no código é o uso do cap, no código abaixo:

_status, img = cap.read()

captura do frame

Ao chamar a função read, dois parametros são retornados, _status (retorno de sucesso) e img, a imagem capturada.

Por fim, uma janela é montada com a visualização da imagem capturada:

cv.imshow(“Video”, img)

janela é montada

Agora iremos analisar o mesmo código em C.

OpenCV em C

Agora mostraremos o código em C, o exemplo é o videocapture_basic.cpp:


#include <opencv2/core.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
#include <stdio.h>

using namespace cv;
using namespace std;

int main(int, char**)
{
    Mat frame;
    //--- INITIALIZE VIDEOCAPTURE
    VideoCapture cap;
    // open the default camera using default API
    // cap.open(0);
    // OR advance usage: select any API backend
    int deviceID = 0;             // 0 = open default camera
    int apiID = cv::CAP_ANY;      // 0 = autodetect default API
    // open selected camera using selected API
    cap.open(deviceID, apiID);
    // check if we succeeded
    if (!cap.isOpened()) {
        cerr << "ERROR! Unable to open camera\n";
        return -1;
    }

    //--- GRAB AND WRITE LOOP
    cout << "Start grabbing" << endl
        << "Press any key to terminate" << endl;
    for (;;)
    {
        // wait for a new frame from camera and store it into 'frame'
        cap.read(frame);
        // check if we succeeded
        if (frame.empty()) {
            cerr << "ERROR! blank frame grabbed\n";
            break;
        }
        // show live and wait for a key with timeout long enough to show images
        imshow("Live", frame);
        if (waitKey(5) >= 0)
            break;
    }
    // the camera will be deinitialized automatically in VideoCapture destructor
    return 0;
}

O primeiro ponto assim como no código em python, e a chamada da biblioteca em c.

#include <opencv2/core.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>

Sem esses includes não teriamos acessos aos tipos do C, como o que segue:

VideoCapture cap;

O tipo VideoCapture é o tipo associado a captura de vídeo da câmera.

Onde usaremos, conforme fragmento abaixo:

int deviceID = 0;             // 0 = open default camera
int apiID = cv::CAP_ANY;      // 0 = autodetect default API
// open selected camera using selected API
cap.open(deviceID, apiID);

Aqui, definimos o deviceID como 0, ou seja, o valor padrão, veja a semelhança do uso do python.

E apiID, passando o escopo (variavel) CAP_ANY, que tem por valor 0.

Chamamos o método open da classe VideoCapture, indicando o deviceID, e o apiID.

Agora iremos ler a imagem da camera, que podemos fazer, através da seguinte função:

cap.read(frame);

Neste fragmento de código, passamos o parametro frame, que é do tipo Mat.

O frame receberá a imagem capturada.

E por fim, no código abaixo a janela que irá mostrar a imagem na interface gráfica.

imshow("Live", frame);

Conclusão

Apesar das diferenças de linguagem, podemos ver o pontos em comum, e a sutileza da semelhança.

É lógico que os códigos foram escolhidos a dedo. Justamente por conta da semelhança e simplicidade.

O opencv é uma biblioteca rica, cheia de opções e dificuldades, este tutorial, bem como o autor, esta apenas adentrando neste mundo para mim misterioso.

Espero que tenham gostado deste artigo. 😉

RFID
RFID com gravação de parametros pela eeprom

A partir da versão 1.0.3, os parametros serão gravados na EEPROM.

Esta mudança visa retirar a dependencia do pino 4.

Agora a parametrização é feita por comandos na serial usando o putty são gravados na memória não volátil do firmware.

Novos parametros foram adicionados a versão 1.0.3

  • Modo Debug
  • Modo HEX Decimal
  • Modo ECHO
  • Modo TECLADO
  • Modo SERIAL

São parametros que podem ser ativados ou inativados.

Com o ajuste de parametrização pela serial, tambem é possivel ler o ultimo cartão lido.

O detalhamento, bem como as informações dos comandos completos, estarão disponíveis em documentação neste site.

Blog RFID
A importancia da prototipagem

A prototipagem é a capacidade de transformar idéias em algo real, criando uma ou mais exemplares a fim de teste de conceito.

A prototipagem não visa criar um produto final, mas validar o conceito deste. Realizando testes de viabilidade, resistência e usabilidade.

O protótipo pode ser modificado e amadurecido, durante o seu tempo de teste. Podendo passar por muitas revisões. Sendo de fato, um tempo destinado para este amadurecimento como produto.

A prototipagem de hardware pode ser:

Prototipagem eletrônica – Consistindo em partes impressas ou não, montadas de forma artesanal ou em cnc routers especificos para PCB. Com o intuíto de teste de circuitos eletrônicos.

Prototipagem mecânica – Consiste em partes impressas ou não , montadas de forma artesanal ou em impressoras 3d.

Um exemplo de prototipagem é a construção da caixa do RFID, que na revisão 1, identificou um erro no posicionamento do chanfro.

Conforme vídeo abaixo:

Erro de prototipagem da caixa plastica.

No caso deste projeto houve duas ações.

Correção da caixa, através uma broca foi feito o ajuste grosseiro na mesma.

Correção no projeto, através de ferramenta cad, a correção no projeto da caixa, para reimpressão e ajuste.

RFID
Montagem da Caixa do Arduino

Dei inicio ao projeto de construção da caixa do RFID.

Como diferencial a caixa tem os padrões do arduino Leonardo, micro USB, e alimentação.

Tambem é um pouco mais alta para o RFID, pois a fiação pode necessitar de 7 cm de altura.

Estou postando o projeto no GRABCAD. Onde costumo postar todos os modelos que monto.

https://grabcad.com/library/box-arduino-leonardo-1

Estou imprimindo a primeira peça hoje dia 24/01.

Minha impressora esta desalinhada, então não garanto qualidade de impressão.

Ao terminar irei publicar fotos do modelo impresso.

Fiquem com Deus.

Blog C/C++
Compilação Cruzada em C – Parte 3

Objetivo

Neste artigo iremos abordar como desenvolver aplicações cruzadas em C que compilam em desktop porem geram binários para Android.

GIT

Repositório da Aplicação

https://github.com/marcelomaurin/croxcompile

Pré requisitos


apt install ncurses-base ncurses-term ncurses-examples ncurses-bin ncurses-doc ncurses-hexedit


sudo apt-get install libncurses5:i386


sudo apt-get install libncurses5

Baixe o compilador

wget http://dl.google.com/android/repository/android-ndk-r12b-linux-x86_64.zip

unzip android-ndk-r12b-linux-x86_64.zip

./android-ndk-r12b/build/tools/make_standalone_toolchain.py –arch arm64 –install-dir ~/arm

./android-ndk-r12b/build/tools/make_standalone_toolchain.py –arch arm –install-dir ~/arm32

Compile o projeto

Aqui apresento o vídeo e depois o processo completo:

/home/mmm/arm/bin/clang -pie crox.c

Para gerar aplicação 64 bits

Ou caso seu hardware não suporte 64 bits, use o seguinte comando.

/home/mmm/arm/bin/clang -pie crox.c

Para gerar aplicação 32 bits

Para automátizar o processo criamos o seguinte Makefile

PROGRAMA=HELLO
PROGRAMA32=HELLO32
PROGRAMAARM=HELLOARM


CC=gcc
CCARM=arm-linux-gnueabi-gcc
CCANDROID=~/arm32/bin/clang

SOURCE= crox.c

all32: clean compile32


all: clean compile

clean:
        rm -f *.o
        rm -f $(PROGRAMA)

compile32:
        $(CC) -m32  $(SOURCE) -o $(PROGRAMA32)

compile:
        $(CC) $(SOURCE) -o $(PROGRAMA)

compileARM:
        $(CCARM) $(SOURCE) -o $(PROGRAMAARM)

compileANDROID:
        $(CCANDROID) -pie $(SOURCE)

Para compilar usando o Makefile digite:

make compileANDROID

Compila 32 bits por padrão.

Transferindo para o Android

Entre no seu equipamento, e ative o modo Duperação USB.

Depois entre liste se o device que esta tentando debugar apareceu em seu sistema:

adb devices -l

Lista de devices ativos

Para nomes apenas:

adb devices

Enviando para device especifico

adb -s <nomedev> push a.out /data/local/tmp/.

Envia para o device especifico o binário criado.

E por fim executamos pela shell, remotamente:

adb -s <nomedev> shell “./data/local/tmp/a.out”

Execução remota da aplicação

Por fim os printes de execução:

Conclusão

No modelo apresentado, conseguimos gerar um aplicativo, que roda em 4 ambientes diferente, todos compilados no Desktop:

  • Linux x64
  • Linux i386
  • Linux ARM
  • Android amr

A versatilidade e alta disponíbilidade do C, é peça unica que garante vida longa para esta popular linguagem.

Por fim, concluimos nossa série de artigos sobre compilação cruzada.

Referências

https://adbshell.com/commands/adb-devices

http://nickdesaulniers.github.io/blog/2016/07/01/android-cli/

https://developer.android.com/ndk/guides

https://zoomadmin.com/HowToInstall/UbuntuPackage/gcc-arm-linux-androideabi

https://stackoverflow.com/questions/20093173/adb-shell-and-adb-push-for-specific-avd

Blog C/C++
Compilação Cruzada em C – Parte 2

No primeiro artigo, definimos o que seria compilação cruzada, e criamos nosso primeiro exemplo de compilação. Gerando binário de 32bits em máquina 64bits.

http://maurinsoft.com.br/index.php/2022/01/22/compilacao-cruzada-em-c/

Neste segundo artigo, iremos dar continuação.

Agora apresentando como compilar em um sistema operaciona x64 para arm.

Pré requisitos

Instale os seguintes pacotes

sudo apt-get install libc6-armel-cross libc6-dev-armel-cross binutils-arm-linux-gnueabi

sudo apt install libncurses5-dev build-essential bison flex libssl-dev bc

sudo apt-get install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf

sudo apt-get install gcc-arm-linux-gnueabi g++-arm-linux-gnueabi

Pré requisitos de instalação

Estes pacotes irão instalar as dependencias do ARM nesta plataforma.

Eles irão criar duas pastas arm-linux-gnueabi e
arm-linux-gnueabihf , ambas com pastas lib para inclusão de respectivas bibliotecas.

Git do projeto

https://github.com/marcelomaurin/croxcompile

Usaremos o git do projeto anterior, agora com uma nova diretiva.

Exemplo

Não apresentarei o fonte em C, pois já foi feito no artivo anterior, me atendo realmente o que foi adicionado neste artigo.

Makefile


PROGRAMA=HELLO
PROGRAMA32=HELLO32
PROGRAMAARM=HELLOARM

CC=gcc
CCARM=arm-linux-gnueabi-gcc

SOURCE= crox.c

all32: clean compile32


all: clean compile

clean:
        rm -f *.o
        rm -f $(PROGRAMA)

compile32:
        $(CC) -m32  $(SOURCE) -o $(PROGRAMA32)

compile:
        $(CC) $(SOURCE) -o $(PROGRAMA)

compileARM:
        $(CCARM) $(SOURCE) -o $(PROGRAMAARM)

Podemos ver que adicionamos, a diretiva compileARM, onde chamamos o CCARM, que tem valor arm-linux-gnueabi-gcc

A outra diferença é o target de execução, que chamamos de programaarm, para diferenciar dos demais binários.

Podemos compilar o programa, chamando a seguinte rotina:

make compileARM

compilação do programa
Execução em máquina x64

Rodando o programa

Agora iremos demonstrar a efetividade do binário, executando o mesmo em um raspberry pi. Que é uma máquina ARM, rodando linux.

Para tanto copiaremos o binário e colocaremos na maquina alvo.

Para esse feito usarei o bitviser.

Copiando o binário gerado para a máquina alvo

Agora iremos dár as permissões na máquina.

Dando permissões ao arquivo

Por fim, executaremos o binário, e veremos seu resultado.

Conclusão

Podemos aproveitar o poder de processamento e velocidade dos desktop e gerar binários nativos para mais de um tipo de equipamento.

No próximo post irei apresentar como fazer isso no android.

Referências

https://www.acmesystems.it/arm9_toolchain

https://howtoinstall.co/pt/gcc-arm-linux-gnueabihf

https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-a/downloads/10-2-2020-11

Blog C/C++
Compilação cruzada em C

Este será o primeiro de alguns artigos que irei abordar sobre compilação cruzada.

Definição

Compilação Cruzada é a capacidade de compilar um aplicativo para um processador que não é o que esta usando.

Definição grosseira, no wiki deve ter alguma melhor, rs.

O processo de compilação cruzada depende de como, e do alvo (target) que iremos compilar.

No nosso caso, iremos compilar uma aplicação 32bits em um sistema 64bits.

O nosso primeiro caso, é montar nossa aplicação.

Objetivo

Como objetivo deste artigo, apresentaremos compilação cruzada, desenvolvendo uma aplicação 32bits em um sistema 64bits linux.

Pré requisitos

Antes de começar precisamos preparar a máquina para compilação cruzada. Para isso, é necessário instalar as libs 32 bits em uma máquina 64 bits.

O primeiro passo é baixar o pacote:

sudo apt-get install gcc-multilib

sudo apt-get install g++-multilib

pacotes para compilação cruzada

Ao instalar o pacote, seu sistema criará várias pastas.

Em geral, um programa não roda sozinho, ele chama uma série de libs que são associadas a funcionálidades. Uma aplicação 64 bits, nativa, aponta sempre para as /usr/lib, porem ao criar um ambiente misto, criamos dois conjuntos de pastas.

Ao compilar um ambiente 32 bits, as libs associadas ao ambiente 32 deverão estar instaladas na pasta /usr/lib32.

Agora para o ambiente 64bits, temos as libs /usr/lib64.

Ao instalar este pacote criamos esta divisão. Porem vale lembrar que criamos os pacotes básicos, cabe ao programador desenvolver e aferir qual o conjunto de pacotes ele irá necessitar, fazendo a instalação do referido pacote para cada uma das pastas necessárias.

Dado a explicação conceitual, vamos ao que interessa!

GIT

Para isso iremos montar um projeto no git, conforme nossa explicação:

https://github.com/marcelomaurin/croxcompile

Neste projeto, iremos fornecer um exemplo que pode ser baixado e utilizado como modelo.

Source: crox.c

#include <stdio.h>

void main(void){
        printf("\nHello World\n");
}

Source: Makefile


PROGRAMA=HELLO
PROGRAMA32=HELLO32

CC=gcc

SOURCE= crox.c

all32: clean compile32


all: clean compile

clean:
        rm -f *.o
        rm -f $(PROGRAMA)

compile32:
        $(CC) -m32  $(SOURCE) -o $(PROGRAMA32)

compile:
        $(CC) $(SOURCE) -o $(PROGRAMA)

O programa crox, irá ser a base para gerar o nosso binário, de fato o mais importante aqui, será o Makefile.

Agora, o primeiro passo é compilar:

Para tanto, iremos executar:

make compile

compilação nativa, deve ser sempre padrão.

Neste caso, nossa máquina é 64 bits, então executaremos um binário quando chamado, 64bits puro.

make compile32

compilação 32 bits em uma máquina 64 bits

Agora, criando uma aplicação 32 bits, podemos comprovar isso, conforme demonstrado na nossa figura abaixo:

Gerados os binários temos que comprovar, que os mesmos, foram gerados nas plataformas alvo desejadas.

O LDD foi apresentado em artigo anterior, conforme link abaixo:

http://maurinsoft.com.br/index.php/2020/11/25/analisando-uma-lib/

Desta forma irei me ater, apenas a apresentar a demonstração do binário.

ldd HELLO

Análise do binário gerado

agora iremos confirmar o resultado do 32 bits:

ldd HELLO32

análise do binário 32bits

Por fim, a tela apresentando os resultados executados.

Demonstração da compilação cruzada

Bibliografia e referências

https://www.geeksforgeeks.org/compile-32-bit-program-64-bit-gcc-c-c/

https://www.filipeflop.com/blog/o-que-e-compilacao-cruzada/

ESCPOS Fila
Mudando Elgin i9 para ESC POS

A impressora Elgin i9 trabalha com dois modos possíveis de impressão.

Utilizando o padrão ESC POS, e o modo tradicional com impressão como impressora Windows.

Ao pegar uma impressora desconhecida, o mais provavel é pegar no modo ESC POS.

A diferença entre um modo e outro, é que o modo ESC POS, cria uma porta serial ao ser conectada.

Porta 38 é a impressora Elgin i9 conectada

Caso voce não encontre esta porta ao plugar sua impressora, deve ser feito o procedimento de instalação dos drivers descritos no arquivo abaixo:

Após instalar os drivers e utilitários Elgin, execute o aplicativo chamado:

Utilitário Impressora térmica

Utilitário de impressora térmica.

Configurações avançadas

Entre outras funções o botão de configurações avançadas, permite selecionar o tipo de perfil que a impressora irá rodar.

Click no botão CONFIGURAÇÕES PORTA USB , em seguida na tela abaixo:

Selecione o item PORTA SERIAL VIRTUAL, e click no botão CONFIGURAR.

Pronto, sua impressora esta configurada como SERIAL ESC POS.

ESCPOS
Primeiro Post sobre o Projeto ESC POS

Fico feliz que arrumei a casa.

Estou postando hoje o primeiro post do projeto ESC POS.

O Objetivo deste post é publicar as novidades realizadas no projeto.

Hoje arrumei a casa. Incluí a página do projeto na aba de projetos de automação comercial.

Tambem, inclui diversas informações na página principal do projeto.

Cheguei até a compilar o projeto.

Espero nos próximos posts deixar mais novidades, quero começar a liberar versões nas outras plataformas como Linux e ARM e quem sabe MAC.

Blog Dicas
Uso do RASPBERRY como servidor WEB


No intuito de desenvolver seu negócio, hoje muitas pessoas tem começado seus próprios blogs e sites.

Os custos relacionado a manter e administrar um site, sempre foi muito caro.

História até aqui

Inicialmente os custos de energia, infra estrutura, ip fixo, domínio, dificultavam muito o acesso a pequenos empresários.

Com o tempo algumas empresas tornaram-se especialistas em hospedagem, o que diminuiu em muito o custo. Porem o preço desta queda, era a massificação dos produtos, e serviços padronizados, que muitas vezes não atendia a necessidade do pequeno empresario.

Em geral os grandes players cobravam taxas até com baixo custo, porem com acesso a banco e limitado a execução de scripts PHP.

De forma geral, quando o negócio precisava de customização mais avançada, tal como scripts, hospedagem de cgi, ou outros programas em background e portas. O custo do serviço voltava a taxas astronomicas.

Em geral os grandes players, baseavam o custo na baixa demanda de pequenos sites, principalmente aqueles rodando wordpress. Pois poderiam subdividir a mesma máquina em vários hosts. Ganhando em escala.

Raspberry

Imagem 1 de 8 de Raspberry Pi 4 Model B Quad Core 1,5ghz 4gb Ram Avista
raspberry PI 4

O Raspberry PI já comecou de forma disrruptiva, apresentando em uma pequena placa, um sistema operacional robusto.

E hoje principalmente com as novas versões de 4Gb e 8G, com capacidade de processamento e memória realmente impressionante.

Esta pequena maravilha, com um processador de 4 núcleos, consegue dar conta sem muito esforço de um site.

IP Fixo

Nos conectamos na grande rede (Internet), através do protocolo TCP/IP, que por definição ao fazermos, ganhamos uma identidade (IP), esta identidade, diz quem somos e onde estamos.

O Endereço IP faz bem isso, porem de forma geral as operadoras de internet, tem usado IPs dinâmicos, pois aloca estes ips a medida que os usuários solicitam.

Porem empresas como a Alcans, tem cobrado valores expressivamente próximos dos valores praticados normalmente no mercado, porem com ip fixo.

Isso permitiu de forma geral, a construção e hospedagem de sites.

Compra de Domínios

Ter uma máquina, o IP fixo, não permite ainda ter um site na web. É necessário a compra de um domínio.

O que é um dominio de site, como comprar dominio de site e como registrar  dominio?

Domínio de fato é o nome que será encontrado o seu site. No meu caso http://maurinsoft.com.br , o dominio tem diversos formatos e sabores. Podendo ser nacional ou internacional.

Em geral o domínio tem um custo anual que varia em torno de R$69,00 ano. O que não é muito caro. Quase o mesmo que uma pizza por ano.

Conclusão

O uso de equipamentos de baixo custo, e alto rendimento, associado a crescente concorrencia de empresas como a alcans, tem permitido que pequenos empresários consigam o tão sonhado site próprio. Com algum conhecimento técnico, hoje é possivel com um pequeno custo mensal de mais ou menos $50,00 de aumento de energia. Ter seu dominio hospedado em sua própria casa.

en_USEnglish