OpenGL로 구현한 프로그램에 화면 캡쳐 기능이 필요해서 오동님 블로그를 참조해서 사용하다가

리눅스(Qt)에서도 사용하게 될 일이 있어서 수정한 거 올립니다.

확인 결과 MFC, Win32 API 에서 문제 없이 잘 동작하며 리눅스에의 확인은 제 친구가 했는 데

리눅스에서도 문제 없이 잘 동작한다고 하네요.(비트맵 관련 구조체가 없어서 구조체는 직접 추가했다고 함)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
void ScreenCapture( const char *strFilePath )
{
    //비트맵 파일 처리를 위한 헤더 구조체
    BITMAPFILEHEADER    BMFH;
    BITMAPINFOHEADER    BMIH;
 
    int nWidth = 0;
    int nHeight = 0;
    unsigned long dwQuadrupleWidth = 0;     //LJH 추가, 가로 사이즈가 4의 배수가 아니라면 4의 배수로 만들어서 저장
 
    GLbyte *pPixelData = NULL;              //front buffer의 픽셀 값들을 얻어 오기 위한 버퍼의 포인터
 
#ifdef WIN32
    //윈도우의 클라이언트 영역 좌표
    RECT ImageRect;
    GetClientRect( *m_hWndCopy, &ImageRect );          
 
    //이미지 영역 좌표를 이용하여 실제 이미지의 사이즈를 계산
    nWidth  = ImageRect.right - ImageRect.left;     //윈도우 버전의 경우 사이즈 변경이 되므로 그때그때 조사
    nHeight = ImageRect.bottom - ImageRect.top;
 
#else
    nWidth  = 1024;     //(나의 경우)리눅스에서의 경우 해상도 고정이므로 그 값을 입력
    nHeight = 768;
 
#endif
 
    //4의 배수인지 아닌지 확인해서 4의 배수가 아니라면 4의 배수로 맞춰준다.
    dwQuadrupleWidth = ( nWidth % 4 ) ? ( ( nWidth ) + ( 4 - ( nWidth % 4 ) ) ) : ( nWidth );
 
    //비트맵 파일 헤더 처리
    BMFH.bfType  = 0x4D42;      //B(42)와 M(4D)에 해당하는 ASCII 값을 넣어준다.
    //바이트 단위로 전체파일 크기
    BMFH.bfSize  = sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER ) + ( dwQuadrupleWidth * 3 * nHeight );
    //영상 데이터 위치까지의 거리
    BMFH.bfOffBits = sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER );
 
    //비트맵 인포 헤더 처리
    BMIH.biSize             = sizeof( BITMAPINFOHEADER );       //이 구조체의 크기
    BMIH.biWidth            = nWidth;                           //픽셀 단위로 영상의 폭
    BMIH.biHeight           = nHeight;                          //영상의 높이
    BMIH.biPlanes           = 1;                                //비트 플레인 수(항상 1)
    BMIH.biBitCount         = 24;                               //픽셀당 비트수(컬러, 흑백 구별)
    BMIH.biCompression      = BI_RGB;                           //압축 유무
    BMIH.biSizeImage        = dwQuadrupleWidth * 3 * nHeight;   //영상의 크기
    BMIH.biXPelsPerMeter    = 0;                                //가로 해상도
    BMIH.biYPelsPerMeter    = 0;                                //세로 해상도
    BMIH.biClrUsed          = 0;                                //실제 사용 색상수
    BMIH.biClrImportant     = 0;                                //중요한 색상 인덱스
 
    pPixelData = new GLbyte[ dwQuadrupleWidth * 3 * nHeight ];  //LJH 수정
 
    //프런트 버퍼로 부터 픽셀 정보들을 얻어온다.
    glReadPixels(
        0, 0,                   //캡처할 영역의 좌측상단 좌표
        nWidth, nHeight,        //캡처할 영역의 크기
        GL_BGR,                 //캡처한 이미지의 픽셀 포맷
        GL_UNSIGNED_BYTE,       //캡처한 이미지의 데이터 포맷
        pPixelData              //캡처한 이미지의 정보를 담아둘 버퍼 포인터
        );
 
    {//저장 부분
        FILE *outFile = fopen( strFilePath, "wb" );
        if( outFile == NULL )
        {
            //에러 처리
            //printf( "에러" );
            //fclose( outFile );
        }
 
        fwrite( &BMFH, sizeof( char ), sizeof(BITMAPFILEHEADER), outFile );         //파일 헤더 쓰기
        fwrite( &BMIH, sizeof( char ), sizeof(BITMAPINFOHEADER), outFile );         //인포 헤더 쓰기
        fwrite( pPixelData, sizeof( unsigned char ), BMIH.biSizeImage, outFile );   //glReadPixels로 읽은 데이터 쓰기
 
        fclose( outFile );  //파일 닫기
    }
 
    if ( pPixelData != NULL )
    {
        delete pPixelData;
    }
}

아래는 위의 함수로 저장한 bmp파일들입니다.



'QT > OpenGL' 카테고리의 다른 글

Qt프로젝트에 OpenGL 사용하기  (0) 2015.04.13
OpenGL에서 팝업(Popup) 메뉴 사용하기  (0) 2015.04.08
QT에서 OpenGL 사용하기  (0) 2015.04.03
Posted by 모래반지빵냐빵냐
,

ui 에디터나 아니면 

맴버 함수에서 setStyleSheet 를 이용하면 된다.

어쨌뜬 사용법은 

CSS하고 같다.

예를들어서

QWidget{
background-image:url("경로");
}
근데 위와 같은 식으로 하면

QWidget을 상속 받은 놈들이 다 적용이 되기때문에

그것보다는 

#objectName{
.....
}
이렇게 하면 상속받은 놈은 관계 없이 이놈만 스타일 쉬트가 적용된다.

위에 방법은 커뮤니티에서 봤다.  


Qt는 이런것을 쓰기에  디자인을 적용하는게 겁나게 편하다.. 


'QT > Basics' 카테고리의 다른 글

Qt5 VS2010으로 사용하기 [출처] Qt5 VS2010으로 사용하기  (0) 2015.04.13
제목표시줄 없애기  (0) 2015.04.08
사용자 정의 클래스.  (0) 2015.04.08
실행파일 아이콘 만들기  (0) 2015.04.08
QWidget  (0) 2015.04.08
Posted by 모래반지빵냐빵냐
,

뭐 어려운건 없다..


생성자에서든 어디서  메뉴를 생성 해 준다.

그리고   

mouseReleaseEvent(QMouseEvent*)를 오버라이딩을 해서 사용한다.


예)

01.MyWidget::MyWidget()
02.{
03......
04.//메뉴 생성
05.QMenu menu = new QMenu(this);
06...
07.....  메뉴 추가
08...
09.////////
10.......
11.}
12. 
13.void MyWidget::mouseReleaseEvent(QMouseEvent* e)
14.{
15.if(  e->button() == Qt::RightButton )
16.{
17.menu->popup(e->pos());
18.}
19.}



위와 같이 처리 하면된다..


사용된 스샷




'QT > OpenGL' 카테고리의 다른 글

Qt프로젝트에 OpenGL 사용하기  (0) 2015.04.13
OpenGL 화면 캡쳐해서 BMP 파일로 저장  (0) 2015.04.08
QT에서 OpenGL 사용하기  (0) 2015.04.03
Posted by 모래반지빵냐빵냐
,

전에 있는거들은.. 죄다 ..

Qt에서 제공되는 클래스를 사용했다..

이번에는 내가 원하는 클래스를 만들어 본다.

접기

#ifndef USERCLASS_H
#define USERCLASS_H

#include <QtGui/QWidget>
#include "ui_userclass.h"

class UserClass : public QWidget
{
    Q_OBJECT

public:
    UserClass(QWidget *parent = 0);
    ~UserClass();

private:

};

#endif // USERCLASS_H

///////////////////////////////////
userclass.cpp
#include "userclass.h"

UserClass::UserClass(QWidget *parent)
    : QWidget(parent)
{

}

UserClass::~UserClass()
{

}

/////////////////////////

main.cpp

#include <QtGui>
#include <QApplication>
#include "userclass.h"
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    
    UserClass user;
    
    user.show();
    return a.exec();
}

실행 결과


접기


소스를 보면.. QWidget클래스를 상속을 받고 있다..

그리고 생성자와 소멸자가 있다. 
생서자의 경우는 QWidget* 를 매개변수로 이용한다.

그리고 보면 Q_OBJECT 라는 매크로가 있다.

요 메크로를 안적어놓으면 connect가 작동 안한다.

고로 시그널과 슬롯을 사용하길 원한다면 Q_OBJECT를 써 놓으면 된다.

그리고 Q_OBJECT를 안쓰면 컴파일 하고 폴더를 살펴보면  debug 폴더에 o 파일 밖에 없다.

하지만 Q_OBJECT를 사용하면 moc_클래스이름.cpp 파일이 생긴것을 볼 수 있다.

저 파일은 MOC(Meta Object Compiler)가 만들어 놓은 것이다.

자세한 것은 실험을 해보면 알 수 있다.

그리고 실행결과는 그냥 창 하나만 뜨고 만다.

이유야.. 뭘 추가한게 없기 때문이다.

그래서 이 창에다가 버튼을 한개 넣고 버튼을 클릭하면 메시지 박스가 나오는것을 할것이다.

접기

///////////////////////
#ifndef USERCLASS_H
#define USERCLASS_H

#include <QtGui/QWidget>
#include "ui_userclass.h"
#include <QPushButton>

class UserClass : public QWidget
{
    Q_OBJECT

public:
    UserClass(QWidget *parent = 0);
    ~UserClass();

public slots:
    void onClicked();
private:

    QPushButton* bt;
};

#endif // USERCLASS_H
/////////////////////////

userclass.cpp
#include "userclass.h"

UserClass::UserClass(QWidget *parent)
    : QWidget(parent)
{

    bt = new QPushButton(this);
    bt->setText("button");

    QObject::connect(bt,SIGNAL(clicked()),this,SLOT(onClicked()));

}

UserClass::~UserClass()
{

}

#include<QMessageBox>
void UserClass::onClicked()
{
    QMessageBox::about(0,"Button clicked","Click!!");
}

/////////////////
main.cpp 위와 동일

/////////////////
실행결과

접기


소스를 보면 음영을 한 부분을 주목하면 된다.

public slots: 라고 써있다. 이 밑에다가 쓰는 것들은 모두 슬롯이라는 의미이다.
signal 도 마찮가지로 public signal: 이라 사용한다.

위에 있는 방식을 토대로 Qt는 만들어지게 된다.

물론 이런식으로 만들지는 않는다. ui 편집기라는게 있어서 편하게 편집을 할 수 있다.

'QT > Basics' 카테고리의 다른 글

제목표시줄 없애기  (0) 2015.04.08
스타일쉬트(Style Sheet) 사용하기.  (0) 2015.04.08
실행파일 아이콘 만들기  (0) 2015.04.08
QWidget  (0) 2015.04.08
QT에서 Mouse를 Control 하는 방법  (0) 2015.04.03
Posted by 모래반지빵냐빵냐
,

말 그래도 http에 연결을 해서  받은 데이터를 화면에 뿌려 보는거다.

쉽게 말하자면  인터넷을 키고  원하는 사이트를 입력하면 그 사이트가 뜨는걸 볼 수 있다.

그 사이트를 보는걸 해보겟다는거다. 당연히 사용되는건 Qt 4.6 버젼이다.

-----------------------------------
http 연결에 쓰는 클래스..

QNetworkAccessManager          이 클래스는 연결하고 request 를 보내거나 하는 클래스이다.
QNetworkReply                         이 클래스는 request를 보냈을때 서버에서 보낸 걸 받는 클래스이다. 

위에 있는 클래스들은 api에 가면 자세하게 설명이 되어있기때문에.. api를 참조.. 
------------------------------------

소스 닫기

소스를 보면 더 쉽게 이해 될 수 있을것이다.

#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QSslError>

class htmlRead : public QWidget
{
    Q_OBJECT

public:
    htmlRead(QWidget *parent = 0);
    ~htmlRead();

public slots:
    //이 슬롯은 QNetworkReply에서 readyRead()라는 시그널이 발생할때 처리하는 메소드이다.
    void slotReadyRead();
    //이 슬롯은  QNetworkReply에서   error라는 시그널이 발생했을때 처리하는 메소드이다.      
    void slotError(QNetworkReply::NetworkError err);
    
    //이 슬롯은  QNetworkReply에서 ssl 에러 처리를 하는 메소드이다.
    void slotSslErrors(QList<QSslError> err);
    // 이 슬롯은 데이터가 다 전송되면 NetworkAccessManager에서 발생하는 시그널인 finished를 처리하는 메소드이다.
    void replyFinished(QNetworkReply* reply);

private:
    //ui에는 textBrowser를 적당하게 배치해놧다.
    Ui::htmlReadClass ui;

    QNetworkReply *reply;
    QByteArray data ;
};


/////////////////////////////////////////////////
// htmlread.cpp

#include "htmlread.h"

htmlRead::htmlRead(QWidget *parent)
    : QWidget(parent)
{
    ui.setupUi(this);

     QNetworkAccessManager *manager = new QNetworkAccessManager(this);
     connect(manager, SIGNAL(finished(QNetworkReply*)),
             this, SLOT(replyFinished(QNetworkReply*)));
     
    //여기서 주의 할 점은 다른곳에서 get 메소드를 사용하면 readyRead() 시그널이 바로 발생하지 않는다.
    // 고로 사용할 때 주의를 해야한다. 즉 get()을 불러온 그 함수가 끝나야 readyRead()가 발생한다.

     reply =  manager->get(QNetworkRequest(QUrl("http://www.naver.com")));
     connect(reply, SIGNAL(readyRead()), this, SLOT(slotReadyRead()));
     connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
             this, SLOT(slotError(QNetworkReply::NetworkError)));
     connect(reply, SIGNAL(sslErrors(QList<QSslError>)),
             this, SLOT(slotSslErrors(QList<QSslError>)));

}

htmlRead::~htmlRead()
{

}

void htmlRead::replyFinished(QNetworkReply* reply)
{
    QString string(data);

    ui.textBrowser->setHtml(string);

}
#include <qdebug.h>

void htmlRead::slotReadyRead()
{
    //reply객체에서 데이터를 읽어오는 메소드이다. 
    //readAll()의 경우는 모든 데이터를 한번에 뽑아오는 메소드이다. 
    // 그것 말고 도 많이 있다. read()도 있고 readLine()도 있다. 더 자세한것은 
    // QIODevice를 참조..
    data = reply->readAll();

}

void htmlRead::slotError(QNetworkReply::NetworkError err )
{

}

void htmlRead::slotSslErrors(QList<QSslError> err)
{

}


소스 닫기


실행결과 :




위에 소스를 보면 알 수 있다.



근데 문제는 해보면 제대로 안뜨는걸 볼 수 있다.

그건 어쩔 수 없다. 일반적인 사이트들은 html만 사용된게 아니라 그림에 자바스크립트,  플래시 기타등등이 사용되었기 때문에 이상하게 나와도 어떻게 할 방도가 없다. 제대로 나오게 하고 싶다면 webkit을 사용하는 수 밖에... 아니면 직접만들던가.

Posted by 모래반지빵냐빵냐
,

Qt로 프로그램을 만들고 나서 보면 아이콘이 xp에서 보면 도스 프로그램 아이콘 같이 나온다..


(나는 윈도우7을 쓰기때문에 이런식으로 나온다..)

그걸 바꿔보자..

각 운영체제 별로 다른데..

지금 나는 윈도우를 쓰고 있으므로 윈도우 용으로 소개를 하겠다..

여기 들어가면 자세하게 설명 되어있다.. 물론 영어로! 

http://qt.nokia.com/doc/4.6/appicon.html

그냥 텍스트 파일을 만든다..

그걸 편집하도록 하자..

aaa.txt를 메모장으로 연다..

IDI_ICON1      ICON      DISCARDABLE         "아이콘 이름.ico"

위에 처럼 적어 놓고 저장을 할때.. 이름.rc 로 저장한다.

아이콘은 반드시.. ico라는 확장자를 가져야한다.. 그림파일로 하면 안된다.. 

그림 파일이면 변환을 시켜서 ICO로 만들도록..

그리고 IDE로 들어가서..

pro 파일을 연다.

그리고 맨 아래에다가..

RC_FILE = 이름.rc

처럼 만든다..

그리고 qmake를 실행 해주고..

프로그램을 빌드하면 아이콘이 들어가 있는것을 볼 수 있다.



이렇게 바뀐다.

'QT > Basics' 카테고리의 다른 글

제목표시줄 없애기  (0) 2015.04.08
스타일쉬트(Style Sheet) 사용하기.  (0) 2015.04.08
사용자 정의 클래스.  (0) 2015.04.08
QWidget  (0) 2015.04.08
QT에서 Mouse를 Control 하는 방법  (0) 2015.04.03
Posted by 모래반지빵냐빵냐
,

강좌랄것도 없음.

그냥 대충 설명하는 정도로 하겠음  .

Qt를 사용하기 위해서는 최소한 C++ 
문법은 알아야할것이다.
어쨌든 모든 프로그램들 보면 항상 "Hello World"  가 나오는걸 한다.

고로 나도 하겠음.

그리고 IDE는  이클립스던 Qt Creator 아무거나 키고 하면 됨.

이클립스의 경우 file에서 new -> Qt Gui Project를 선택 후.. next를 계속 누른다.



그리고 Project Explorer 에서 main.cpp를 찾는다. 



이후 부터는 위에꺼는 설명 안함.


소스..

#include <QtGui>
#include <QApplication>

#include <QLabel>                             //QLabel이라는걸 include 한다.
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QLabel 
t("<b>Hello World</b>");         // 이렇게 처 넣는다.

    t.show();                                        //show 메소드를 호출.

    return a.exec();
}


실행 결과



위에와 같이 나온다.  Qt는 Label도 혼자서 창으로 띄울 수 있다.  
MFC도 할 수야 있겠지만 Qt 처럼 간단하게는 안됀다. 워낙 구려서..
그리고 HTML 테크가 먹힌다. Html 을 안다면 한번 해보도록 한다.

Qt는 main 부터 시작을 한다. 물론 내부적으로는 winmain이지만 프로그래머가 편하게 이런식으로 만들어져있다.
QApplication 이 클래스를 안써주면 동작을 안한다. 
나도 어떻게 돌아가는건지는 모르겠으나  QApplication이 각종 라이브러리 정보를 읽어오고 WinMain을 실행하는 것 같다. 넘어가서..

show 메소드 .. 메소드 이름이 아주 직관적이다.   보여줘라 라는 뜻으로 사용하면 결과와 같이
창이 뜬다.    이클립스 같은걸로 보면  인라인 함수로 setVisible(true) 해가지고 만들어 졌다.
setVisible 처럼 쓰기 귀찮은거 보다 show가 편한다.

그리고 이런걸 처음 해본 사람이 아니라면 그냥 http://qt.nokia.com/doc/4.6/index.html 여기 들어가서 하면 충분히 할 수 있다.

'QT > Examples' 카테고리의 다른 글

QT로 Serial 통신 구현하기 - 1  (0) 2015.04.15
QT에서 이미지 출력하는 방법  (0) 2015.04.03
Qt에서 OpenCV 사용하기  (0) 2015.03.30
Posted by 모래반지빵냐빵냐
,

QWidget

QT/Basics 2015. 4. 8. 15:22

QWidget 이란..

간단하게 실행을 해보면 안다.

#include <QtGui>
#include <QApplication>

#include <QWidget>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

///////////////////
    QWidget widget;

    widget.show();
//////////////////////
    return a.exec();
}
실행결과 



실행하면 그냥 창 한개 뜬다.

이게 QWidget의 역활이다. 창을 띄우는 역활을 한다. 물론 이거 하나만으로는 잘 안쓰인다.

이 Widget안에다가 여러가지 컴포넌트를 넣고 한다.

그리고 많은 Qt 클래스들이 이 클래스를 상속받아서 쓰고 있다.

전에 한 QLabel 도 QWidget을 상속 받았기 때문에 독자적으로 띄울 수 있는것이다.

밑에 있는 주소에 가면  QWidget에 대해 잘 설명 되어있다.. 그 중에 몇개만 설명한다.

http://qt.nokia.com/doc/4.6/qwidget.html

void addAction ( QAction * action )   
요 메소드는 액션을 추가하는 메소드이다.. 액션이란게 여러가지 있는데.. 메뉴를 추가 한다던가 
숏컷, 그러니까  단축키를 추가한다던가 여러가지를 추가 할 수있다.

void setGeometry ( int x, int y, int w, int h )
위치를 설정하는 메소드이다.. x 와 y는 위치 w 는 넓이  h 높이이다.

void setWindowTitle(const QString s)
이 메소드는  창의 제목을 설정하는 메소드이다.

void resize(int w, int h)
이 메소드는 창의 크기를 조절 한다.


끗.. 별거 없다.. 도큐먼트 보면 영어로 잘 설명 되어있으니까  거기 가서 보면 된다.

=============================
이전꺼..
1. Hello World

저작자 표시 비영리 동일 조건 변경 허락


'QT > Basics' 카테고리의 다른 글

제목표시줄 없애기  (0) 2015.04.08
스타일쉬트(Style Sheet) 사용하기.  (0) 2015.04.08
사용자 정의 클래스.  (0) 2015.04.08
실행파일 아이콘 만들기  (0) 2015.04.08
QT에서 Mouse를 Control 하는 방법  (0) 2015.04.03
Posted by 모래반지빵냐빵냐
,

출처 : http://ko11011.tistory.com/trackback/8


QT에서 이미지를 로드하여 화면에 출력하는 방법을 알아보자

 

순서

QImage로 이미지를 불러온다. -> QPixmap에 옮긴다. -> QLabel에서 QPixmap를 불러와서 화면에 출력한다.

 

코드를 보며 설명하겠다.

 

 

#include <QImage>              //QImage를 사용하기 위한 라이브러리

#include <QPixmap>             //QPixmap를 사용하기 위한 라이브러리

#include <QLabel>              //QLabel를 사용하기 위한 라이브러리

#include <QMessageBox>         //QMessageBox를 사용하기 위한 라이브러리

 

//해당 함수로 이미지를 로드한다. ( 직접 제작한 함수이다.)

void MainWindow::imgload()

{

    QImage *Img = new QImage();       //이미지를 로드하기 위한 QImage 선언

    QPixmap *buffer = new QPixmap();  //버퍼로 사용할 QPixmap 선언

 

    if(Img->load(":/img/1.jpg"))      //이미지를 로드한다.

{

        *buffer = QPixmap::fromImage(*Img);   //이미지를 버퍼에 옮긴다.

        *buffer = buffer->scaled(Img->width(),Img->height()); //이미지 사이즈 조절

    }

    else // 이미지 로드 실패

{

        QMessageBox::about(0, QString::fromAscii("Image load Error"),QString::fromAscii    ("Image load Error"));

    }

 

    QLabel *lbView = new QLabel(this); //이미지를 화면에 출력할 QLabel 선언

    lbView->setPixmap(*buffer);       //버퍼에 있는 이미지를 QLabel에 출력

    lbView->resize(buffer->width(),buffer->height()); //QLabel의 크기를 이미지 사이즈에 맞추어 조절한다.

    lbView->move(0,0);                //QLabel위치 조정

    lbView->show();                   //QLabel 를 보여준다.

}

 

 

 

 

변수는 총 3개 필요하다.

1) QImage         이미지를 불러올 때 이미지라는 것을 알기 위해 사용한다.

2) QPixmap        : QLabel에 이미지를 옮길 때 사용하는 중간 버퍼

3) QLabel          실제로 화면에 출력해주기 위한 Label

 

QImage load함수를 사용하여 이미지를 로드한다.

if(Img->load(":/img/1.jpg"))   //이미지를 로드한다.

 

 

bool QImage::load ( const QString & fileName, const char * format = 0 )

 

첫번째 인자 : 파일이름이 들어간다.

두번째 인자 : 파일의 포멧이 들어간다. (생략 가능하다.)

 

리턴값 : 이미지 로드가 성공시 TRUE을 리턴하고 실패시 FALSE를 리턴한다.

 

 

QPixmap static 함수를 사용하여 QImage 변수형을 QPixmap형식으로 전환하여 옮긴다.

 

*buffer = QPixmap::fromImage(*Img);

 

 

QPixmap QPixmap::fromImage ( const QImage & image, Qt::ImageConversionFlags flags = Qt::AutoColor ) [static]

 

첫번째 인자 : 변환할 QImage

두번째 인자 : Qt::ImageConversionFlags 설정 (기본값이 설정되어있어 변경하지 않았다자세한 내용은 필자도 모른다. Qt::ImageConversionFlags를 참고 )

 

 

 

QLabel setPixmap 함수를 이용하여 QPixmap에 옮긴 이미지를 QLabel에 출력한다.

 

lbView->setPixmap(*buffer);

 

 

Public Slots

        void    setPixmap ( const QPixmap & )

첫번째 인자 : 출력할 QPixmap

'QT > Examples' 카테고리의 다른 글

QT로 Serial 통신 구현하기 - 1  (0) 2015.04.15
Hello World를 띄우자.  (0) 2015.04.08
Qt에서 OpenCV 사용하기  (0) 2015.03.30
Posted by 모래반지빵냐빵냐
,

출처 : http://guimong.tistory.com/trackback/37

QtInOpengl.zip

QT 응용프로그램에서 OpenGl를 사용하기 위해서는 QtOpenGL과 OpenGL 라이브러리에 링크를 해야 합니다.

라이브러리와 링크하기 위해서는 프로젝트 파일에 QT+= opengl 를 추가해주어야 합니다.

[test.pro]

사용자 삽입 이미지









QGLWidget을 이용하면 표준 OpenGl 함수를 그대로 이용할 수 있습니다.
[test.h]

사용자 삽입 이미지






























protected에 선언된 paintGL()는 위젯이 그려질때마다 호출되는 paint()이벤트를 재정의 한것이고, mousePressEvent(), mouseMoveEvent()는 각각 마우스를 눌렀을때와 움직였을때를 재정의한 것입니다.

private에 선언된 함수와 변수들은 실제로 OpelGl를 그리기 위한 함수와 변수들입니다.
자세한 코드는 첨부파일을 받으셔서 보시기 바랍니다.
[결과]

사용자 삽입 이미지










Posted by 모래반지빵냐빵냐
,

출처 : http://ko11011.tistory.com/trackback/9


QT에서 Mouse Control 하는 방법

 

 QT에서 Main이 되는 Class  QWidget이다.

QWidget에서 virtual function으로 mouse control하기 위한 함수를 제공한다.

 

virtual void   mouseDoubleClickEvent ( QMouseEvent * event );

virtual void   mouseMoveEvent ( QMouseEvent * event );

virtual void   mousePressEvent ( QMouseEvent * event );

virtual void   mouseReleaseEvent ( QMouseEvent * event );

 

해당 함수를 재정의 (오버라이딩  overiding) 를 해서 사용하면 된다.

 

해당 함수에서 event->x()  event->y()로 현재 마우스의 좌표를 알 수가 있다.

마우스 좌표는 창의 좌측 상단을 기준으로 0, 0으로 되어있다.

'QT > Basics' 카테고리의 다른 글

제목표시줄 없애기  (0) 2015.04.08
스타일쉬트(Style Sheet) 사용하기.  (0) 2015.04.08
사용자 정의 클래스.  (0) 2015.04.08
실행파일 아이콘 만들기  (0) 2015.04.08
QWidget  (0) 2015.04.08
Posted by 모래반지빵냐빵냐
,

http://homepages.inf.ed.ac.uk/rbf/CVonline/LOCAL_COPIES/DIAS1/


Tsai Camera Calibration

 

Camera calibration and pose estimation are major issues in computer vision since they are related to many vision problems such as stereovision, structure from motion, robot navigation and change detection [Tsai86,Faugeras93Fitzgibbon98Kumar94Wilson94Heikkila97Pollefeys00Zhang00Debevec01Kurazume02].

Camera calibration consists in the estimation of a model for an un-calibrated camera. The objective is to find the external parameters (position and orientation relatively to a world co-ordinate system), and the internal parameters of the camera (principal point or image centre, focal length and distortion coefficients). One of the most used camera calibration techniques is the one proposed by Tsai [Tsai86]. Its implementation needs corresponding 3D point co-ordinates and 2D pixels in the image. It uses a two-stage technique to compute: first, the position and orientation and, second, the internal parameters of the camera.

In many computer vision applications a camera already calibrated is considered. This means that a model of the internal camera parameters is available. This model can be provided by the manufacturer or computed using a known target (usually a chessboard plane) [Heikkila97Zhang00]. This situation, called pose estimation, just needs to recover the six parameters relative to the position and orientation of the camera. Some methods for pose estimation as well as a sensitivity analysis can be found in [Kumar94].

One of the most popular calibration method is the well-known Tsai camera calibration method that is suitable for a wide area of application since it can deal with coplanar and non-coplanar points. It also offers the possibility to calibrate internal and external parameters separately. This option is particularly useful since it gives the possibility to fix the internal parameters of the camera, when known, and carry out only pose estimation.

An online implementation of the Tsai calibration algorithm proposed by Reg Willson is available here.

 

Tsai Camera Model

The Tsai model is based on a pinhole perspective projection model and the following eleven parameters are to estimate:

f - Focal length of camera,

k - Radial lens distortion coefficient,

Cx, Cy - Co-ordinates of centre of radial lens distortion,

Sx - Scale factor to account for any uncertainty due to imperfections in hardware timing for scanning and digitisation,

Rx, Ry, Rz - Rotation angles for the transformation between the world and camera co-ordinates,

Tx, Ty, Tz - Translation components for the transformation between the world and camera co-ordinates.

 

Figure 1: Tsai Camera re-projection model with perspective projection and radial distortion.

 

The transformation from world (Xw,Yw,Zw) to image (Xi,Yi,Zi) co-ordinates considers the extrinsic parameters of the camera (Translation T and Rotation R) within the equation:






where R and T characterize the 3D transformation from the world to the camera co-ordinate system and are defined as follows:

with

(Rx,Ry,Rz) the Euler angles of the rotation around the three axes.

(Tx,Ty,Tz) the 3D translation parameters from world to image co-ordinates.

The transformation from 3D position (in the image co-ordinate frame) to the image plane is then computed through the following steps (see Figure 1):

Transformation from 3D world co-ordinates (Xi,Yi) to undistorted image plane (Xu,Yu) co-ordinates

Transformation from undistorted (Xu,Yu) to distorted (Xd,Yd) image co-ordinates

where

, and k is the lens distortion coefficient.

Transformation from distorted co-ordinates in image plane (Xd,Yd) to the final image co-ordinates (Xf,Yf) are:

with

(dx,dy): distance between adjacent sensor elements in the X and Y direction. dx and dy are fixed parameters of the camera. They depend only on the CCD size and the image resolution, (Xf,Yf) are the final pixel position in the image.

References

[Debevec01]P. Debevec, 
Reconstructing and Augmenting Architecture with Image-Based Modelling, Rendering and Lighthing.
Proceedings of the International Symposium on Virtual Architecture (VAA’01), pp. 1-10, Dublin 21-22 June 2001.
[Faugeras93]O. Faugeras,
Three-Dimensional Computer Vision.
MIT Press, 1993.
[Fitzgibbon98]A.W. Fitzgibbon, A. Zisserman,
Automatic 3D Model Acquisition and Generation of New Images from Video Sequences.
In Proceedings of European Signal Processing conference (EUSIPCO '98), Rhodes, Greece, pages 1261-1269, 1998.
[Heikkila97]J. Heikkila, O. Silven, 
A Four-Step Camera Calibration Procedure with Implicit Image Correction. 
In Proc. of IEEE Computer Vision and Pattern Recognition, pp. 1106-1112, 1997.
[Kumar94]R. Kumar and A. Hanson. 
Robust Methods for Estimating Pose and a Sensitivity Analysis. 
CVGIP-Image Understanding, Vol. 60, No. 3, pp. 313-342, 1994.
[Kurazume02]R. Kurazume, K. Nishino, Z. Zhang, and K. Ikeuchi, 
Simultaneous 2D images and 3D geometric model registration for texture mapping utilizing reflectance attribute 
Proc. of Fifth Asian Conference on Computer Vision (ACCV), Vol. I, pp. 99-106, January 2002.
[Pollefeys00]M. Pollefeys, 
3D Modelling from Images, 
Tutorial notes, in conjunction with ECCV 2000, Dublin, Ireland, June 2000.
[Tsai86]R.Y. Tsai,
An Efficient and Accurate Camera Calibration Technique for 3D Machine Vision.
Proceedings of IEEE Conference on Computer Vision and Pattern Recognition, Miami Beach, FL, pp. 364-374, 1986.
[Tsai87]R.Y. Tsai, 
Metrology Using Off-the-Shelf TV Cameras and Lenses 
IEEE Journal of Robotics and Automation, Vol. 3, No. 4, pp. 323-344, August 1987.
[Wilson94]Reg G. Willson
Modeling and Calibration of Automated Zoom Lenses
Ph.D. thesis, Department of Electrical and Computer Engineering,Carnegie Mellon University, January 1994.
[Zhang00]Z. Zhang. 
A flexible new technique for camera calibration. 
IEEE Transactionson Pattern Analysis and Machine Intelligence, Vol. 22, No. 11, pp. 1330-1334, 2000

Author: Paulo Dias at IEETA/Universidade de Aveiro, Portugal - 05/11/2003

'Camera Calibration' 카테고리의 다른 글

Transformations  (0) 2015.04.01
Posted by 모래반지빵냐빵냐
,

http://blog.naver.com/slime321/50013775951

만약에 당신의 computer graphics modeling system 이 모든 object 들에게 같은 위치와 같은방위,  같은 크기 만을 제공하여 줄 수 있다면... 그 modeling system 의 사용은 극히 제한적으로 이루어 질 수 밖에 없을 것입니다..

 

우리가 실제로 작업을 하기 위해서는 공간상에서 object 를 움직이고..

그것의 방위를 회전 시키며.. 크기를 바꾸어 줄 수 있어야 합니다..

이러한 세 가지의 변화를 합쳐서 우리는 transformations 라고 부르게 됩니다..

 

우리가 작업 공간에서 object 의 위치를 바꾸어 주는 것을 그 object 를 Move 혹은 Translate시킨다.. 라고 부르게 됩니다..

object 를 이동시키게 될 때 우리는 three - dimensional coordinate system 에서 사용하였던개념을 그대로  적용 시키게 되어 집니다..

우리가 앞에서 다루었던 three axis 의 coordinate system 에서의 위치 개념과 동일하게 생각 하시면 됩니다..

 

일반적으로 object 를 움직이게 되면 object 는 three axis   즉 X, Y, Z 방향으로 이동하게

되고 ..  이렇게 이동 되어진 값을 우리는 translation X, translation Y, translation Z 로 이야기하게 되고.. translate x,y,z 혹은 translate (x,y,z) 또는 move x,y,z 로 부르게 되어 집니다..

 

예를 들어 translate ( 5, 3, -2) 로 표현되어 진다면...

X 방향으로 5 만큼 이동하고, Y 방향으로 3만큼 이동하고, Z 방향으로는 음의 방향으로

2만큼 이동하였다는 의미를 갖게 됩니다..

 

 


 

                                               Fig 1

 

그림 1 의 cube 는 원점 (0,0,0) 에서 오른쪽으로 5만큼 , 위쪽으로 3만큼 뒤쪽으로 2만큼

이동하였다는 것을 알 수 있습니다.. 위의 (5,3,-2) 란 위와 같은 형태의 움직임을 이야기

하게 되는 것입니다..

 

object 이 움직임에서 기울기나 방향의 전환이 발행하도록 움직이는 것을 우리는 rotate

라고 부르게 됩니다..  이것은 가장 기본적인 transformation 의 두번째 형태 입니다..

 

rotate 에 대한 이해를 위해 아래의 그림 처럼 밀랍 인형이 서 있는 형태를 생각해 보도록

하겠습니다..

 

 


 

위의 그림 (a) 의 경우를 보면 머리가 위를 향하고 발이 아래로 향한 채 꼬챙이에 꽃혀 꽂꽂이 서있는형태를 보여 주고 있습니다..

그림 (b) 의 경우 처럼 Y axis 에 의해 회전하는 형태를 보여 준다면 우리는 "Y 축으로 회전 한다" 라고 이야기 하게 됩니다..

그림 (c) 는 Z 축으로 회전하는 모습을 보여 주고 있고 , (d) 의 경우는 X 축으로 회전하는 모습을 보여주고 있습니다..

이러한 회전은 한 점을 출발하여 다시 그 지점으로 되돌아오는 것을 완전한 회전으로 생각하여 360도의 값으로 나타내어 집니다..

어떤 시스템에서는 degree 보다는 radians 를 단위로 사용하기도 하는데 One radian 은 57.29578 degree의 값을 가지게 됩니다..

 

Rotations  와 같은 translations 는 일반적으로 3 가지의 값을 가지고 사용되어 지게 되는데 이 세 가지의값은 각각 X rotation, Y rotation, Z rotation 입니다.. Rotate (90,0,0) 라고 한다면 이것은 X 축으로 90 도를회전 하였고 Y 나 Z 축으로는 변화가 없다는 것을 의미하게 됩니다..

 

이러한 표현에서 한가지 생각해 보아야 할 것은 우리가 X 축으로 90 도 회전 하였다 라고 이야기 할때 X축에서 어떤 방향으로 회전하였다는 말이 되는 걸까요?

이것에 대한 정의를 내리기 위하여 먼저 엄지 손가락을 세운 뒤 네 손가락을 쫙 펼쳐 줍니다..

 

 


 

 

위의 그림에 나타난 것과 같이 손가락들이 축에 위치한 상태에서 엄지 손가락이 축의 방향을가르키도록 위치 시켜 줍니다..

오른 손을 이용한 이러한 작업을 우리는 right -handed rotation 이라고 부르게 됩니다..

그림처럼 엄지 손가락을 원하는 축의 방향을 향하도록 한 후 움켜진 방향으로 의 회전이 right-handed rotation 에서 증가하는 양수의 값을 가지는 회전으로 정해지게 됩니다..

이때 이러한 방향의 설정은 앞장에서 다룬 적이 있는 coordinate system 과 연관성을 가지게 됩니다..

 

coordinate system 에서 left - handed coordinate system 과 right - handed coordinate system 을 생각해 보게 되면..

 

만약 left-handed coordinate system 에서 위의 그림 a 와 같이 X 방향을 오른쪽으로 지정하여 주게 되면 Z 축을 제외한 X와 Y 축의 방향은 right - handed coordinate system 과 동일하게 되지만 Z 축의 방향은 역전되게 되어 집니다..

바꾸어 이야기 하자면 left-handed coordinate system 과 right-handed coordinate system 에서의 위와 같은 handed rotation 방식의 가장 큰 차이점은 회전하는 방향이 서로 역전되어 진다는 것입니다..

 

이러한 이유로 인한여 표준적인 방법이 제시되지 않는다면 rotation 에서의 방향 문제는 많은 혼란을 가져 올 수도 있게 되므로 rotation 이 right-handed direction 이냐? 아니면 left-handed direction 을 따르고 있느냐? , software 가 right-handed coordinate system 을 사용하느냐?  아니면 left-handed  coordinate system 을 사용하느냐는 아주 중요한 문제입니다..

 

위의 그림에 적용되어진 것은 right - handed coordinate system 과 right - handed rotations 을 사용한 것인데.. 대부분의 animation package 들이 이러한 조합을 사용하고 있다고 이해하고 있어도 큰 무리가 없을 것 입니다..

 

transformation 의 세번째 형태로는 object 의 size 에 변화를 주게 되는 Scale 이 있습니다..object 의 Scale 역시 세 개의 축에 의지하여 변화하게 되는데...

만약에 object 가 한 축을 따라 scale 에 변화를 주게 되면 size 는 한 방향으로만 변화 가 됩니다..

 

 


 

 

위의 그림 에서 a 는 기본 상태의 cube 를 나타내고 있습니다..

b 의 경우는 X 축을 따라 scale 을 변화 시킨 경우를 나타내고 있고...

c 의 경우는 Y 축을 따라 ... d 는 Z 축을 따라 변화 한 것을 나타내고 있습니다..

매우 일반적인 이야기 이긴 하지만 scale 은 하나나 혹은 그 이상의 axis 를 따라 변화하게 됩니다..

e 의 경우는 y 와 z 축을 따라 크기의 변화가 생긴 경우를 나타내고 있습니다..

 

object 가 scale 의 변화를 주면서 처음 상태의 비율을 계속하여 유지하지 않는 것을 우리는 ..nonproportional scale. 또는 nonuniform scale 이라고 부르게 됩니다..

 

반대로 처음 상태의 비율을 계속하여 유지한다면 우리는 그것을 proportional scale 혹은 uniform scale라고 부릅니다..

scale transformation 역시 다른 transformation 과 동일하게 3 개의 숫자를 사용하여 표시 되어 집니다.

 

3 개의 숫자는 각각의 축을 나타내게 되는데..

위의 그림에서 f 를 예로 들게 되면 uniformly 상태인 이 object 는 세 개의 축의 값이 모두 같습니다..

예를 들자면 (2,2,2) 라는 식으로 말입니다...

nonproportional scale 을 예로 들어 X 축으로 2, Y 축으로 3, Z 축으로 7 이라고 생각해 보면.. 이것은 (2,3,7) 이라고 표시되어 질 수 있습니다..

 

동일한 크기로 변하는 scale 의 변화에 대하여 는 위와 같은 표시 이외

 

에 한 자리의 숫자로 표시 하는

것이 가능한데.. 만약 0.5 라는 값이 주어지게 된다면.. 크기가 절반으로 줄어 들게 됩니다..

만약 cube 의 vertex 가 각각 (6,6,6) 에 위치하고 있는 cube 를 0.5 라는 값으로 변화를 주게 되면..

vertex 의 위치는 (3,3,3) 으로 변화하게 되는 것입니다..

그리고 scale 에 (-) 의 값을 부여하게 되면 .. flip 이나 invert 효과를 가져오게 됩니다..

예를 들어 (2,5,8) 이라는 scale 값을 가지고 있는데 (2,-5,8) 이라는 식으로 scale 에 변화를 주게 되면..

Y 방향이 바뀌게 되어 Y 방향으로 반전되는 효과를 가져오게 된다는 의미 입니다..

( 그림 2 참조 )

 

  Fig 2

                                                                           

자 .. 이제 기본적인 세 가지의 transformations 에 대하여 알아보았습니다..

여기에서 한가지 경우를 생각해 보도록 하겠습니다..

당신이 0,0,0 지점에 서 있는데 move 3,0,0 란 이야기를 듣고 3,0,0 지점으로 이동하였다고 생각해 봅시다

다시 당신에게 move 3,0,0 란 명령이 주어지게 된다면 당신은 그것을 어떻게 해석 하시겠습니까?

3,0,0 지점으로 이동하라고 한다고 생각 한다면 이미 그곳에 위치하고 있으니 움직일 필요가 없겠지만

3,0,0 만큼 더 이동하라고 이해 한다면 다시 움직여 주어야 할 것입니다..

 

이러한 비슷한 예로 일상생활에서 위치를 가르쳐 주는 경우를 생각해 본다면..

어느거리 몇번지 어느 집이라고 분명하게 가르쳐 줄 수 있는 경우가 있는데 ..

이러한 것을 우리는 absolute transformation 이라고 이야기 하게 됩니다..

three - dimensional coordinate system 에서 absolute locate 는 직접 위치를 명시하여 주는 것을 말

하는데 " move absolutery (3,0,0) " 라고 한다면 우리는 (3,0,0) 지점으로 이동하여 주면 됩니다..

 

또 다른 형태로는 현재 위치한 지점에서 상대적으로 움직일 거리를 지정하여 주는 방법이 있습니다..

이러한 방식을 우리는 relative transformation 이라고 부르게 됩니다..

이러한 예를 들어 보자면 " 거기서 2블록 위로 올라와서 코너를 돌아 4번째 건물.." 정도가 되겠지요..

"move relatively (3,0,0)" 라고 한다면 현재의 위치에서 (3,0,0) 의 값을 더하여 주면 된다는 의미 입니다..

 

 
 
 
 
 
 
 
 
                                 


 

이러한 차이는 위의 그림을 보면 분명히 알 수 있습니다..

(a) 의 위치가 (-2,0,0) 라고 한다면 absolute move (-2,1,0) 라는 명령이 주어지게 되면 이미 -2 의 위치에

있는 cube 는 X 방향으로는 움직이지 않고 Y 방향으로만 움직이게 될 것입니다..(b)

만약 relative move (-2,1,0) 라고 주어지게 된다면 현재의 위치에 (-2,1,0) 의 값을 더해 주게 되므로

(-4,1,0) 의 지점으로 이동하게 될 것입니다..(c)

 

위에서는 단순히 translation 에 대하여만 예를 든 것이지만 다른 두 가지의 transformations 에 대하여도

동일하게 적용되어 집니다..

rotate 에 대하여 예를 들어 보게 되면..

그림 3 의 a 와 같은 형태에서 X 축으로 45 도 rotate 하라는 명령을 주게 될때에..

현재 a 에서 90 도의 각을 가지고 있는 board 가 absolutely 상태에서는 b 와 같이 움직이게 되고 ...

relatively 상태에서는 90 도에 45 도가 더해져서 그림 c 와 같은 형태로 움직이게 될 것입니다..

 


                                                              fig 3

 


scale 을 예로 들게 되면...

위의 그림에 나타난 것과 같이 이미 2 라는 scale 값을 가지고 있는 a 의 cube 에 다시 2 라는 scale 값

이 주어지게 된다면...

absolute acale 상태에서는 전혀 변화가 일어나지 않게 되지만... (b)

relative scale 상태에서는 object 의 sale 이 다시 2배로 증가하게 됩니다...(c)

 3D gomputer graphics system 작업에서 absolute 와 relative 의 적용 상태에 대하여는 미리 알고 있는 것이 좋으며.. 대부분의 software 들은 이러한 구분이 가능한 기능들을 제공하여 주고 있습니다..

실제로 우리가 작업할때에도 상대좌표와 절대좌표라는 표현으로 이러한 기능을 적절히 사용하고있습니다..

 

자.. 이제 그림 4와 같은 cylinder 가 있다고 가정하여 봅시다..

우리는 이 cylinder 를 회전 시키기 위해서 중심점을 (b) 처럼 cylinder 의 center 에 위치 시켜 줄 수도

있고 그림 (c) 처럼 cylinder 의 아래에 위치 시켜 줄 수도 있게 됩니다..

 

이 point 를 우리는 pivot point , 혹은 local origin 이라고 부르게 됩니다..

여기에서 우리는 transformations 와 관련해서 이해해야 될 것이 있는데 .. 그것은 world coordinate

system , 혹은 global coordinate system 이라고 불리우는 것과 local coordinate system 이라는

것입니다..

local coordinate system 이 개별적인 object 의 pivot point 를 중심으로 작업이 이루어 진다면..

world coordinate system 은 작업공간의 한 지점을 전체 object 의 작업 중심으로 작업이 이루어 지게

됩니다.                                              fig 4

 

 

 

 

 

 

 

 

local coordinate system 에서 local origin 이 어느 에 위치하고 있느냐에 따라 아래 그림과 같이 전혀 다른 움직임이 보여 질 수 있게 됩니다..

 


 

또한 world coordinate system 과 달리 local coordinate system 에서는 object 의 움직임에 따라 object 의 origin 도 함께 움직이게 됩니다..

아래 그림의 a,b 는 동일하게 (5,3,0) 라는 지점에 위치하고 있습니다..

하지만 서로의 local origin 의 위치가 다르므로 서로 동일하게 위차하고 있지 않은 모습을 보여 주게 되는 것입니다..

 


 

scale 을 예로 들게 되면 아래 그림은 cube 에서 각각의 local origin 의 위치에 따른 scale 의 변화에서의 모습을 보여 주고 있습니다..

 


 

만들때 마다 다르기는 하지만 일반적으로 object 를 만들기 위한 변형의 순서가 있게 됩니다..예를 들어 램프의 갓을 만들고자 한다면 .. 먼저 적당한 크기로 cone 을 조정하여 줄 것이고..그것을 lamp 의 상단 부위에 위치시키게 될 것입니다..

그리고 적당한 위치를 조절하여 주고.. 다시 움직여 주고.. 회전 시켜 주고.. 크기를 조금 수정하여 주고.. 위치를 조금 수정하여 주고..

 

이러한 모든 변형은 3D modeling system 안에서 세 개의 기본적인 transformation 을 하나의 set 으로 압축한 형태로 나타내어 지게 되는데..

이렇게 여러 가지의 transformation 을 하나의 transformation set 으로 엮어주는 것을 ..

concatenation of transformations 라고 합니다..

그 결과는 9개의 transformation 값으로 연결 되어진 형태로 나타나게 되는데..

3개의 translation 값과.. 3개의 rotation 값과.. 3개의 scale 값으로 나타나게 되어 집니다..

이렇게 9개의 값을 그림 5와 같은 형태로 배열하여 준것을 "matrix" 라고 부르게 됩니다..

( 복수의 matrix 를 matrices 라고도 합니다..)

그리고 이러한 것을 transformation matrix 라고 합니다..        

이렇게 변형을 일종의 도식화 하여 배치하여 주는 것은 수학적인 관점에서 볼때 개발자들이 손쉽게 변형값을 사용하여 조작할 수 있도록 할 수 있도록 하기 위하여 중요한 의미를 갖게 됩니다..

그림 5의 a 는 일반적인transformation matrix 의 배치를 나타내어 주고 있고.. 그림 5의 b 는 transformation 값이 배치 되어진 모습을 나타내어 주고 있습니다..                      fig 5

 

 

우리가 object 를 만들고 아무 변형을 가하지 않았다 하더라도.. 그것은 이미 변형을 가지기 전의 transformation값이 적용되어진 상태입니다..

이렇게 move, rotate, scale 의 변화가 주어지지 않은 transformation 의 값을 default 상태라고 하는데.. 이러한 default transformation 이란 다른 말로 이야기 하자면..move (0,0,0); rotate (0,0,0); scale (1,1,1) 로 표시되어 질 수 있습니다..그리고 이렇게 변형을 주지 않은 값을 우리는 identity transformation 이라고 부르기도 합니다.. ( 그림 6 )

이 identity transformation 값은 우리가 작업 중 object 의 transformation 값을 없애기를 원할 때 되돌아가는 기본이되는 값이 기도 합니다.                                            fig 6

 

 

transformation matrix 라는 이러한 개념은 3D computer graphics 의 중심적인 개념입니다..

그리고 이러한 개념의 연장선에서의 기술의 예를 들어 보게 되면..

이러한 기술이 포함될 수 있는 경우로 한 scene 에 여러개의 같은 object 가 존재 한다고 생각해 보면..

 


 

위의 그림에서 알 수 있듯이 이 경우는 위치와 방위만이 다를 뿐인 많은 의자가 존재 하고 있게 됩니다..

우리는 computer graphics developed 에서 이러한 종류의 modeling 상태에 대한 기술을 instantiation 이라고부릅니다....

이러한 instance 는 copy 와는 다른 개념입니다..

copy 의 경우는 geometry 를 복제하여 주는 것 입니다..

instance 의 경우에는 model 의 geometry 를 duplicate 하지 않습니다..  다만...

software system 은 " 그 위치" 라는 개념만을 가지고 있습니다..

그렇기 때문에 copy 와는 달리 원 모델에 대한변화가 모든 object 에 동일하게 적용되어 지게 되는 것입니다..

여기에서는 새로운 geometry 의 형태를 만들어 주지는 못합니다..

그러므로 여러분이 original model 에서 instance 상태로 model 을 만들어 주게 된다면...

그것은 하나의 geometry 와 두 개의 transformation matrices 로 정의 되어 질 것입니다..


 

이러한 방식은 data 의 관리라는 측면에서도 매우 경제적이지만..

한번의 작업으로 동일한 모든 model 에 변형을 줄 수 있기 때문에 많은 object 가 포함되어 지는 scene 에서는 매우 유용하게 사용되어 질 수 있습니다..

[출처] Transformations|작성자 slime321


'Camera Calibration' 카테고리의 다른 글

Tsai calibration  (0) 2015.04.02
Posted by 모래반지빵냐빵냐
,

출처:http://blog.daum.net/goodgodgd/12


이번엔 Qt에서 opencv 설치하는 과정에 대해서 써보도록 하겠습니다.

이미 구글에 검색해보면 여러가지 비슷한 설치방법들이 나오는데요.. 제가 완결판을 만들어보겠습니다.


OpenCV 설치 방법을 간단 요약하자면

1. 다운받아서 설치한다.

2. CMake로 make 파일 만든다. (Qt 관련 설정 필요)

3. 빌드한다.

4. Qt 프로젝트 파일을 수정한다.

5. 코드에 #include <opencv2/opencv.hpp> 추가하고 OpenCV를 맘껏 쓴다.

비주얼 스튜디오를 사용하는 경우에는 직접 빌드할 필요가 없습니다. 이미 비주얼 스튜디오의 컴파일러로 빌드된 파일들을 설치시에 제공하기 때문이죠.

OpenCV코드를 직접 수정하거나 Qt같은 마이너 환경을 쓰는 경우엔 직접 빌드해야 합니다.

CMake는... 저도 아직 잘 모르겠어요. 저도 OpenCV 설치할 때만 CMake를 쓰는지라...ㅎ;;

CMake를 쓰는 이유는 (저도 잘은 모르지만) 비주얼 스튜디오 같은 통합개발환경(IDE) 없이 컴파일러만 가지고 빌드하려면 코드들 사이의 관계를 정의해주는 Makefile 이라는게 필요한데 코드가 많은 복잡한 프로젝트의 경우 Makefile을 직접 작성하기가 지랄맞게 어렵다고해서 그것보다 좀 더 쉬운 문법으로 CMakeLists.txt를 써주면 CMake 프로그램에서 알아서 Makefile을 만들어주겠다.... 는 거라네요. (그럼 애초에 Makefile을 만들기 쉽게하던가..;;)

암튼 OpenCV는 설치시 CMakeLists.txt를 제공하고 그래서 CMake로 빌드할 준비를 해야한다는 겁니다.


이제 본론 갑니다.


일단 OpenCV를 다운받아서 설치를 해야겠죠?

http://opencv.org/downloads.html

그런데 제가 해본 결과 3.0 버전은 Qt로 빌드가 잘 되지 않습니다. 그러니 일단 OpenCV 2.4.9 버전을 설치해주세요.

(3.0으로 Qt 잘 돌리시는 분 있음 댓글로 팁좀 주세요;;;)

저는 이미 구버전이 깔려있어서 헷갈리지 않게 C:\opencv_249 에 설치했습니다.

그리고 CMake도 설치해 주세요.

http://www.cmake.org/download/ 

윈도우라면 Binary distributions에 Windows (Win32 Installer) 이걸로 설치하는게 편할겁니다.


CMake를 실행하기 전에 먼저 시스템 환경변수를 설정해줘야 합니다.

이걸 안하면 아예 Configure부터 막힙니다;;

아래 그림대로 쭉 따라가세요.



저기서 저 Path란 변수에 Qt를 이용한 빌드에 필요한 경로를 추가해줍니다.

C:\Qt\5.3\mingw482_32\bin;C:\Qt\Tools\mingw482_32\bin;C:\Qt\Tools\QtCreator\bin;


처음에 설치 방법 소개했을때 말한 MinGW를 사용하는 것입니다.

절대 Path의 기존 경로들을 지운다거나 그런 실수는 하지 마세요;;; 위 경로를 추가!하는 겁니다.

시스템변수를 설정했으니 이제 CMake를 실행하는 것이... 아니고 일단 컴퓨터를 리부팅 해줘야 수정한 경로가 적용됩니다. Reboot!!


이제 진짜 CMake를 실행해서 다음과 같이 경로를 설정해 봅시다.

Where is the source code: 에는 OpenCV 설치 폴더에 들어있는 sources 폴더의 경로를 적어주면 되고

Where to build the binaries: 에는 빌드할 폴더를 지정합니다. sources 옆에 build라는 폴더는 이미 있기 때문에 다른 폴더 이름을 지정합니다.

Qt debug 모드에서 사용할 바이너리 파일을 만들기 위해 build_qt_debug란 이름을 붙였습니다. Release 모드로 쓸거라면 build_qt_release라고 했겠죠.

근데 debug 모드랑 release 모드랑 빌드를 따로해야 하냐구요? 맞습니다. 어떻게 하냐구요? 뒤에 나옵니다. 왜 그래야 하냐구요? 물론 공용으로 빌드해도 어느정도 돌아가긴 합니다.

그런데 몇가지 기능이 제대로 동작하지 않는것을 보고 저도 디버그 모드로 다시 빌드했습니다.

예를들면 imshow()로 이미지를 새 창에 띄우고 나서 똑같은 window name으로 다른 이미지를 imshow() 했는데 그림이 바뀌지 않더란 말입니다;;;


그리고 Configure를 누릅니다. 빌드 폴더가 없으면 만들겠냐고 물어보는데 당연히 Yes!

그러면 어떤 컴파일러로 OpenCV를 빌드할 것인지 아래와 같이 설정해줍니다.

Qt 설치시 MinGW를 선택하였으므로 Qt에서 설치해준 mingw 컴파일러를 지정합니다.


이제 Finish를 누르면 configure가 진행됩니다. 아까 환경변수를 수정하고 재부팅!까지 해주지 않았다면 여기서 바로 에러뜨고 막힙니다.

Configure가 약간 시간이 걸리는데 끝나고 나면 다음과 같은 화면이 뜹니다. 빨간색이 아니어도 에러만 안뜨면 괜찮습니다.


Configuring done 이라고 뜨지만 끝난것은 아닙니다. 여기가 핵심 비법이라고 할수 있는데요ㅋ

위에 search 창에 qt라고 검색해서 WITH 아래 WITH_QT를 체크해줍니다. WITH 옆에 화살표가 안보인다고 당황하지 마세요!

마음의 눈으로 화살표가 있을만한 왼쪽에 빈 공간을 눌러주면 아래 항목이 나옵니다.


또한 cmake로 검색해서 cmake 아래에 CMAKE_BUILD_TYPE에 Debug라고 씁니다. 그리고 Configure를 몇 번 더 눌러주세요.


Configure 다음은 Generate 입니다. 이건 한번만 실행하면 됩니다. 그럼 이렇게 빌드폴더에 갖가지 파일과 폴더.. 그리고 Makefile이 생겼음을 볼 수 있습니다.


이제 드뎌 진짜!! 빌드를 할 차례입니다.

윈도우키+R 로 "실행"을 실행시키고 cmd라고 쓰고 엔터!치면 콘솔창이 나옵니다. 그리고 아래와 같이 make 합니다.

>c:\opencv_249\opencv\build_qt_degub

>mingw32-make



그럼 한참동안 컴퓨터가 빌드하고 있을겁니다. 10분이상 걸릴테니 잠깐 딴짓을 해도 좋습니다.

그런데 제가 집컴에서는 빌드가 한방에 되는데 회사에서 하면 자꾸 중간에 멈춰서 진행이 안되고 다시 빌드하고 그런 것을 반복해야 했는데 왜 그런지는 모르겠습니다. 잘 되고 있나 한번씩 확인해주세요.

다 되고 나면 이런 화면이 뜰겁니다. 다음은 mingw32-make install 입니다. make install을 하면 빌드된 곳으로 소스코드까지 다 복사가 됩니다.


끝나면 결과는 이렇게...


이제 설치는 끝났습니다. 몇 가지 설정만 더 해주면 사용할 수 있습니다.

초반에 보였던대로 빌드해서 만든 opencv의 dll 파일들을 우리 프로젝트에 링크시킬려면 (즉 opencv를 사용하려면) 위에서 한대로 

시스템 속성 - 환경변수로 들어가서 Path에 다음 경로를 추가해야 합니다.

C:\opencv_249\opencv\build_qt_debug\bin


그리고 역시 재부팅을 해줍니다. 이걸 건너뛰고 프로그램을 실행하면 다음과 같은 메시지를 보며 한참을 머릴 쥐어뜯으며 구글을 헤메이게 될 것입니다.ㅎㅎ 

(절대 경험담 아님;;)


이제 드디어!! Qt를 켜봅시다.

QtOpenCVTest라는 Qt Widgets Application 프로젝트를 만들었습니다.


비주얼 스튜디오에서도 opencv를 사용할 때 프로젝트 속성에서 opencv 경로를 설정해줬듯이 Qt에서는 .pro 파일에서 경로를 지정합니다.

왼쪽 위에 QtOpenCVTest.pro 파일을 열어 다음 경로와  dll 파일들을 추가합니다. 아래 지정한 dll 파일들은 기본적인 것들이고 필요에 따라 빼거나 추가할 수 있습니다.

INCLUDEPATH += C:\opencv_249\opencv\build_qt_debug\install\include


LIBS += C:\opencv_249\opencv\build_qt_debug\bin\libopencv_calib3d249d.dll \
        C:\opencv_249\opencv\build_qt_debug\bin\libopencv_contrib249d.dll \
        C:\opencv_249\opencv\build_qt_debug\bin\libopencv_core249d.dll \
        C:\opencv_249\opencv\build_qt_debug\bin\libopencv_features2d249d.dll \
        C:\opencv_249\opencv\build_qt_debug\bin\libopencv_highgui249d.dll \
        C:\opencv_249\opencv\build_qt_debug\bin\libopencv_imgproc249d.dll \



반드시 프로젝트 파일을 수정한 후에는 Ctrl+S로 저장을 해줘야 효과가 나타납니다.

그리고 헤더 파일 mainwindow.h 에 opencv 헤더 파일을 인클루드합니다. 이후 예제를 위해 파일다이얼로그 클래스와 문자열 클래스도 추가합니다.

#include <opencv2/opencv.hpp>

#include <QFileDialog>

#include <QString>


이제 OpenCV를 쓸 수 있습니다. 위젯에 버튼하나 추가해서 버튼을 누르면 이미지 하나를 열어서 보여주는 예제를 만들겠습니다.

버튼하나 추가하고 우클릭 - Go to slot - clicked() 선택해서 연결함수를 생성합니다.


void MainWindow::on_pushButton_clicked()
{
    QString qsfileName = QFileDialog::getOpenFileName(this,
        tr("Open Image"), "../", tr("Image Files (*.png *.jpg *.bmp)"));
    cv::Mat image = cv::imread(qsfileName.toStdString());
    cv::imshow("Hello OpenCV", image);

}


파일 다이얼로그를 열어서 파일을 선택하고 그 파일을 열어서 보여주는 간단한 함수입니다. 파일명의 형태를 std::string으로 바꿔주기 위해 .toStdString() 함수가 들어갔습니다.

이제 실행해서 버튼을 누르고 이미지 파일을 열어봅시다. Voila!!


역시 비전 관련 예제는 레나가 나와야 제맛!!

여기까지 잘 따라오셨다면 축하합니다. 하지만 삽질은.. 이제부터 시작이겠죠?

별 내용도 아닌데 캡쳐로 도배를 했더니 페이지수만 많아졌네요;;

저도 이 과정을 완전히 이해한 것은 아니라 수정/태클/지적질 환영합니다.

그럼 다음 삽질때 봐요~

'QT > Examples' 카테고리의 다른 글

QT로 Serial 통신 구현하기 - 1  (0) 2015.04.15
Hello World를 띄우자.  (0) 2015.04.08
QT에서 이미지 출력하는 방법  (0) 2015.04.03
Posted by 모래반지빵냐빵냐
,