Subversion Repositories seema-scanner

Rev

Rev 41 | Rev 43 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 41 Rev 42
1
#include "SMPointCloudWidget.h"
1
#include "SMPointCloudWidget.h"
2
 
2
 
3
#include <opencv2/opencv.hpp>
3
#include <opencv2/opencv.hpp>
4
#include <opencv2/core/eigen.hpp>
4
#include <opencv2/core/eigen.hpp>
5
 
5
 
6
#include <vtkWindowToImageFilter.h>
6
#include <vtkWindowToImageFilter.h>
7
#include <vtkPNGWriter.h>
7
#include <vtkPNGWriter.h>
8
#include <vtkRenderWindow.h>
8
#include <vtkRenderWindow.h>
9
 
9
 
10
#include <pcl/point_cloud.h>
10
#include <pcl/point_cloud.h>
11
#include <pcl/point_types.h>
11
#include <pcl/point_types.h>
12
#include <pcl/common/io.h>
12
#include <pcl/common/io.h>
13
#include <pcl/visualization/point_cloud_color_handlers.h>
13
#include <pcl/visualization/point_cloud_color_handlers.h>
14
#include <pcl/geometry/quad_mesh.h>
14
#include <pcl/geometry/quad_mesh.h>
15
 
15
 
16
#include <pcl/io/pcd_io.h>
16
#include <pcl/io/pcd_io.h>
17
#include <pcl/io/ascii_io.h>
17
#include <pcl/io/ascii_io.h>
18
#include <pcl/io/ply_io.h>
18
#include <pcl/io/ply_io.h>
19
#include <pcl/io/png_io.h>
19
#include <pcl/io/png_io.h>
20
#include <pcl/io/vtk_io.h>
20
#include <pcl/io/vtk_io.h>
21
#include <vtkPolyDataWriter.h>
21
#include <vtkPolyDataWriter.h>
22
#include <pcl/conversions.h>
22
#include <pcl/conversions.h>
23
 
23
 
24
#include <fstream>
24
#include <fstream>
25
 
25
 
26
#include <QFileDialog>
26
#include <QFileDialog>
27
#include <QSettings>
27
#include <QSettings>
28
 
28
 
29
#include "SMCalibrationParameters.h"
29
#include "SMCalibrationParameters.h"
30
 
30
 
31
SMPointCloudWidget::SMPointCloudWidget(QWidget *parent) : QVTKWidget(parent) {
31
SMPointCloudWidget::SMPointCloudWidget(QWidget *parent) : QVTKWidget(parent) {
32
 
32
 
33
    visualizer = new pcl::visualization::PCLVisualizer("PCLVisualizer", false);
33
    visualizer = new pcl::visualization::PCLVisualizer("PCLVisualizer", false);
34
    this->SetRenderWindow(visualizer->getRenderWindow());
34
    this->SetRenderWindow(visualizer->getRenderWindow());
35
 
35
 
36
    visualizer->setShowFPS(false);
36
    visualizer->setShowFPS(false);
37
 
37
 
38
    // Create point cloud viewport
38
    // Create point cloud viewport
39
    visualizer->setBackgroundColor(0, 0, 0);
39
    visualizer->setBackgroundColor(0, 0, 0);
40
    visualizer->addCoordinateSystem(100, 0);
40
    visualizer->addCoordinateSystem(100, 0);
41
#ifndef __APPLE__
41
#ifndef __APPLE__
42
    // this leads to a segfault on OS X
42
    // this leads to a segfault on OS X
43
    visualizer->setCameraPosition(0,0,-50,0,0,0,0,-1,0);
43
    visualizer->setCameraPosition(0,0,-50,0,0,0,0,-1,0);
44
#endif
44
#endif
45
 
45
 
46
    // Initialize point cloud color handler
46
    // Initialize point cloud color handler
47
    colorHandler = new pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGB>();
47
    colorHandler = new pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGB>();
48
 
48
 
49
    updateCalibrationParameters();
49
    updateCalibrationParameters();
50
    //time.start();
50
    //time.start();
51
}
51
}
52
 
52
 
53
void SMPointCloudWidget::addPointCloud(PointCloudConstPtr _pointCloudPCL){
53
void SMPointCloudWidget::addPointCloud(PointCloudPtr _pointCloudPCL){
54
 
54
 
55
//    time.restart();
55
//    time.restart();
56
 
56
 
57
    pointCloudPCL = _pointCloudPCL;
57
    pointCloudPCL = _pointCloudPCL;
58
 
58
 
59
    // Note: using the color handler makes a copy of the rgb fields
59
    // Note: using the color handler makes a copy of the rgb fields
60
    colorHandler->setInputCloud(_pointCloudPCL);
60
    colorHandler->setInputCloud(_pointCloudPCL);
61
 
61
 
62
    visualizer->addPointCloud(pointCloudPCL, *colorHandler, "pointCloudPCL");
62
    visualizer->addPointCloud(pointCloudPCL, *colorHandler, "pointCloudPCL");
63
    visualizer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2.0, "pointCloudPCL");
63
    visualizer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2.0, "pointCloudPCL");
64
 
64
 
65
    this->update();
65
    this->update();
66
    emit newPointCloudDisplayed();
66
    emit newPointCloudDisplayed();
67
 
67
 
68
//    std::cout << "PCL Widget: " << time.restart() << "ms" << std::endl;
68
//    std::cout << "PCL Widget: " << time.restart() << "ms" << std::endl;
69
}
69
}
70
 
70
 
71
void SMPointCloudWidget::updatePointCloud(PointCloudConstPtr _pointCloudPCL){
71
void SMPointCloudWidget::updatePointCloud(PointCloudPtr _pointCloudPCL){
72
 
72
 
73
//    time.restart();
73
//    time.restart();
74
 
74
 
75
    pointCloudPCL = _pointCloudPCL;
75
    pointCloudPCL = _pointCloudPCL;
76
 
76
 
77
    // Note: using the color handler makes a copy of the rgb fields
77
    // Note: using the color handler makes a copy of the rgb fields
78
    colorHandler->setInputCloud(_pointCloudPCL);
78
    colorHandler->setInputCloud(_pointCloudPCL);
79
 
79
 
80
    if(!visualizer->updatePointCloud(pointCloudPCL, *colorHandler, "pointCloudPCL")){
80
    if(!visualizer->updatePointCloud(pointCloudPCL, *colorHandler, "pointCloudPCL")){
81
        visualizer->addPointCloud(pointCloudPCL, *colorHandler, "pointCloudPCL");
81
        visualizer->addPointCloud(pointCloudPCL, *colorHandler, "pointCloudPCL");
82
        visualizer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2.0, "pointCloudPCL");
82
        visualizer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2.0, "pointCloudPCL");
83
     }
83
     }
84
 
84
 
85
    this->update();
85
    this->update();
86
    emit newPointCloudDisplayed();
86
    emit newPointCloudDisplayed();
87
 
87
 
88
//    std::cout << "PCL Widget: " << time.restart() << "ms" << std::endl;
88
//    std::cout << "PCL Widget: " << time.restart() << "ms" << std::endl;
89
}
89
}
90
 
90
 
91
void SMPointCloudWidget::savePointCloud(){
91
void SMPointCloudWidget::savePointCloud(){
92
 
92
 
93
    QString selectedFilter;
93
    QString selectedFilter;
94
    QString fileName = QFileDialog::getSaveFileName(this, "Save Point Cloud", QString(), "*.pcd;;*.ply;;*.vtk;;*.png;;*.txt", &selectedFilter);
94
    QString fileName = QFileDialog::getSaveFileName(this, "Save Point Cloud", QString(), "*.pcd;;*.ply;;*.vtk;;*.png;;*.txt", &selectedFilter);
95
    QFileInfo info(fileName);
95
    QFileInfo info(fileName);
96
    QString type = info.suffix();
96
    QString type = info.suffix();
97
    if(type == ""){
97
    if(type == ""){
98
        fileName.append(selectedFilter.remove(0,1));
98
        fileName.append(selectedFilter.remove(0,1));
99
        type = selectedFilter.remove(0,1);
99
        type = selectedFilter.remove(0,1);
100
    }
100
    }
101
 
101
 
102
    if(type == "pcd"){
102
    if(type == "pcd"){
103
        pcl::io::savePCDFileASCII(fileName.toStdString(), *pointCloudPCL);
103
        pcl::io::savePCDFileASCII(fileName.toStdString(), *pointCloudPCL);
104
    } else if(type == "ply"){
104
    } else if(type == "ply"){
105
        //pcl::io::savePLYFileBinary(fileName.toStdString(), *pointCloudPCL);
105
        //pcl::io::savePLYFileBinary(fileName.toStdString(), *pointCloudPCL);
106
        pcl::PLYWriter w;
106
        pcl::PLYWriter w;
107
        // Write to ply in binary without camera
107
        // Write to ply in binary without camera
108
        w.write<pcl::PointXYZRGB> (fileName.toStdString(), *pointCloudPCL, true, false);
108
        w.write<pcl::PointXYZRGB> (fileName.toStdString(), *pointCloudPCL, true, false);
109
    } else if(type == "vtk"){
109
    } else if(type == "vtk"){
110
        pcl::PCLPointCloud2 pointCloud2;
110
        pcl::PCLPointCloud2 pointCloud2;
111
        pcl::toPCLPointCloud2(*pointCloudPCL, pointCloud2);
111
        pcl::toPCLPointCloud2(*pointCloudPCL, pointCloud2);
112
        pcl::io::saveVTKFile(fileName.toStdString(), pointCloud2);
112
        pcl::io::saveVTKFile(fileName.toStdString(), pointCloud2);
113
 
113
 
114
//        vtkPolyData polyData;
114
//        vtkPolyData polyData;
115
//        pcl::io::pointCloudTovtkPolyData(*pointCloudPCL, polyData);
115
//        pcl::io::pointCloudTovtkPolyData(*pointCloudPCL, polyData);
116
//        vtkPolyDataWriter::Pointer writer = vtkPolyDataWriter::New();
116
//        vtkPolyDataWriter::Pointer writer = vtkPolyDataWriter::New();
117
//        writer->SetInput(polyData);
117
//        writer->SetInput(polyData);
118
//        writer->SetFileName(fileName.toStdString());
118
//        writer->SetFileName(fileName.toStdString());
119
//        writer->Update();
119
//        writer->Update();
120
    } else if(type == "png"){
120
    } else if(type == "png"){
121
        pcl::io::savePNGFile(fileName.toStdString(), *pointCloudPCL, "rgb");
121
        pcl::io::savePNGFile(fileName.toStdString(), *pointCloudPCL, "rgb");
122
    } else if(type == "txt"){
122
    } else if(type == "txt"){
123
        std::ofstream s(fileName.toLocal8Bit());
123
        std::ofstream s(fileName.toLocal8Bit());
124
        for(unsigned int r=0; r<pointCloudPCL->height; r++){
124
        for(unsigned int r=0; r<pointCloudPCL->height; r++){
125
            for(unsigned int c=0; c<pointCloudPCL->width; c++){
125
            for(unsigned int c=0; c<pointCloudPCL->width; c++){
126
                pcl::PointXYZRGB p = pointCloudPCL->at(c, r);
126
                pcl::PointXYZRGB p = pointCloudPCL->at(c, r);
127
                if(p.x == p.x)
127
                if(p.x == p.x)
128
                    s << p.x << " " << p.y << " " << p.z << "\r\n";
128
                    s << p.x << " " << p.y << " " << p.z << "\r\n";
129
            }
129
            }
130
        }
130
        }
131
        std::flush(s);
131
        std::flush(s);
132
        s.close();
132
        s.close();
133
    }
133
    }
134
 
134
 
135
}
135
}
136
 
136
 
137
void SMPointCloudWidget::saveScreenShot(){
137
void SMPointCloudWidget::saveScreenShot(){
138
 
138
 
139
    vtkWindowToImageFilter* filter = vtkWindowToImageFilter::New();
139
    vtkWindowToImageFilter* filter = vtkWindowToImageFilter::New();
140
    //filter->SetInput(visualizer->getRenderWindow());
140
    //filter->SetInput(visualizer->getRenderWindow());
141
    filter->Modified();
141
    filter->Modified();
142
 
142
 
143
    QString fileName = QFileDialog::getSaveFileName(this, "Save Screen Shot", QString(), "*.png");
143
    QString fileName = QFileDialog::getSaveFileName(this, "Save Screen Shot", QString(), "*.png");
144
    QFileInfo info(fileName);
144
    QFileInfo info(fileName);
145
    QString type = info.suffix();
145
    QString type = info.suffix();
146
    if(type == "")
146
    if(type == "")
147
        fileName.append(".png");
147
        fileName.append(".png");
148
 
148
 
149
    vtkPNGWriter* writer = vtkPNGWriter::New();
149
    vtkPNGWriter* writer = vtkPNGWriter::New();
150
    writer->SetInput(filter->GetOutput());
150
    writer->SetInput(filter->GetOutput());
151
    writer->SetFileName(qPrintable(fileName));
151
    writer->SetFileName(qPrintable(fileName));
152
    writer->Write();
152
    writer->Write();
153
    writer->Delete();
153
    writer->Delete();
154
}
154
}
155
 
155
 
156
void SMPointCloudWidget::updateCalibrationParameters(){
156
void SMPointCloudWidget::updateCalibrationParameters(){
157
 
157
 
158
    QSettings settings;
158
    QSettings settings;
159
    SMCalibrationParameters calibration = settings.value("calibration/parameters").value<SMCalibrationParameters>();
159
    SMCalibrationParameters calibration = settings.value("calibration/parameters").value<SMCalibrationParameters>();
160
 
160
 
161
    // camera 0 coordinate system
161
    // camera 0 coordinate system
162
    visualizer->removeCoordinateSystem(0);
162
    visualizer->removeCoordinateSystem(0);
163
    visualizer->addCoordinateSystem(100, 0);
163
    visualizer->addCoordinateSystem(100, 0);
164
 
164
 
165
    // camera 1 coordinate system
165
    // camera 1 coordinate system
166
    cv::Mat Transform1CV(3, 4, CV_32F);
166
    cv::Mat Transform1CV(3, 4, CV_32F);
167
    cv::Mat(calibration.R1).copyTo(Transform1CV.colRange(0, 3));
167
    cv::Mat(calibration.R1).copyTo(Transform1CV.colRange(0, 3));
168
    cv::Mat(calibration.T1).copyTo(Transform1CV.col(3));
168
    cv::Mat(calibration.T1).copyTo(Transform1CV.col(3));
169
    Eigen::Affine3f Transform1;
169
    Eigen::Affine3f Transform1;
170
    cv::cv2eigen(Transform1CV, Transform1.matrix());
170
    cv::cv2eigen(Transform1CV, Transform1.matrix());
171
 
171
 
172
    visualizer->addCoordinateSystem(100, Transform1.inverse());
172
    visualizer->addCoordinateSystem(100, Transform1.inverse());
173
 
173
 
174
    // rotation axis coordinate system
174
    // rotation axis coordinate system
175
//    cv::Mat TransformRCV(3, 4, CV_32F);
175
//    cv::Mat TransformRCV(3, 4, CV_32F);
176
//    cv::Mat(calibration.Rr).copyTo(TransformRCV.colRange(0, 3));
176
//    cv::Mat(calibration.Rr).copyTo(TransformRCV.colRange(0, 3));
177
//    cv::Mat(calibration.Tr).copyTo(TransformRCV.col(3));
177
//    cv::Mat(calibration.Tr).copyTo(TransformRCV.col(3));
178
//    Eigen::Affine3f TransformR;
178
//    Eigen::Affine3f TransformR;
179
//    cv::cv2eigen(TransformRCV, TransformR.matrix());
179
//    cv::cv2eigen(TransformRCV, TransformR.matrix());
180
 
180
 
181
//    visualizer->addCoordinateSystem(100, TransformR);
181
//    visualizer->addCoordinateSystem(100, TransformR);
182
 
182
 
183
    // rotation axis at (0,0,0) pointing (0,1,0) in rotation stage frame
183
    // rotation axis at (0,0,0) pointing (0,1,0) in rotation stage frame
184
    cv::Vec3f O(0.0, -100.0, 0.0);
184
    cv::Vec3f O(0.0, -100.0, 0.0);
185
    cv::Vec3f v(0.0, 300.0, 0.0);
185
    cv::Vec3f v(0.0, 300.0, 0.0);
186
 
186
 
187
    // determine coefficients in camera 0 frame
187
    // determine coefficients in camera 0 frame
188
    O = calibration.Rr.t()*O + -calibration.Rr.t()*calibration.Tr;
188
    O = calibration.Rr.t()*O + -calibration.Rr.t()*calibration.Tr;
189
    v = calibration.Rr.t()*v + -calibration.Rr.t()*calibration.Tr - O;
189
    v = calibration.Rr.t()*v + -calibration.Rr.t()*calibration.Tr - O;
190
 
190
 
191
    pcl::ModelCoefficients lineCoefficients;
191
    pcl::ModelCoefficients lineCoefficients;
192
    lineCoefficients.values.resize(6);
192
    lineCoefficients.values.resize(6);
193
    lineCoefficients.values[0] = O[0];
193
    lineCoefficients.values[0] = O[0];
194
    lineCoefficients.values[1] = O[1];
194
    lineCoefficients.values[1] = O[1];
195
    lineCoefficients.values[2] = O[2];
195
    lineCoefficients.values[2] = O[2];
196
    lineCoefficients.values[3] = v[0];
196
    lineCoefficients.values[3] = v[0];
197
    lineCoefficients.values[4] = v[1];
197
    lineCoefficients.values[4] = v[1];
198
    lineCoefficients.values[5] = v[2];
198
    lineCoefficients.values[5] = v[2];
199
    visualizer->removeShape("line");
199
    visualizer->removeShape("line");
200
    visualizer->addLine(lineCoefficients);
200
    visualizer->addLine(lineCoefficients);
201
 
201
 
202
 
202
 
203
}
203
}
204
 
204
 
205
SMPointCloudWidget::~SMPointCloudWidget(){
205
SMPointCloudWidget::~SMPointCloudWidget(){
206
 
206
 
207
    //delete visualizer;
207
    //delete visualizer;
208
 
208
 
209
}
209
}
210
 
210