Home sweet home…

What smell is that?

Yes, it is smell like of new home and this blog is my new home… so, update your bookmark!

Thanks!

Advertisements

Um mesmo projeto para qualquer sistema!

No post anterior eu dizia como alterara um arquivo de projeto (.pro) do Qt Creator para que o compilador pudesse encontrar as devidas bibliotecas. Neste post vou mostrar como modificá-lo novamente para que compile tanto no windows quanto no Linux sem que necessite de modificação alguma.

Tinhamos no final do post anterior o seguinte arquivo .pro:

INCLUDEPATH += C:/OpenCV2.1/include/
LIBS += -LC:/OpenCV2.1/lib/ -lcv210 -lhighgui210

HEADERS += mainwindow.h 
LabelImage.h

SOURCES += mainwindow.cpp 
main.cpp 
LabelImage.cpp

FORMS += mainwindow.ui

RESOURCES += hIP_Recursos.qrc

Este aquivo compila perfeitamente no windows. Agora, se eu fosse levar esse arquivo para compilar no Linux teria que desfazer todas as alterações feitas anteriormente, pois o arquivo que funciona no Linux, é assim:

LIBS += -lcv -lhighgui

(... daqui em diante ele é igual ao anterior ...)

Você pode dizer: “Só precisa apagar uma linha e modificar a outra”. E é isso mesmo. Agora imagine ter que fazer isso várias vezes. A coisa começa a ficar chata. Para resolver esse problema podemos fazer uso de um modo que o qmake (compilador de arquivos .pro) entende. Nesse modo o código do arquivo .pro passaria a ter uma instrução que se comporta como um if … else da linguagem C/C++.

O nosso arquivo .pro final ficaria assim:

win32 {
    INCLUDEPATH += C:/OpenCV2.1/include/
    LIBS += -LC:/OpenCV2.1/lib/ -lcv210 -lhighgui210
}

unix {
    LIBS += -lcv -lhighgui
}

(...)

Aqui estamos dizendo que se a plataforma usada for win32, defina o INCLUDEPATH e a LIBS com seus respectivos valores. Caso não seja uma plataforma win32 e sim um ambiente unix, o qmake não vai entrar no primeiro ambiente de chaves e sim no segundo, definindo então a respectiva LIB. Ainda é possível especificar caso o ambiente seja o MacOs, mas não vamos abordar isso.

Feito a alteração, temos então um arquivo .pro que irá compilar tanto no windows quanto no Linux sem qualquer necessidade de alteração!

Ainda podemos fazer uma última mudança caso você queria. Veja:

win32 {
    INCLUDEPATH += C:/OpenCV2.1/include/
    LIBS += -LC:/OpenCV2.1/lib/ -lcv210 -lhighgui210
} else {
    LIBS += -lcv -lhighgui
}

(...)

Fizemos a inclusão da palavra “else”. Fazendo então com que essa estrutura fica ainda mais parecida com uma estrutura de seleção da linguagem C/C++.

O problema dos Includes no Windows

Hoje me deparei com um problema que sempre amedronta quem desenvolve para a plataforma windows e utiliza bibliotecas que precisam ser indicadas ao compilador não hora da compilação.

Fiz um programa no Linux utilizando o Qt Creator, o programa compilou e rodou perfeitamente. Neste programa eu faço uso da biblioteca OpenCV então para fazer o compilador entendê-la, no Linux, eu implesmente faço os includes (obviamente!) de no arquivo de projeto (.pro) do Qt Creator eu coloco uma linha (se esta não existir):

LIBS += -lcv -lhighgui

Ok, perfeito o código compila e o compilador consegue achar os devidos includes sozinho, pois no Linux todos os .h vão para o mesmo local.

Então eu levei meu código para compilar no windows, usando, é claro, o Qt Creator para windows. O primeiro problema: O compilador não consegue achar os arquivos, estranhos ao Qt, que fiz os includes:

...
#include "opencv/cv.h"
#include "opencv/highgui.h"
...

Neste computador com windows está instalado o OpenCV, então fui verificar se o caminho do diretório de includes do OpenCV estava na variável de ambiente (PATH) do sistema sim, estava. E mesmo assim o compilador não conseguia achar. Então pensei: “Terei que especificar na mão o caminho para os includes”. E foi isso que fiz.

Acabei descobrindo que o arquivo de projeto do Qt Creator é simplesmente fantástico, pois ele aceita que eu faça uma compilação diferente de acordo com cada sistema operacional. Nada que um arquivo make não resolva, mas o arquivo de projeto é bem mais simples que um make.

Então fiz o seguinte. O meu arquivo .pro estava assim:

LIBS += -lcv -lhighgui

HEADERS += mainwindow.h 
LabelImage.h

SOURCES += mainwindow.cpp 
main.cpp 
LabelImage.cpp

FORMS += mainwindow.ui

RESOURCES += hIP_Recursos.qrc

E eu precisava especificar o caminho dos includes, então o modifiquei da seguinte maneira:

INCLUDEPATH += C:/OpenCV2.1/include/
LIBS += -lcv -lhighgui

(... a parte que não mexemos é a mesma de anteriormente ...)

Mandei compilar e deu erro, mas pelo menos o compilador não acusou que não havia encontrado os hearders (.h). E o erro que deu eu tinha a certeza que era em relação as libs que são chamadas na hora da linkagem. Fui até a pasta lib do OpenCV e notei que não havia um arquivo cvlib ou highgui.lib. Esses arquivos deveriam existir pois eu os especifico na linha LIBS.
Veja:

  1. -lcv: Está indicando a biblioteca cv.lib na pasta lib do Opencv;
  2. -lhighgui: Está indicando o arquivo highgui.lib na mesma pasta;

Então notei que haviam os arquivos: cv210.lib e highgui210.lib. Então alterei novamente o arquivo de projeto, mas agora a linha referente as LIBS. Eu também precisava especificar o local desses arquivos pois caso contrário o compilador não iria encontrar:

INCLUDEPATH += C:/OpenCV2.1/include/
LIBS += -LC:/OpenCV2.1/lib/ -lcv210 -lhighgui210

(...)

Depois disso o código compilou normalmente.

No próximo post eu digo como fazer o mesmo arquivo de projeto ser compilado tanto no Linux quanto no windows, sem que haja qualquer alteração!

Desenhando Figuras Geométricas em um QGraphicsView

Desenhar figuras geométricas utilizando Qt é muito fácil. O que precisamos saber antes de tudo é uma coisa que todo livro de Qt quando vai falar de um QGraphicsView diz:

“Para se desenhar objetos em um QGraphicsView é necessário entender que o ato de desenhar algo implica no uso de basicamente três classes: QGraphicsView, QGraphicsScene e QGraphicsItem.”
Onde:

  • QGraphicsItem: é o a base de todo objeto que desenhamos, podendo ser um retângulo (QGraphicsRectItem), elipse (QGraphicsEllipseItem) e vários outros;
  • QGraphicsScene: o(s) objeto(s) precisam ser desenhados em uma cena (QGraphicsScene);
  • QGraphicsView: é o módulo responsável por mostrar a cena juntamente com todos os objetos que ela contém.

Para colocar isso em prática, crie um novo projeto “Qt4 Gui Application” e coloque na janela criada um botão e um QGraphicsView.

No slot clicked do botão (clique com o botão direito em cima do botão > Go to Slot… > Clicked > Ok) coloque o seguinte código:

// construimos a cena
cena = new QGraphicsScene();


// definimos o tamanho da cena
cena->setSceneRect(0,0,700,500);

// setamos a cena no graphicsview
ui->graphicsView->setScene(cena);

// criamos uma elipse
QGraphicsEllipseItem *it = new QGraphicsEllipseItem();

// definimos as dimensões e posição da elipse
it->setRect(5,5,30,30);

// setamos a elipse como sendo um objeto selecionável e móvel.
// isso quer dizer que podemos selecioná-la e movê-la na tela.
it->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);

// colocamos a elipse na cena
cena->addItem(it);

Feito isso, rode o programa. Quando o programa estiver rodando clique no botão inserido e irá aparecer a elipse. Você poderá clicar nela e arrastar pela tela do QGraphicsView.

Obs.: Mesmo que o tamanho da cena seja pequeno, ela vai aumentando seu tamanho automaticamente para poder suportar novos itens e para suportar o movimento dos objetos.

Histogramas com Qwt

Estive empenhado em descobrir como fazer um histograma de uma imagem. Para o Qt existe uma biblioteca de terceiros chamada Qwt. Esta biblioteca é própria para a produção de gráficos dos mais diversos tipos. Instalei no Ubuntu 10.04 pelo próprio gerenciador de pacotes que disponibilizava a versão 5.2.

Depois de olhar alguns códigos e ler uma parte da documentação do Qwt, percebi que a biblioteca não possui uma classe própria para fazer gŕaficos de barras, como é o caso de um histograma, então uma solução foi seguir o estilo do código de exemplo que constrói um histograma. Demorei um pouco para chegar até esta conclusão pois eu gostaria fazer algo diferente, mas que não deu certo para o meu propósito.

Uma coisa que vale a pena ressaltar é que quando você coloca um QwtPlot na sua janela dentro do QtCreator e manda compilar ocorre um erro. Este erro acontece porque o g++ não conseguiu achar a o arquivo qwt_plot.h, que é posto (automaticamente) nos includes do seu mainwindow.h no momento que você adiciona um QwtPlot a sua janela.

A solução é você ir no seu arquivo .pro e adicionar a linha:

INCLUDEPATH += /usr/include/qwt-qt4

Esta linha faz com que o compilador ache os headers (arquivos .h) referente ao Qwt.

Para que o linker também encontre os arquivos corretos é necessário adicionar ao mesmo arquivo .pro a seguinte linha:

LIBS += -lqwt-qt4

Com isso a sua compilação deve correr bem.
A janela do meu teste é mostrada abaixo.

Gnome Sort

Last night I was boring… Holiday and I was without want do what I need to do. So I went to Wikipedia and seach by “Algorithms”, some minutes later I was in this page. More some minutes and I was reading about the “Gnome Sort“. Its was strange because I never had heard about it. Then some momments later  I tried to write a Python code implementing this algorithm… He sounds like Bubble Sort.
Here is the code:

 

#!/usr/bin/python

"""http://pt.wikipedia.org/wiki/Gnome_sort"""

import sys

v = [5, 7, 9, 23, 28, 2, 1, 49, 37, 12]
change = True
    while (change):
        change = False
        for i in range(0, len(v)-1):
            if (v[i] > v[i+1]):
                aux = v[i]
                v[i] = v[i+1]
                v[i+1] = aux
                change = True

print v

Splitting and Joining Big Files at Ubuntu

Its a fast tip.
To split a big file in some parts of X size, use the next command at your shell:

$ split --bytes=200M --verbose bigFile.tar.gz ./bigFile

The command above split your file (bigFile.tar.gz) in several others files of 200Mb, look the 200M. So will be created some files with the names like: bigFileaa, bigFileab, bigFileac…

To merge the splitted parts type this:

$ cat bigFile* > bigFile.tar.gz

Thats all…