Subversion Repositories seema-scanner

Rev

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

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