1 | initial version |
so, opencv's loadPLYSimple() won't work for your data. you could try to adapt the code from here to fit your specific needs, like:
#include <opencv2/opencv.hpp>
using namespace cv;
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
static std::vector<std::string> split(const std::string &text, char sep) {
std::vector<std::string> tokens;
std::size_t start = 0, end = 0;
while ((end = text.find(sep, start)) != std::string::npos) {
tokens.push_back(text.substr(start, end - start));
start = end + 1;
}
tokens.push_back(text.substr(start));
return tokens;
}
bool loadPLY(const char* fileName, std::vector<Point3f> &points, std::vector<Vec3b> &colors)
{
int numVertices = 0;
std::ifstream ifs(fileName);
if (!ifs.is_open())
CV_Error(Error::StsError, String("Error opening input file: ") + String(fileName) + "\n");
std::string str;
while (str.substr(0, 10) != "end_header")
{
std::vector<std::string> tokens = split(str,' ');
if (tokens.size() == 3)
{
if (tokens[0] == "element" && tokens[1] == "vertex")
{
numVertices = atoi(tokens[2].c_str());
}
}
else if (tokens.size() > 1 && tokens[0] == "format" && tokens[1] != "ascii")
CV_Error(Error::StsBadArg, String("Cannot read file, only ascii ply format is currently supported..."));
std::getline(ifs, str);
}
for (int i = 0; i < numVertices; i++)
{
float x,y,z,nx,ny,nz,curvature; // read *all* in, but only keep points & colors
int r,g,b;
ifs >> x >> y >> z >> r >> g >> b >> nx >> ny >> nz >> curvature;
points.push_back(Point3f(x,y,z));
colors.push_back(Vec3b(b,g,r));
}
return true;
}
int main() {
std::vector<Point3f> points;
std::vector<Vec3b> colors;
loadPLY("cloud.ply", points, colors);
cout << points[0] << points[1] << endl; // go check, if this is correct !
cout << colors[0] << colors[1] << endl;
return 0;
}
then, you could try to render an image from it:
int W = draw_img.cols;
int H = draw_img.rows;
float focal = 5; // e.g from the ply !
Point p(focal * points[i].x / points[i].z, focal * points[i].y / points[i].z); // project to 2d
p.x = p.x * W/2 + W/2; // scale/offset to img coords
p.y = p.y * H/2 + H/2;
cv::circle(draw_img, p, 3, colors[i], -1); // filled circle of some size
2 | No.2 Revision |
so, opencv's loadPLYSimple() won't work for your data. you could try to adapt the code from here to fit your specific needs, like:
#include <opencv2/opencv.hpp>
using namespace cv;
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
static std::vector<std::string> split(const std::string &text, char sep) {
std::vector<std::string> tokens;
std::size_t start = 0, end = 0;
while ((end = text.find(sep, start)) != std::string::npos) {
tokens.push_back(text.substr(start, end - start));
start = end + 1;
}
tokens.push_back(text.substr(start));
return tokens;
}
bool loadPLY(const char* fileName, std::vector<Point3f> &points, std::vector<Vec3b> &colors)
{
int numVertices = 0;
std::ifstream ifs(fileName);
if (!ifs.is_open())
CV_Error(Error::StsError, String("Error opening input file: ") + String(fileName) + "\n");
std::string str;
while (str.substr(0, 10) != "end_header")
{
std::vector<std::string> tokens = split(str,' ');
if (tokens.size() == 3)
{
if (tokens[0] == "element" && tokens[1] == "vertex")
{
numVertices = atoi(tokens[2].c_str());
}
}
else if (tokens.size() > 1 && tokens[0] == "format" && tokens[1] != "ascii")
CV_Error(Error::StsBadArg, String("Cannot read file, only ascii ply format is currently supported..."));
std::getline(ifs, str);
}
for (int i = 0; i < numVertices; i++)
{
float x,y,z,nx,ny,nz,curvature; // read *all* in, but only keep points & colors
int r,g,b;
ifs >> x >> y >> z >> r >> g >> b >> nx >> ny >> nz >> curvature;
points.push_back(Point3f(x,y,z));
colors.push_back(Vec3b(b,g,r));
}
return true;
}
int main() {
std::vector<Point3f> points;
std::vector<Vec3b> colors;
loadPLY("cloud.ply", points, colors);
cout << points[0] << points[1] << endl; // go check, if this is correct !
cout << colors[0] << colors[1] << endl;
return 0;
}
then, you could try to render an image from it:
int W = draw_img.cols;
int H = draw_img.rows;
float focal = 5; // e.g from the ply !
Point p(focal * points[i].x / points[i].z, focal * points[i].y / points[i].z); // project to 2d
p.x = p.x * W/2 + W/2; // scale/offset to img coords
p.y = p.y * H/2 + H/2;
cv::circle(draw_img, p, 3, colors[i], -1); // filled circle of some size
3 | No.3 Revision |
so, opencv's loadPLYSimple() won't work for your data. you could try to adapt the code from here to fit your specific needs, like:
#include <opencv2/opencv.hpp>
using namespace cv;
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
static std::vector<std::string> split(const std::string &text, char sep) {
std::vector<std::string> tokens;
std::size_t start = 0, end = 0;
while ((end = text.find(sep, start)) != std::string::npos) {
tokens.push_back(text.substr(start, end - start));
start = end + 1;
}
tokens.push_back(text.substr(start));
return tokens;
}
bool loadPLY(const char* fileName, std::vector<Point3f> &points, std::vector<Vec3b> &colors)
{
int numVertices = 0;
std::ifstream ifs(fileName);
if (!ifs.is_open())
CV_Error(Error::StsError, String("Error opening input file: ") + String(fileName) + "\n");
std::string str;
while (str.substr(0, 10) != "end_header")
{
std::vector<std::string> tokens = split(str,' ');
if (tokens.size() == 3)
{
if (tokens[0] == "element" && tokens[1] == "vertex")
{
numVertices = atoi(tokens[2].c_str());
}
}
else if (tokens.size() > 1 && tokens[0] == "format" && tokens[1] != "ascii")
CV_Error(Error::StsBadArg, String("Cannot read file, only ascii ply format is currently supported..."));
std::getline(ifs, str);
}
for (int i = 0; i < numVertices; i++)
{
float x,y,z,nx,ny,nz,curvature; // read *all* in, but only keep points & colors
int r,g,b;
ifs >> x >> y >> z >> r >> g >> b >> nx >> ny >> nz >> curvature;
points.push_back(Point3f(x,y,z));
colors.push_back(Vec3b(b,g,r));
}
return true;
}
int main() {
std::vector<Point3f> points;
std::vector<Vec3b> colors;
loadPLY("cloud.ply", points, colors);
cout << points[0] << points[1] << endl; // go check, if this is correct !
cout << colors[0] << colors[1] << endl;
return 0;
}
then, you could try to render an image from it:
int W = draw_img.cols;
int H = draw_img.rows;
float focal = 5; // e.g from the ply !
// project to 2d
Point p(focal * points[i].x / points[i].z, focal * points[i].y / points[i].z); // project scale/offset to 2d
img coords
p.x = p.x * W/2 + W/2; // scale/offset to img coords
p.y = p.y * H/2 + H/2;
cv::circle(draw_img, p, 3, colors[i], -1); // filled circle of some size
cv::circle(draw_img, p, 3, colors[i], -1);