Upload
others
View
1
Download
0
Embed Size (px)
Citation preview
Author:
Safar A. Alqahtani
Presented To The
Institute of Information
& Mathematical Sciences
Massey University at Albany,
Auckland, New Zealand
Supervisor:
Dr. Andre L. Barczak
TABLE OF CONTENTS
#include <QThread>
class MyExtraThread : public QThread
{
Q_OBJECT
public:
MyExtraThread();
void Stop();
signals:
void signal_ourLabel(QString msg);
private:
void run();
bool run_;
};
#include "myextrathread.h"
MyExtraThread::MyExtraThread()
{
}
void MyExtraThread::Stop(){
run_ = false;
}
void MyExtraThread::run(){
run_ = true;
QString temp = "";
int counter = 0;
while(run_){
temp = "Extra Thread msg num: ";
temp += QString::number(counter);
emit signal_ourLabel(temp);
++counter;
sleep(1);
}
}
#include <QMainWindow>
#include <myextrathread.h>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void slot_update_ourLabel(QString msg);
private:
Ui::MainWindow *ui;
MyExtraThread * my_thread_;
};
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
my_thread_ = new MyExtraThread();
connect(my_thread_,
SIGNAL(signal_ourLabel(QString)),
SLOT(slot_update_ourLabel(QString))
);
my_thread_->start();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::slot_update_ourLabel(QString msg){
ui->label->setText(msg);
}
640 480
720 480
800 600
960 720
1024 768
weights LookupTable::GetPixel(int px, int py, float x, float y){
float dx = x - px; //dx
float dy = y - py; // dy
float dx_1 = 1.0f - dx;//(1-dx)
float dy_1 = 1.0f - dy;//(1-dy)
// Bilinear Interpolation constants
weights temp;
temp.w[0] = dx_1 * dy_1;
temp.w[1] = dx * dy_1;
temp.w[2] = dx_1 * dy ;
temp.w[3] = dx * dy ;
// Biquadratic Interpolation constants
temp.qx = 0.5*pow(dx,2);
temp.qy = 0.5*pow(dy,2);
temp.dx = 0.5*dx;
temp.dy = 0.5*dy;
// Bicubic Interpolation constants
temp.dx2 = dx*dx;
temp.dy2 = dy*dy;
temp.dx3 = temp.dx2 * dx;
temp.dy3 = temp.dy2 * dy;
return temp;
}
uchar getBilinear(uchar *pixels_,int pos, int cell);
uchar getBiquadratic(uchar *pixels_,int pos, int cell);
uchar getBicubic(uchar *pixels_,int pos, int cell);
uchar LookupTable::getBilinear(uchar *pixels_,int pos, int cell){
weights wt = lookup_tf[pos];
int x = lookup_t[pos];
float avg = wt.w[0]*pixels_[ (x*3) + cell];
avg += wt.w[1]*pixels_[((x+1)*3) + cell];
avg += wt.w[2]*pixels_[((x+max_x_)*3) + cell];
avg += wt.w[3]*pixels_[((x+max_x_+1)*3) + cell];
return avg;
}
phi = 3.1415926*( 605 - i - 90* 5)/(180* 5);
phi = 0.54105206+i*(-0.0034906584);
#ifndef CAMERATHREAD_H
#define CAMERATHREAD_H
#include "opencv/highgui.h"
#include <qthread.h>
#include <QImage>
#include <qwaitcondition.h>
struct Resolution{
int height;
int width;
};
struct Resolutions{
Resolution all[30];
int size;
};
class CameraThread : public QThread
{
Q_OBJECT
public:
CameraThread(int device);
CameraThread(int device, QWaitCondition* frame_syn,
Resolution cam_res);
CameraThread(std::string image_path , QWaitCondition*
frame_syn);
void setImage(std::string image);
void Stop();
cv::Mat getLastFrame();
Resolutions CheckRes();
void ConnectCamera();
int getHieght();
int getWidth();
bool IsCameraOn();
bool test_res_;
signals:
void updateLabelOrignal(QImage extra);
private:
void run();
QWaitCondition* frame_syn_;
cv::VideoCapture cap;
int x_, y_, device_num_;
cv::Mat frame ;
bool run_, is_connected_, is_image_;
};
#endif // CAMERATHREAD_H
#include "camerathread.h"
#include <MatToQImage.h>
#include <stdio.h>
#include <ctype.h>
#include <fstream>
CameraThread::CameraThread(int device){
test_res_ = true;
device_num_ = device;
ConnectCamera();
}
CameraThread::CameraThread(std::string image_path,
QWaitCondition* frame_syn){
frame_syn_ = frame_syn;
device_num_ = 0;
x_ = 0; y_ = 0;
test_res_ = false;
setImage(image_path);
}
CameraThread::CameraThread(int device, QWaitCondition*
frame_syn, Resolution cam_res){
frame_syn_ = frame_syn;
device_num_ = device;
x_ = cam_res.width; y_ = cam_res.height;
test_res_ = is_image_ = false;
ConnectCamera();
}
void CameraThread::Stop() {
run_ = false;
}
cv::Mat CameraThread::getLastFrame(){
return frame;
}
void CameraThread::setImage(std::string image){
cap.open(image);
if(!cap.isOpened()){
ConnectCamera();
is_image_ = false;
}else{
is_image_ = true;
cap >> frame;
x_ = frame.cols;
y_ = frame.rows;
}
}
void CameraThread::run() {
run_ = true;
std::cout<<"Started CameraThread"<<std::endl;
if(is_image_)
while(run_){
if(!frame.empty()){
this->msleep(100);
frame_syn_->wakeAll();
emit
updateLabelOrignal(MatToQImage(frame));
}
}
else{
cap.set(CV_CAP_PROP_FRAME_WIDTH,x_);
cap.set(CV_CAP_PROP_FRAME_HEIGHT,y_);
while(run_){
cap >> frame;
frame_syn_->wakeAll();
emit updateLabelOrignal(MatToQImage(frame));
}
}
std::cout<<"Finshed CameraThread"<<std::endl;
}
void CameraThread::ConnectCamera(){
is_connected_ = true;
cap.open(device_num_);
if(!cap.isOpened()){
is_connected_ = false;
std::cout<<"Camera failed to
connected."<<std::endl;
if(device_num_!=0){
std::cout<<"Opening the default
camera..."<<std::endl;
cap.open(0);
if(cap.isOpened()){
is_connected_ = true;
std::cout<<"The default camera is
connected."<<std::endl;
}
else
std::cout<<"Camera failed to
connected."<<std::endl;
}
}
else
std::cout<<"Camera is connected."<<std::endl;
}
bool CameraThread::IsCameraOn(){
if(is_image_) return false;
return is_connected_;
}
Resolutions CameraThread::CheckRes(){
Resolutions res;
res.size = 0;
res.all[0].width = 640;
res.all[0].width = 480;
if(!is_connected_) return res;
std::ifstream infile("res.txt");
int a, b;
while (infile >> a>> b)
{
cap.set(CV_CAP_PROP_FRAME_WIDTH,a);
cap.set(CV_CAP_PROP_FRAME_HEIGHT,b);
if(cap.get(CV_CAP_PROP_FRAME_WIDTH)==a &&
cap.get(CV_CAP_PROP_FRAME_HEIGHT)==b){
res.all[res.size].width = a;
res.all[res.size].height = b;
res.size++;
}
}
infile.close();
return res;
}
int CameraThread::getHieght(){
return y_;
}
int CameraThread::getWidth(){
return x_;
}
#ifndef FACEDETECTION_H
#define FACEDETECTION_H
#include "lookuptable.h"
#include <string>
#include <QTime>
struct FacePos{
XY face[8];
int size;
};
class FaceDetection
{
public:
FaceDetection(const char *cas_name, int milliseconds,
int faces_count);
bool allowed();
FacePos update();
void processImage(cv::Mat dst);
void ChangeRefresh(int milliseconds);
void ChangeFaceCount(int faces_count);
void clear();
protected:
void DetectFace(cv::Mat dst_);
FacePos faces_;
bool wait_face_;
QTime myTimer_;
cv::Mat frame_gray_;
std::string face_cascade_name_;
cv::CascadeClassifier face_cascade_;
bool face_xml_loaded_;
int milliseconds_, faces_count_limit_;
};
#endif // FACEDETECTION_H
#include "facedetection.h"
#include <vector>
#include <iostream>
#include <opencv/cv.h>
#include <lookuptable.h>
FaceDetection::FaceDetection(const char* cas_name, int
milliseconds, int faces_count) {
myTimer_.start();
face_cascade_name_ = cas_name;
face_xml_loaded_ = true;
if( !face_cascade_.load( face_cascade_name_ ) ){
std::cout<<"--(!)Error loading face cascade\n";
face_xml_loaded_ = false;
};
faces_.size = 0;
wait_face_ = false;
ChangeRefresh(milliseconds);
ChangeFaceCount(faces_count);
}
void FaceDetection::clear(){
faces_.size = 0;
}
void FaceDetection::ChangeRefresh(int milliseconds){
milliseconds_ = milliseconds;
}
void FaceDetection::ChangeFaceCount(int faces_count){
if(faces_count>7){
faces_count_limit_ = 7;
std::cout<<"You are limited to 7 faces
only"<<std::endl;
}
else
faces_count_limit_ = faces_count;
}
void FaceDetection::DetectFace(cv::Mat dst) {
faces_.size = 0; // set to zero to remove non-face
pictures
if(!face_xml_loaded_) return;
std::vector<cv::Rect> rect_pos;
if(dst.empty())
return;
cvtColor( dst, frame_gray_, cv::COLOR_BGR2GRAY );
equalizeHist( frame_gray_, frame_gray_ );
//-- Detect faces
face_cascade_.detectMultiScale( frame_gray_, rect_pos,
1.1, 2, 0|cv::CASCADE_SCALE_IMAGE, cv::Size(30, 30) );
// warning: comparison between signed and unsigned
integer expressions (no need for casting) all positive
for ( int i = 0; i < rect_pos.size()&&
i<faces_count_limit_; i++ )
{
cv::Point center( rect_pos[i].x +
rect_pos[i].width/2, rect_pos[i].y + rect_pos[i].height/2 );
cv::ellipse( dst, center, cv::Size(
rect_pos[i].width/2, rect_pos[i].height/2 ), 0, 0, 360,
cv::Scalar( 0, 0, 255 ), 2, 2, 0 );
faces_.face[i].x=rect_pos[i].x +
rect_pos[i].width/2;
faces_.face[i].y=rect_pos[i].y +
rect_pos[i].height/2;
faces_.size = i+1;
}
}
FacePos FaceDetection::update(){
return faces_;
}
bool FaceDetection::allowed(){
return wait_face_;
}
void FaceDetection::processImage(cv::Mat dst){
if(myTimer_.elapsed()> milliseconds_){
wait_face_=false;
DetectFace(dst);
myTimer_.restart();
wait_face_=true;
}
}
#ifndef LOOKUPTABLE_H
#define LOOKUPTABLE_H
#include "opencv/cv.h"
#include "opencv/highgui.h"
#define MTHETA 2160 // DIVT*(azimuth or horizontal
view angle = 360)
#define MPHI 605 // DIVP*(elevational or vertical
view angle = 121)
#define MTP 1306800 // MTHETA*MPHI
struct XY{
int x,y;
};
struct Kernal{
float mask[9];
};
struct weights{
float w[4];
float dx, dy, qx, qy;
float dx2, dy2; //pow(dx,2), pow(dy,2)
float dx3, dy3; //pow(dx,3), pow(dy,3)
};
enum Interpolation{
None = 0,
Bilinear = 1,
Bicubic = 2,
Biquadratic = 3
};
// Lookup Tables
class LookupTable {
public:
LookupTable();
LookupTable(int max_x, int max_y);
void compute_perspective_colour( cv::Mat src, cv::Mat
per, float phi_z, float theta_z, float f);
void compute_panoramica_colour(cv::Mat src, cv::Mat
dst);
void compute_lookuptables(int centerx_omni, int
centery_omni);
void setInterpolation(Interpolation inter);
float rtsafe(float ang, float x1, float x2, float
xacc);
inline float df_mirror(float x);
inline void faux1(float ang, float x, float *fn, float
*df);
inline float f_mirror(float x);
inline float root(float ang);
uchar getBilinear(uchar *pixels_,int pos, int cell);
uchar getBiquadratic(uchar *pixels_,int pos, int cell);
uchar getBicubic(uchar *pixels_,int pos, int cell);
void setKernal(Kernal cp);
Kernal getKernal();
int lookup_t[MTP];
weights lookup_tf[MTP];
bool interpol;
private:
weights GetPixel(int px, int py, float x, float y);
uchar (LookupTable::*interpol_function)(uchar
*pixels_,int pos, int cell);
int max_x_, max_y_;
Kernal kl_;
};
#endif // LOOKUPTABLE_H
#include "lookuptable.h"
#define DIVT 6
#define DIVP 5
// Parameters of omnidirectional vision system
#define X_MAX 20 // Mirror radius
#define Y_MAX 12.96 // Height of mirror
//#define Y_MAX 16.00 // Height of mirror
#define DFOCOS 82.915 // Distance between camera
focus and mirror focus
//#define FCAMERA 12 // Focal distance of the
camera//ORIGINAL
#define FCAMERA 12 // Focal distance of the camera
//TEST
#define ACU 0.000001
LookupTable::LookupTable()
{
interpol = false;
for(int i = 0; i<9; ++i){
kl_.mask[i] = 1.0;
}
max_x_ = 640;
max_y_ = 480;
compute_lookuptables(max_x_/2,max_y_/2);//initial guess
for centre
}
LookupTable::LookupTable(int max_x, int max_y)
{
interpol = false;
for(int i = 0; i<9; ++i){
kl_.mask[i] = 1.0;
}
max_x_ = max_x;
max_y_ = max_y;
compute_lookuptables(max_x_/2,max_y_/2);//initial guess
for centre
}
Kernal LookupTable::getKernal(){
return kl_;
}
void LookupTable::setKernal(Kernal cp){
kl_ = cp;
}
inline float LookupTable::f_mirror(float x) {
return((sqrt(1374.97*(1 + (x*x)/343.74))-41.457));
}
inline float LookupTable::df_mirror(float x) {
return(-x*(144176054272.0/(sqrt(0.1786295048423e25 +
0.5196645861473e22*x*x))));
}
inline void LookupTable::faux1(float ang, float x, float
*fn, float *df) {
*fn = f_mirror(x) - ang*x;
*df = df_mirror(x) - ang;
}
float LookupTable::rtsafe(float ang, float x1, float x2,
float xacc) {
int j;
float df,dx,dxold,f,fh,fl;
float temp,xh,xl,rts;
faux1(ang,x1,&fl,&df);
faux1(ang,x2,&fh,&df);
if ((fl > 0.0 && fh > 0.0) || (fl < 0.0 && fh < 0.0)) {
printf("\nRoot must be bracketed in rtsafe\n");
exit(1);
}
if (fl == 0.0) return x1;
if (fh == 0.0) return x2;
if (fl < 0.0) {
xl=x1;
xh=x2;
}
else {
xh=x1;
xl=x2;
}
rts=0.5*(x1+x2);
dxold=fabs(x2-x1);
dx=dxold;
faux1(ang,rts,&f,&df);
for (j=1;j<=100;++j) {
if ((((rts-xh)*df-f)*((rts-xl)*df-f) >= 0.0) ||
(fabs(2.0*f) > fabs(dxold*df))) {
dxold=dx;
dx=0.5*(xh-xl);
rts=xl+dx;
if (xl==rts) return rts;
}
else {
dxold = dx;
dx=f/df;
temp=rts;
rts -= dx;
if (temp==rts) return rts;
}
if (fabs(dx) < xacc) return rts;
faux1(ang,rts,&f,&df);
if (f<0.0)
xl=rts;
else
xh=rts;
}
printf("\nMaximum number of iterations exceeded in
rtsafe\n");
exit(1);
return 0.0;
}
inline float LookupTable::root(float ang) {
return rtsafe(ang, 0, X_MAX, ACU);
}
void LookupTable::compute_lookuptables(int centerx_omni,
int centery_omni) { // take foucas
int width_omni = max_x_; // width (pixels)
int height_omni = max_y_; // height (pixels)
int i, j, xu, yu;
float beta, phi, x, Pim;
double xud, yud;
float myx, myy;
printf("Computing Lookup Tables... Please wait...\n");
for (i=0;i<MPHI;++i) {
for(j=0;j<MTHETA;++j) {
//calculate the incident angle in the mirror
that formed the pixel
phi = 3.1415926*(MPHI - i -
90*DIVP)/(180*DIVP);
// phi = 0.54105206+i*(-0.0034906584); //
wolframalpha
// tangent of the angle
beta = tan(phi);
//calculation of the x coordinate of the
mirrors
x = root(beta);
if (x > X_MAX)
printf("Error in the calculation of x");
if (x*beta > Y_MAX)
printf("Error in the calculation of y");
//calculation of the radial distance m pixel
pixel equivalent to angle phi
Pim =
(x*(centery_omni)*((DFOCOS)+Y_MAX))/(X_MAX*((DFOCOS)+(x*beta))
);
//writing the coordinates of the rectangular
image
xud= -Pim*(cos((6.28*j)/(MTHETA-1)));
// xud= -Pim*(cos(0.00290875*j)); //
wolframalpha
yud= -Pim*(sin((6.28*j)/(MTHETA-1)));
// yud= -Pim*(sin(0.00290875*j)); //
wolframalpha
myx = xud;
myy = yud;
xud=rint(xud); // round to int
yud=rint(yud);
lookup_tf[(i*MTHETA)+j] =
GetPixel(xud,yud,myx,myy);
myx+= centerx_omni;
myy+= centery_omni;
xu = xud + (centerx_omni);// cast to int
removed not needed look above rint()
yu = yud + (centery_omni);
if(yu < 0)
yu = 0;
else
if(yu >= height_omni)
yu = height_omni-1;
if(xu < 0)
xu = 0;
else
if(xu >= width_omni)
xu = width_omni-1;
lookup_t[(i*MTHETA)+j] = (yu*width_omni)+xu;
}
}
printf("Lookup Tables done.\n");
}
void LookupTable::compute_panoramica_colour(cv::Mat src,
cv::Mat dst) {
int pos_y_, pos_x_,accss, index1_;
uchar *colorpixels = (unsigned char*)(src.data);
uchar *colorpixeld = (unsigned char*)(dst.data);
int largd_ = dst.step;
for(pos_y_=0; pos_y_<dst.rows; ++pos_y_) {
for(pos_x_=0; pos_x_<dst.cols; ++pos_x_) {
index1_ = pos_y_*largd_+pos_x_*3;
accss = (int)((pos_y_*MPHI)/dst.rows)*MTHETA +
(int)(((dst.cols-pos_x_)*MTHETA)/dst.cols);
colorpixeld[index1_] =
colorpixels[lookup_t[accss]*3];
colorpixeld[index1_+1] =
colorpixels[(lookup_t[accss]*3)+1];
colorpixeld[index1_+2] =
colorpixels[(lookup_t[accss]*3)+2];
}
}
}
weights LookupTable::GetPixel(int px, int py, float x,
float y){
//http://fastcpp.blogspot.co.nz/2011/06/bilinear-pixel-
interpolation-using-sse.html
float dx = x - px; //dx
float dy = y - py; // dy
float dx_1 = 1.0f - dx;//(1-dx)
float dy_1 = 1.0f - dy;//(1-dy)
// Bilinear Interpolation
weights temp;
temp.w[0] = dx_1 * dy_1;
temp.w[1] = dx * dy_1;
temp.w[2] = dx_1 * dy ;
temp.w[3] = dx * dy ;
// Biquadratic Interpolation
temp.qx = 0.5f*pow(dx,2);
temp.qy = 0.5f*pow(dy,2);
temp.dx = 0.5f*dx;
temp.dy = 0.5f*dy;
temp.dx2 = dx*dx;
temp.dy2 = dy*dy;
temp.dx3 = temp.dx2 * dx;
temp.dy3 = temp.dy2 * dy;
return temp;
}
uchar LookupTable::getBilinear(uchar *pixels_,int pos, int
cell){
weights wt = lookup_tf[pos];
int x = lookup_t[pos];
return wt.w[0]*pixels_[ (x*3) + cell]
+ wt.w[1]*pixels_[((x+1)*3) + cell]
+ wt.w[2]*pixels_[((x+max_x_)*3) + cell]
+ wt.w[3]*pixels_[((x+max_x_+1)*3) + cell];
}
uchar LookupTable::getBiquadratic(uchar *pixels_,int pos,
int cell){
weights wt = lookup_tf[pos];
int x = lookup_t[pos];
int C00 = pixels_[((x-max_x_-1)*3) + cell];
int C10 = pixels_[((x-max_x_)*3) + cell];
int C20 = pixels_[((x-max_x_+1)*3) + cell];
int C01 = pixels_[((x-1)*3) + cell];
int C11 = pixels_[(x*3) + cell];
int C21 = pixels_[((x+1)*3) + cell];
int C02 = pixels_[((x+max_x_-1)*3) + cell];
int C12 = pixels_[((x+max_x_)*3) + cell];
int C22 = pixels_[((x+max_x_+1)*3) + cell];
float Ca = C10+(C20-C00)*wt.dx + (C00-
2.0f*C10+C20)*wt.qx;
float Cb = C11+(C21-C01)*wt.dx + (C01-
2.0f*C11+C21)*wt.qx;
float Cc = C12+(C22-C02)*wt.dx + (C02-
2.0f*C12+C22)*wt.qx;
return Cb +(Cc - Ca)*wt.dy + (Ca -
2.0f*Cb+Cc)*wt.qy;
}
uchar LookupTable::getBicubic(uchar *pixels_,int pos, int
cell){
weights wt = lookup_tf[pos];
int x = lookup_t[pos];
float C0[4],C1[4],C2[4],C3[4];
C0[0] = pixels_[((x-max_x_-1)*3) + cell];
C1[0] = pixels_[((x-max_x_)*3) + cell];
C2[0] = pixels_[((x-max_x_+1)*3) + cell];
C3[0] = pixels_[((x-max_x_+2)*3) + cell];
C0[1] = pixels_[((x-1)*3) + cell];
C1[1] = pixels_[(x*3) + cell];
C2[1] = pixels_[((x+1)*3) + cell];
C3[1] = pixels_[((x+2)*3) + cell];
C0[2] = pixels_[((x+max_x_-1)*3) + cell];
C1[2] = pixels_[((x+max_x_)*3) + cell];
C2[2] = pixels_[((x+max_x_+1)*3) + cell];
C3[2] = pixels_[((x+max_x_+2)*3) + cell];
int two_r = max_x_ + max_x_;
C0[3] = pixels_[((x+two_r-1)*3) + cell];
C1[3] = pixels_[((x+two_r)*3) + cell];
C2[3] = pixels_[((x+two_r+1)*3) + cell];
C3[3] = pixels_[((x+two_r+2)*3) + cell];
float d0, d2, d3, a0, a1, a2, a3;
float C[4];
for(int j=0; j<4; ++j){
d0 = C0[j]-C1[j];
d2 = C2[j]-C1[j];
d3 = C3[j]-C1[j];
a0 = C1[j];
a1 = ((-1.0f/3.0f)*d0) + d2 - ((1.0f/6.0f)*d3);
a2 = (0.5f*d0) + (0.5f*d2);
a3 = ((-1.0f/6.0f)*d0) - (0.5f*d2) +
((1.0f/6.0f)*d3);
C[j] = a0 + a1*wt.dx + a2*wt.dx2 + a3*wt.dx3;
}
d0 = C[0]-C[1];
d2 = C[2]-C[1];
d3 = C[3]-C[1];
a0 = C[1];
a1 = ((-1.0f/3.0f)*d0) + d2 - ((1.0f/6.0f)*d3);
a2 = (0.5f*d0) + (0.5f*d2);
a3 = ((-1.0f/6.0f)*d0) - (0.5f*d2) + ((1.0f/6.0f)*d3);
return a0 + a1*wt.dy + a2*wt.dy2 + a3*wt.dy3;
}
void LookupTable::setInterpolation(Interpolation inter){
if(inter == None){
interpol = false;
}else
if(inter == Bilinear){
interpol = true;
interpol_function = &LookupTable::getBilinear;
}else
if(inter == Bicubic){
interpol = true;
interpol_function = &LookupTable::getBicubic;
}else
if(inter == Biquadratic){
interpol = true;
interpol_function = &LookupTable::getBiquadratic;
}
}
void LookupTable::compute_perspective_colour( cv::Mat src,
cv::Mat per, float phi_z, float theta_z, float f) {
int pos_y, pos_x, mphi_divp_phi,col, row_n, index_;
float theta, phi, ctheta_z, stheta_z, cphi_z, sphi_z;
sphi_z = sin(phi_z);
cphi_z = cos(phi_z);
stheta_z = sin(theta_z);
ctheta_z = cos(theta_z);
uchar *pixels = (unsigned char*)(src.data);
uchar *pixeld = (unsigned char*)(per.data);
int largd=per.step;
if(!interpol) // keep the code below if no
interpolation is needed
for(pos_y=1;pos_y<per.rows;++pos_y) {
for(pos_x=1;pos_x<per.cols;++pos_x) {
row_n = (-pos_y+per.rows/2);
col = (pos_x-per.cols/2);
index_ = f*cphi_z - (row_n)*sphi_z;
theta = 57.3248*atan2( ((index_)*stheta_z -
(col)*ctheta_z),((index_)*ctheta_z + (col)*stheta_z) );
phi = 57.3248*atan2( (f*sphi_z +
(row_n)*cphi_z),f*cphi_z );
if (theta < 0)
theta = theta + 360;
phi = phi + 90;
mphi_divp_phi = (((int)(MPHI - DIVP * phi))
* MTHETA) + (int)(DIVT * theta);
index_ = pos_y*largd+pos_x*3;
if ( (mphi_divp_phi < (MTP)) &&
(mphi_divp_phi > 0) ) {
if ( (lookup_t[mphi_divp_phi] <
max_x_*max_y_) && (lookup_t[mphi_divp_phi] >0 )) {
pixeld[index_] =
pixels[lookup_t[mphi_divp_phi]*3];
pixeld[index_+1] =
pixels[lookup_t[mphi_divp_phi]*3 + 1];
pixeld[index_+2] =
pixels[lookup_t[mphi_divp_phi]*3 + 2];
}else {
pixeld[index_] = 255;
pixeld[index_+1] = 255;
pixeld[index_+2] = 255;
}
}else {
pixeld[index_] = 0;
pixeld[index_+1] = 0;
pixeld[index_+2] = 0;
}
}
}
else
for(pos_y=1;pos_y<per.rows;++pos_y) {
for(pos_x=1;pos_x<per.cols;++pos_x) {
row_n = (-pos_y+per.rows/2);
col = (pos_x-per.cols/2);
index_ = f*cphi_z - (row_n)*sphi_z;
theta = 57.3248*atan2( ((index_)*stheta_z -
(col)*ctheta_z),((index_)*ctheta_z + (col)*stheta_z) );
phi = 57.3248*atan2( (f*sphi_z +
(row_n)*cphi_z),f*cphi_z );
if (theta < 0)
theta = theta + 360;
phi = phi + 90;
mphi_divp_phi = (((int)(MPHI - DIVP * phi))
* MTHETA) + (int)(DIVT * theta);
index_ = pos_y*largd+pos_x*3;
if ( (mphi_divp_phi < (MTP)) &&
(mphi_divp_phi > 0) ) {
if ( (lookup_t[mphi_divp_phi] <
max_x_*max_y_) && (lookup_t[mphi_divp_phi] >0 )) {
pixeld[index_] = (this-
>*interpol_function)(pixels,mphi_divp_phi, 0);
pixeld[index_+1] = (this-
>*interpol_function)(pixels,mphi_divp_phi, 1);
pixeld[index_+2] = (this-
>*interpol_function)(pixels,mphi_divp_phi, 2);
}else {
pixeld[index_] = 255;
pixeld[index_+1] = 255;
pixeld[index_+2] = 255;
}
}else {
pixeld[index_] = 0;
pixeld[index_+1] = 0;
pixeld[index_+2] = 0;
}
}
}
}
/**********************************************************
**************/
/* qt-opencv-multithreaded:
*/
/* A multithreaded OpenCV application using the Qt
framework. */
/*
*/
/* MatToQImage.h
*/
/*
*/
/* Nick D'Ademo <[email protected]>
*/
/*
*/
/* Copyright (c) 2012-2013 Nick D'Ademo
*/
/*
*/
/* Permission is hereby granted, free of charge, to any
person */
/* obtaining a copy of this software and associated
documentation */
/* files (the "Software"), to deal in the Software without
restriction, */
/* including without limitation the rights to use, copy,
modify, merge, */
/* publish, distribute, sublicense, and/or sell copies of
the Software, */
/* and to permit persons to whom the Software is furnished
to do so, */
/* subject to the following conditions:
*/
/*
*/
/* The above copyright notice and this permission notice
shall be */
/* included in all copies or substantial portions of the
Software. */
/*
*/
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
*/
/* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS */
/* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN */
/* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN */
/* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE */
/* SOFTWARE.
*/
/*
*/
/**********************************************************
**************/
#ifndef MATTOQIMAGE_H
#define MATTOQIMAGE_H
// Qt
#include <QtGui/QImage>
// OpenCV
#include <opencv/cv.h>
#include <opencv/highgui.h>
using namespace cv;
QImage MatToQImage(const Mat&);
#endif // MATTOQIMAGE_H
/**********************************************************
**************/
/* qt-opencv-multithreaded:
*/
/* A multithreaded OpenCV application using the Qt
framework. */
/*
*/
/* MatToQImage.cpp
*/
/*
*/
/* Nick D'Ademo <[email protected]>
*/
/*
*/
/* Copyright (c) 2012-2013 Nick D'Ademo
*/
/*
*/
/* Permission is hereby granted, free of charge, to any
person */
/* obtaining a copy of this software and associated
documentation */
/* files (the "Software"), to deal in the Software without
restriction, */
/* including without limitation the rights to use, copy,
modify, merge, */
/* publish, distribute, sublicense, and/or sell copies of
the Software, */
/* and to permit persons to whom the Software is furnished
to do so, */
/* subject to the following conditions:
*/
/*
*/
/* The above copyright notice and this permission notice
shall be */
/* included in all copies or substantial portions of the
Software. */
/*
*/
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
*/
/* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS */
/* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN */
/* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN */
/* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE */
/* SOFTWARE.
*/
/*
*/
/**********************************************************
**************/
#include "MatToQImage.h"
// Qt
#include <QDebug>
QImage MatToQImage(const Mat& mat)
{
// 8-bits unsigned, NO. OF CHANNELS=3
if(mat.type()==CV_8UC3)
{
// Copy input Mat
const uchar *qImageBuffer = (const uchar*)mat.data;
// Create QImage with same dimensions as input Mat
QImage img(qImageBuffer, mat.cols, mat.rows,
mat.step, QImage::Format_RGB888);
return img.rgbSwapped();
}
// 8-bits unsigned, NO. OF CHANNELS=1
else if(mat.type()==CV_8UC1)
{
// Set the color table (used to translate colour
indexes to qRgb values)
QVector<QRgb> colorTable;
for (int i=0; i<256; i++)
colorTable.push_back(qRgb(i,i,i));
// Copy input Mat
const uchar *qImageBuffer = (const uchar*)mat.data;
// Create QImage with same dimensions as input Mat
QImage img(qImageBuffer, mat.cols, mat.rows,
mat.step, QImage::Format_Indexed8);
img.setColorTable(colorTable);
return img;
}
else
{
qDebug() << "ERROR: Mat could not be converted to
QImage.";
return QImage();
}
}
#ifndef PANORAMICTHREAD_H
#define PANORAMICTHREAD_H
#include <camerathread.h>
#include <qthread.h>
#include <opencv/cv.h>
#include <lookuptable.h>
#include "facedetection.h"
class PanoramicThread : public QThread
{
Q_OBJECT
public:
explicit PanoramicThread(CameraThread *camera,
LookupTable *table,FaceDetection *face_detection,
QWaitCondition* frame_syn);
void ExtendPanoramic(cv::Mat dst);
void Stop();
bool face_on;
signals:
void updateLabelPanoramic(QImage extra);
private:
void run();
LookupTable *table_;
CameraThread *camera_;
FaceDetection *face_detection_;
QWaitCondition* frame_syn_;
cv::Mat frame_, dst_;
bool run_;
};
#endif // PANORAMICTHREAD_H
#include "panoramicthread.h"
#include <MatToQImage.h>
#include <stdio.h>
#include <qmutex.h>
PanoramicThread::PanoramicThread(CameraThread *camera,
LookupTable *table, FaceDetection *face_detection,
QWaitCondition *frame_syn) {
table_ = table;
camera_ = camera;
frame_syn_ = frame_syn;
run_ = true;
face_on = false;
face_detection_ = face_detection;
dst_ = Mat(camera_->getHieght()/2,camera->getWidth(),
CV_8UC3);
}
void PanoramicThread::Stop() {
run_ = false;
}
void PanoramicThread::ExtendPanoramic(cv::Mat dst) {
}
void PanoramicThread::run() {
// Lookup Tables
std::cout<<"Started PanoramicThread"<<std::endl;
QMutex temp;
while(run_){
temp.lock();
frame_syn_->wait(&temp);
frame_ = camera_->getLastFrame().clone();
table_->compute_panoramica_colour(frame_, dst_);
if(face_on){
ExtendPanoramic(dst_);
face_detection_->processImage(dst_);
}
emit updateLabelPanoramic(MatToQImage(dst_));
temp.unlock();
}
std::cout<<"Finshed PanoramicThread"<<std::endl;
}
#ifndef PERSPECTIVETHREAD_H
#define PERSPECTIVETHREAD_H
#include <camerathread.h>
#include <qthread.h>
#include <opencv/cv.h>
#include <lookuptable.h>
#include <facedetection.h>
struct Faces{
QImage face[8];
int size;
};
class PerspectiveThread : public QThread
{
Q_OBJECT
public:
PerspectiveThread(CameraThread* camera, void *winds,
LookupTable *table,FaceDetection* face_detection,
QWaitCondition* frame_syn);
void Stop();
void Zoom(bool zoom);
void inputKeyFace(XY key);
public slots:
void inputKey(XY key);
signals:
void updateLabelPerspective(Faces extra);
private:
void run();
LookupTable *table_;
CameraThread* camera_;
FaceDetection* face_detection_;
QWaitCondition* frame_syn_;
cv::Mat frame_ ;
cv::Mat per_ ;
Faces face_cont_;
FacePos faces_;
bool run_;
float phi_z_,phi_z_2_, theta_z_,theta_z_2_, dist_;
int x_,y_;
};
#endif // PERSPECTIVETHREAD_H
#include "perspectivethread.h"
#include <MatToQImage.h>
#include <stdio.h>
#include <QObject>
#include <qmutex.h>
PerspectiveThread::PerspectiveThread(CameraThread *camera,
void *winds, LookupTable *table,FaceDetection* face_detection,
QWaitCondition *frame_syn) {
table_ = table;
frame_syn_ = frame_syn;
QObject *wina = (QObject*)winds;
camera_ = camera;
run_ = true; dist_=170;
x_ = camera_->getWidth()/2; y_ = camera_-
>getHieght()/2;
per_ = Mat(100,100, CV_8UC3);
face_detection_ = face_detection;
connect(wina, SIGNAL(updateKey(XY)),
SLOT(inputKey(XY)));
face_cont_.size = 0;
faces_.size = 0;
}
void PerspectiveThread::Stop() {
run_ = false;
}
void PerspectiveThread::run() {
std::cout<<"Started PerspectiveThread"<<std::endl;
QMutex temp;
while(run_){
temp.lock();
frame_syn_->wait(&temp);
frame_ = camera_->getLastFrame().clone();
table_-
>compute_perspective_colour(frame_,per_,phi_z_,theta_z_,dist_)
;
resize(per_, per_, Size(200,200),0,0,
CV_INTER_LINEAR);
face_cont_.face[0] = MatToQImage(per_);
face_cont_.size = 0; // avoid old face pos
if(face_detection_->allowed()){
faces_ = face_detection_->update();
}
for(int i=0; i<faces_.size;++i){
inputKeyFace(faces_.face[i]);
table_-
>compute_perspective_colour(frame_,per_,phi_z_2_,theta_z_2_,di
st_);
if(!per_.empty())
face_cont_.face[i+1] =
MatToQImage(per_);
face_cont_.size = i+1;
}
emit updateLabelPerspective(face_cont_);
temp.unlock();
}
std::cout<<"Finshed PerspectiveThread"<<std::endl;
}
void PerspectiveThread::inputKey(XY key) {
theta_z_=(2*3.141592105*(float)(camera_->getWidth()-
key.x))/camera_->getWidth();
phi_z_=-1.3*((float)(key.y-camera_-
>getHieght()/8)/(camera_->getHieght()/2));
if(phi_z_>0.3)phi_z_=0.3;
}
void PerspectiveThread::inputKeyFace(XY key) {
theta_z_2_=(2*3.141592105*(float)(camera_->getWidth()-
key.x))/camera_->getWidth();
phi_z_2_=-1.3*((float)(key.y-camera_-
>getHieght()/8)/(camera_->getHieght()/2));
if(phi_z_2_>0.3)phi_z_2_=0.3;
}
void PerspectiveThread::Zoom(bool zoom){
if(zoom)
dist_ += 10;
else
dist_ -= 10;
}
#ifndef RECALCULATETHREAD_H
#define RECALCULATETHREAD_H
#include <QThread>
#include <lookuptable.h>
#include <camerathread.h>
class RecalculateThread : public QThread
{
Q_OBJECT
public:
explicit RecalculateThread(CameraThread *camera,
LookupTable *table);
void Stop();
void setLookUpTable(int x, int y);
private:
void run();
LookupTable *table_;
CameraThread* camera_;
bool run_, do_table_;
int x_,y_;
};
#endif // RECALCULATETHREAD_H
#include "recalculatethread.h"
RecalculateThread::RecalculateThread(CameraThread
*camera,LookupTable *table) {
table_ = table;
camera_ = camera;
run_ = true;
}
void RecalculateThread::Stop() {
run_ = false;
}
void RecalculateThread::run() {
while(run_){
if(do_table_){
table_->compute_lookuptables(x_,y_);
std::cout<<"sussfull"<<std::endl;
do_table_ = false;
}
}
}
void RecalculateThread::setLookUpTable(int x, int y){
std::cout<<"setLookUpTable"<<std::endl;
x_ = x;
y_ = y;
do_table_ = true;
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QKeyEvent>
#include <QMainWindow>
#include <camerathread.h>
#include <panoramicthread.h>
#include <perspectivethread.h>
#include <recalculatethread.h>
#include <qwaitcondition.h>
#include <facedetection.h>
#include <QLabel>
#include <QSize>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
bool eventFilter(QObject* watched, QEvent* event);
void PointersToNull();
void keyPressEvent(QKeyEvent * event);
void ClearImages();
void DeleteClasses();
void StopThreads();
void SetupGUIVaules();
bool StartCamera(bool image);
void StartPanoramic();
void StartPerspective();
void StopPerspective();
void StopPanoramic();
void StopCamera();
public slots:
void onLabelOrignal(QImage Image);
void onLabelPanoramic(QImage Image);
void onLabelPerspective(Faces Images);
void onMenuCameraDeviceClick();
void onMenuCameraResClick();
void onMenuCameraImageClick();
void onMenuExitClick();
void onClickRadioButtons();
private slots:
void on_pushButton_start_clicked();
void on_pushButton_face_clicked();
void on_horizontalSlider_face_valueChanged(int value);
void on_horizontalSlider_seconds_valueChanged(int
value);
signals:
void updateKey(XY key);
private:
LookupTable *table_;
CameraThread *camera_;
FaceDetection *face_detection_;
PanoramicThread *panoramic_;
PerspectiveThread *perspective_;
RecalculateThread *calculate_;
QWaitCondition wait_frame;
uint device_num_;
bool threads_running_, stop_mouse_event_;
int counter_;
QLabel *face_pointer_;
Resolution cam_res_;
QString image_path_;
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
//mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "iostream"
#include "qinputdialog.h"
#include "qfiledialog.h"
#include "qmessagebox.h"
#include "QtGui"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow) {
ui->setupUi(this);
device_num_ = 0;
cam_res_.height = 480;
cam_res_.width = 640;
image_path_.clear();
threads_running_ = false;
ui->pushButton_face->hide();
ui->groupBox_face_tool->hide();
ui->groupBox_inter->hide();
ui->lcdNumber_seconds->display(1.5);
ui->label_panoramic->setAccessibleName(ui-
>label_panoramic->text());
ui->label_zoom->setAccessibleName(ui->label_zoom-
>text());
ui->label_orignal->setAccessibleName(ui->label_orignal-
>text());
qRegisterMetaType<Faces>("Faces");
// connect some event to self defined functions
connect(ui->actionSpecifiy_Camera, SIGNAL(triggered()),
this, SLOT(onMenuCameraDeviceClick()));
connect(ui->actionInput_Image, SIGNAL(triggered()),
this, SLOT(onMenuCameraImageClick()));
connect(ui->actionChange_Resolution,
SIGNAL(triggered()), this, SLOT(onMenuCameraResClick()));
connect(ui->actionExit, SIGNAL(triggered()), this,
SLOT(onMenuExitClick()));
// connect radio buttons to one function
connect(ui->radioButton_none, SIGNAL(clicked()), this,
SLOT(onClickRadioButtons()));
connect(ui->radioButton_bilinear, SIGNAL(clicked()),
this, SLOT(onClickRadioButtons()));
connect(ui->radioButton_bicubic, SIGNAL(clicked()),
this, SLOT(onClickRadioButtons()));
connect(ui->radioButton_biquadratic, SIGNAL(clicked()),
this, SLOT(onClickRadioButtons()));
PointersToNull();
}
MainWindow::~MainWindow() {
if(threads_running_){
on_pushButton_start_clicked();
QWidget::close();
}else{
QWidget::close();
}
delete ui;
}
void MainWindow::PointersToNull(){
camera_ = 0;
panoramic_ = 0;
perspective_ = 0;
calculate_ = 0;
table_ = 0;
face_detection_ = 0;
}
void MainWindow::onLabelOrignal(QImage Image) {
ui->label_orignal->setPixmap(QPixmap::fromImage(Image).
scaled(ui->label_orignal-
>width(),
ui->label_orignal-
>height(),
Qt::KeepAspectRatioByExpanding));
}
void MainWindow::onLabelPanoramic(QImage Image){
ui->label_panoramic-
>setPixmap(QPixmap::fromImage(Image).
scaled(ui-
>label_panoramic->width(),
ui->label_panoramic-
>height(),
Qt::KeepAspectRatioByExpanding));
}
void MainWindow::onLabelPerspective(Faces Images){
ui->label_zoom-
>setPixmap(QPixmap::fromImage(Images.face[0]).
scaled(ui->label_zoom-
>width(),
ui->label_zoom->height(),
Qt::KeepAspectRatio));
for (counter_ = 0; counter_ < ui->lcdNumber_faces-
>value(); ++counter_){
face_pointer_ = (QLabel*)ui->groupBox_per_face-
>itemAt(counter_)->widget();
if(Images.size > counter_){
face_pointer_-
>setPixmap(QPixmap::fromImage(Images.face[counter_+1]).
scaled(face_pointer_-
>width(),
face_pointer_-
>height(),
Qt::KeepAspectRatio));
}else{
face_pointer_->setText("Waiting..");
}
}
}
void MainWindow::ClearImages()
{
QApplication::processEvents(); // wait for slots to
disconnect
ui->label_orignal->setText(ui->label_orignal-
>accessibleName());
ui->label_panoramic->setText(ui->label_panoramic-
>accessibleName());
ui->label_zoom->setText(ui->label_zoom-
>accessibleName());
}
void MainWindow::SetupGUIVaules()
{
ui->label_orignal->installEventFilter(this);
ui->label_panoramic->installEventFilter(this);
}
void MainWindow::StartPanoramic()
{
panoramic_ = new PanoramicThread(camera_,
table_,face_detection_, &wait_frame);
connect(panoramic_,
SIGNAL(updateLabelPanoramic(QImage)),
SLOT(onLabelPanoramic(QImage)));
panoramic_->start();
}
void MainWindow::StopPanoramic()
{
panoramic_->Stop();
panoramic_->wait();
delete panoramic_;
}
void MainWindow::StartPerspective()
{
perspective_ = new PerspectiveThread(camera_,this,
table_,face_detection_, &wait_frame);
connect(perspective_,
SIGNAL(updateLabelPerspective(Faces)),
SLOT(onLabelPerspective(Faces)));
perspective_->start();
}
void MainWindow::StopPerspective()
{
perspective_->Stop();
perspective_->wait();
delete perspective_;
}
bool MainWindow::StartCamera(bool image)
{
if(image){
camera_ = new
CameraThread(image_path_.toStdString(), &wait_frame);
image_path_.clear();
}else{
camera_ = new CameraThread(device_num_,
&wait_frame, cam_res_);
if(!camera_->IsCameraOn()){
delete camera_;
return false;
}
}
connect(camera_, SIGNAL(updateLabelOrignal(QImage)),
SLOT(onLabelOrignal(QImage)));
camera_->start();
std::cout<<camera_->getWidth()<<","<<camera_-
>getHieght()<<std::endl;
table_ = new LookupTable(camera_->getWidth(),camera_-
>getHieght());
face_detection_ = new
FaceDetection("haarcascade_frontalface_alt.xml",
500*ui-
>horizontalSlider_seconds->value(),
ui-
>horizontalSlider_face->value());
// calculate_ = new RecalculateThread(camera_, table_);
// calculate_->start();
return true;
}
void MainWindow::StopCamera()
{
// calculate_->Stop();
// calculate_->wait();
camera_->Stop();
camera_->wait();
// delete calculate_;
delete camera_;
delete table_;
if(face_detection_ != NULL){
this->resize(1060, this->size().height());
panoramic_->face_on = false;
ui->pushButton_face->setText("Detection Mode");
delete face_detection_;
ui->pushButton_face->hide();
ui->groupBox_inter->hide();
ui->groupBox_face_tool->hide();
}
}
void MainWindow::on_pushButton_start_clicked() {
if(!threads_running_){
if(image_path_.isEmpty()){
if(!StartCamera(false))
return; // failed to connect to a camera
}else{
StartCamera(true);
}
SetupGUIVaules();
StartPanoramic();
StartPerspective();
ui->pushButton_start->setText("Stop");
ui->pushButton_face->show();
ui->groupBox_inter->show();
threads_running_ = true;
}else{
threads_running_ = false;
ui->pushButton_start->setText("Start");
StopPerspective();
StopPanoramic();
StopCamera();
PointersToNull();
ClearImages();
}
}
void MainWindow::keyPressEvent(QKeyEvent *event){
if (event->key() == Qt::Key_Escape || event->key() ==
Qt::Key_Q) {
if(threads_running_){
on_pushButton_start_clicked();
QWidget::close();
}else{
QWidget::close();
}
}else if(event->key() == Qt::Key_S){
if(stop_mouse_event_)
stop_mouse_event_ = false;
else
stop_mouse_event_ = true;
}
}
bool MainWindow::eventFilter(QObject* watched, QEvent*
event)
{
if(table_ == NULL)
return false;
const QMouseEvent* const mouse_pos = static_cast<const
QMouseEvent*>(event);
int x ,y; x=y=0;
if(camera_ != NULL && !camera_->test_res_){
x = mouse_pos->pos().x()*camera_->getWidth()/ui-
>label_orignal->width();
y = mouse_pos->pos().y()*camera_->getHieght()/ui-
>label_orignal->height();
}
if(watched == ui->label_orignal){
if (event->type() == QEvent::MouseButtonPress){
table_->compute_lookuptables(x , y);
}else{
if(x!=0&&y!=0){
ui->label_x_print->setNum(x);
ui->label_y_print->setNum(y);
}
}
}else if(watched == ui->label_panoramic &&
!stop_mouse_event_){
if (event->type() == QEvent::MouseButtonPress){
if(((QMouseEvent *)event)->button() ==
Qt::LeftButton)//casting
perspective_->Zoom(true);
else
perspective_->Zoom(false);
}else{
if(x!=0&&y!=0){
ui->label_x_print->setNum(x);
ui->label_y_print->setNum(y);
XY temp;
temp.x = x;
temp.y = y;
emit updateKey(temp);
}
}
}
return false;
}
void MainWindow::onMenuCameraDeviceClick(){
device_num_ = QInputDialog::getInt(this, tr("Camera
Number"),
tr("Device
Num:"), QLineEdit::Normal, -1);
}
void MainWindow::onMenuCameraImageClick(){
QFileDialog dialog(this);
dialog.setNameFilter(tr("Images (*.png *.xpm *.jpg
*.bmp)"));
dialog.setViewMode(QFileDialog::Detail);
image_path_ = QFileDialog::getOpenFileName(this,
tr("Open File"),
"C:/",
tr("Images (*.png *.xpm *.jpg *.bmp)"));
if(!image_path_.isEmpty()){
std::cout<<image_path_.toStdString()<<std::endl;
if(threads_running_)
on_pushButton_start_clicked();
on_pushButton_start_clicked();
}
}
std::string ResToString(Resolutions res){
QString info;
info = "Enter the id of the Resolution:\n";
for(int i = 0; i < res.size; ++i){
info+= "[" + QString::number(i) +"] "+
QString::number(res.all[i].width)+
"x"+
QString::number(res.all[i].height)+
"\n";
}
return info.toStdString();
}
void MainWindow::onMenuCameraResClick(){
if(camera_ == NULL){
camera_ = new CameraThread(device_num_);
Resolutions supported_res = camera_->CheckRes();
cam_res_ =
supported_res.all[QInputDialog::getInt(this, tr("Camera
Resolutions"),
tr(ResToString(supported_res).c_str()),
QLineEdit::Normal, 0, supported_res.size-1)];
delete camera_;
camera_ = NULL;
}else{
QMessageBox msgBox;
msgBox.setText("Please press the stop button
first.");
msgBox.setIcon(QMessageBox::Information);
msgBox.exec();
}
}
void MainWindow::onMenuExitClick(){
if(threads_running_){
on_pushButton_start_clicked();
QWidget::close();
}else{
QWidget::close();
}
}
void MainWindow::on_pushButton_face_clicked()
{
if(this->size().width()==1060){
this->resize(1640, this->size().height());
panoramic_->face_on = true;
ui->pushButton_face->setText("Stop Detecting");
ui->groupBox_face_tool->show();
}else{
ui->groupBox_face_tool->hide();
this->resize(1060, this->size().height());
panoramic_->face_on = false;
ui->pushButton_face->setText("Detection Mode");
face_detection_->clear();
}
}
void MainWindow::on_horizontalSlider_face_valueChanged(int
value)
{
ui->lcdNumber_faces->display(value);
if(face_detection_ != NULL){
for (counter_ = 0; counter_ < ui-
>groupBox_per_face->count(); ++counter_){
face_pointer_ = (QLabel*)ui->groupBox_per_face-
>itemAt(counter_)->widget();
if(counter_>=value){
face_pointer_->hide();
}else{
face_pointer_->show();
}
}
face_detection_->ChangeFaceCount(value);
}
}
void
MainWindow::on_horizontalSlider_seconds_valueChanged(int
value)
{
ui->lcdNumber_seconds->display(value*.5);
if(face_detection_ != NULL)
face_detection_->ChangeRefresh((500)*value);
}
void MainWindow::onClickRadioButtons(){
if(table_ != NULL){
if(ui->radioButton_none->isChecked()){
table_->setInterpolation(None);
}else
if(ui->radioButton_bicubic->isChecked()){
table_->setInterpolation(Bicubic);
}else
if(ui->radioButton_biquadratic->isChecked()){
table_->setInterpolation(Biquadratic);
}else
if(ui->radioButton_bilinear->isChecked()){
table_->setInterpolation(Bilinear);
}
}
}
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1060</width>
<height>856</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<property name="tabShape">
<enum>QTabWidget::Rounded</enum>
</property>
<widget class="QWidget" name="centralWidget">
<widget class="QLabel" name="label_orignal">
<property name="geometry">
<rect>
<x>30</x>
<y>260</y>
<width>640</width>
<height>480</height>
</rect>
</property>
<property name="mouseTracking">
<bool>true</bool>
</property>
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="text">
<string><html><head/><body><p><span
style=" font-size:16pt;">Camera
</span><span style=" font-size:16pt;
color:#55aa00;">View</span></p></body&g
t;</html></string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
<widget class="QPushButton" name="pushButton_start">
<property name="geometry">
<rect>
<x>940</x>
<y>760</y>
<width>91</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>11</pointsize>
</font>
</property>
<property name="text">
<string>Start</string>
</property>
</widget>
<widget class="QLabel" name="label_panoramic">
<property name="geometry">
<rect>
<x>30</x>
<y>10</y>
<width>640</width>
<height>240</height>
</rect>
</property>
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="text">
<string><html><head/><body><p><span
style=" font-size:16pt;">Panoramic
</span><span style=" font-size:16pt;
color:#55aa00;">View</span></p></body&g
t;</html></string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
<widget class="QLabel" name="label_zoom">
<property name="geometry">
<rect>
<x>730</x>
<y>10</y>
<width>300</width>
<height>300</height>
</rect>
</property>
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="text">
<string><html><head/><body><p><span
style=" font-size:16pt;">Perspective
</span><span style=" font-size:16pt;
color:#55aa00;">View</span></p></body&g
t;</html></string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>710</x>
<y>530</y>
<width>321</width>
<height>221</height>
</rect>
</property>
<property name="text">
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD
HTML 4.0//EN" "http://www.w3.org/TR/REC-
html40/strict.dtd">
<html><head><meta name="qrichtext"
content="1" /><style
type="text/css">
p, li { white-space: pre-wrap; }
</style></head><body style=" font-
family:'Sans Serif'; font-size:9pt; font-weight:400; font-
style:normal;">
<p style=" margin-top:0px; margin-bottom:0px;
margin-left:0px; margin-right:0px; -qt-block-indent:0; text-
indent:0px;"><span style=" font-
size:16pt;">Panoramic </span><span
style=" font-size:16pt;
color:#55aa00;">View</span><span style="
font-size:16pt;
color:#000000;">:</span></p>
<ul style="margin-top: 0px; margin-bottom: 0px;
margin-left: 0px; margin-right: 0px; -qt-list-indent:
1;"><li style=" margin-top:12px; margin-
bottom:0px; margin-left:0px; margin-right:0px; -qt-block-
indent:0; text-indent:0px;"><span style="
font-size:12pt;
color:#ff0000;">Left</span><span style="
font-size:12pt; color:#0000ff;"> </span><span
style=" font-size:12pt;">click to zoom
in.</span></li>
<li style=" margin-top:0px; margin-bottom:0px;
margin-left:0px; margin-right:0px; -qt-block-indent:0; text-
indent:0px;"><span style=" font-size:12pt;
color:#ff0000;">Right </span><span
style=" font-size:12pt;">click to zoom
out.</span></li>
<li style=" font-size:12pt;" style="
margin-top:0px; margin-bottom:0px; margin-left:0px; margin-
right:0px; -qt-block-indent:0; text-indent:0px;">Press
<span style=" color:#ff0000;">S</span>
to lock/release view.</li></ul>
<p style=" margin-top:12px; margin-bottom:12px;
margin-left:0px; margin-right:0px; -qt-block-indent:0; text-
indent:0px;"><span style=" font-
size:16pt;">Camera </span><span style="
font-size:16pt;
color:#55aa00;">View</span><span style="
font-size:16pt;
color:#000000;">:</span></p>
<ul style="margin-top: 0px; margin-bottom: 0px;
margin-left: 0px; margin-right: 0px; -qt-list-indent:
1;"><li style=" margin-top:12px; margin-
bottom:0px; margin-left:0px; margin-right:0px; -qt-block-
indent:0; text-indent:0px;"><span style="
font-size:12pt;
color:#ff0000;">Click</span><span
style=" font-size:12pt;"> to recalculate lookup
table.</span></li></ul></body></htm
l></string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
</widget>
<widget class="QLabel" name="label_x_name">
<property name="geometry">
<rect>
<x>30</x>
<y>740</y>
<width>16</width>
<height>16</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>x:</string>
</property>
</widget>
<widget class="QLabel" name="label_y_name">
<property name="geometry">
<rect>
<x>30</x>
<y>760</y>
<width>16</width>
<height>21</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>y:</string>
</property>
</widget>
<widget class="QLabel" name="label_x_print">
<property name="geometry">
<rect>
<x>60</x>
<y>745</y>
<width>57</width>
<height>15</height>
</rect>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="QLabel" name="label_y_print">
<property name="geometry">
<rect>
<x>60</x>
<y>765</y>
<width>57</width>
<height>15</height>
</rect>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="QPushButton" name="pushButton_face">
<property name="enabled">
<bool>true</bool>
</property>
<property name="geometry">
<rect>
<x>780</x>
<y>760</y>
<width>141</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>11</pointsize>
</font>
</property>
<property name="text">
<string>Detection Mode</string>
</property>
</widget>
<widget class="QGroupBox" name="groupBox_face_tool">
<property name="geometry">
<rect>
<x>710</x>
<y>400</y>
<width>341</width>
<height>151</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="title">
<string>Face Detection Tools</string>
</property>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>120</x>
<y>40</y>
<width>131</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>Faces to detect</string>
</property>
</widget>
<widget class="QLabel" name="label_3">
<property name="geometry">
<rect>
<x>210</x>
<y>90</y>
<width>71</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>Seconds</string>
</property>
</widget>
<widget class="QSlider" name="horizontalSlider_face">
<property name="geometry">
<rect>
<x>10</x>
<y>70</y>
<width>311</width>
<height>16</height>
</rect>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>6</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="value">
<number>6</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::NoTicks</enum>
</property>
<property name="tickInterval">
<number>0</number>
</property>
</widget>
<widget class="QLCDNumber" name="lcdNumber_faces">
<property name="geometry">
<rect>
<x>60</x>
<y>40</y>
<width>51</width>
<height>23</height>
</rect>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="digitCount">
<number>1</number>
</property>
<property name="segmentStyle">
<enum>QLCDNumber::Flat</enum>
</property>
<property name="intValue" stdset="0">
<number>6</number>
</property>
</widget>
<widget class="QLCDNumber" name="lcdNumber_seconds">
<property name="geometry">
<rect>
<x>150</x>
<y>90</y>
<width>51</width>
<height>23</height>
</rect>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="smallDecimalPoint">
<bool>true</bool>
</property>
<property name="digitCount">
<number>3</number>
</property>
<property name="segmentStyle">
<enum>QLCDNumber::Flat</enum>
</property>
<property name="value" stdset="0">
<double>1.000000000000000</double>
</property>
<property name="intValue" stdset="0">
<number>1</number>
</property>
</widget>
<widget class="QLabel" name="label_4">
<property name="geometry">
<rect>
<x>40</x>
<y>90</y>
<width>111</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>Detect every</string>
</property>
</widget>
<widget class="QSlider"
name="horizontalSlider_seconds">
<property name="geometry">
<rect>
<x>7</x>
<y>120</y>
<width>311</width>
<height>16</height>
</rect>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>10</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="value">
<number>4</number>
</property>
<property name="sliderPosition">
<number>4</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::NoTicks</enum>
</property>
<property name="tickInterval">
<number>0</number>
</property>
</widget>
</widget>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>1060</x>
<y>60</y>
<width>561</width>
<height>691</height>
</rect>
</property>
<layout class="QGridLayout" name="groupBox_per_face"
columnstretch="0,0">
<property name="sizeConstraint">
<enum>QLayout::SetNoConstraint</enum>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_face_1">
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="text">
<string><html><head/><body><p><span
style=" font-size:16pt; color:#55aa00;">Face
</span><span style=" font-size:16pt;
color:#000000;">One</span></p></body>
;</html></string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_face_4">
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="text">
<string><html><head/><body><p><span
style=" font-size:16pt; color:#55aa00;">Face
</span><span style=" font-size:16pt;
color:#000000;">Four</span></p></body&g
t;</html></string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_face_2">
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="text">
<string><html><head/><body><p><span
style=" font-size:16pt; color:#55aa00;">Face
</span><span style=" font-size:16pt;
color:#000000;">Two</span></p></body>
;</html></string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="label_face_5">
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="text">
<string><html><head/><body><p><span
style=" font-size:16pt; color:#55aa00;">Face
</span><span style=" font-size:16pt;
color:#000000;">Five</span></p></body&g
t;</html></string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_face_3">
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="text">
<string><html><head/><body><p><span
style=" font-size:16pt; color:#55aa00;">Face
</span><span style=" font-size:16pt;
color:#000000;">Three</span></p></body&
gt;</html></string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="label_face_6">
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="text">
<string><html><head/><body><p><span
style=" font-size:16pt; color:#55aa00;">Face
</span><span style=" font-size:16pt;
color:#000000;">Six</span></p></body>
;</html></string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QGroupBox" name="groupBox_inter">
<property name="geometry">
<rect>
<x>710</x>
<y>320</y>
<width>341</width>
<height>71</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
<italic>true</italic>
</font>
</property>
<property name="title">
<string>Interpolation</string>
</property>
<widget class="QRadioButton" name="radioButton_none">
<property name="geometry">
<rect>
<x>10</x>
<y>20</y>
<width>71</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>None</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
<widget class="QRadioButton"
name="radioButton_bilinear">
<property name="geometry">
<rect>
<x>100</x>
<y>20</y>
<width>71</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Bilinear</string>
</property>
</widget>
<widget class="QRadioButton"
name="radioButton_bicubic">
<property name="geometry">
<rect>
<x>190</x>
<y>20</y>
<width>71</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Bicubic</string>
</property>
</widget>
<widget class="QRadioButton"
name="radioButton_biquadratic">
<property name="geometry">
<rect>
<x>10</x>
<y>40</y>
<width>231</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Biquadratic (Recommended)</string>
</property>
</widget>
</widget>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1060</width>
<height>21</height>
</rect>
</property>
<widget class="QMenu" name="menuMenu">
<property name="title">
<string>Menu</string>
</property>
<addaction name="separator"/>
<addaction name="actionExit"/>
</widget>
<widget class="QMenu" name="menuCamera">
<property name="title">
<string>Camera</string>
</property>
<addaction name="actionSpecifiy_Camera"/>
<addaction name="actionInput_Image"/>
<addaction name="actionChange_Resolution"/>
</widget>
<addaction name="menuMenu"/>
<addaction name="menuCamera"/>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
<action name="actionExit">
<property name="text">
<string>&Exit</string>
</property>
</action>
<action name="actionSpecifiy_Camera">
<property name="text">
<string>Specifiy Camera</string>
</property>
</action>
<action name="actionInput_Image">
<property name="text">
<string>Input Image</string>
</property>
</action>
<action name="actionChange_Resolution">
<property name="text">
<string>Change Resolution</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>