在上一篇博客中我们已经实现了在给定的一点实现一个给定长宽的细长方柱,接下来我们只要将我们的二位码图片读入然后遍历,如果是白则在该处生成一个立柱。(在我的图片中白色的话就生成方柱,请注意这张图片的白边因为背景问题没法看清)。
这一步用的opencv库中的imread函数。需要注意的是,再将图片读入数组时,我们应当将imread函数的第二个参数设置为CV_LOAD_IMAGE_GRAYSCALE,这样才能保证将图片以单通道而非三通道的方式读入。否则可能会出现生成的模型列是正常的三倍的情况。
效果图:
现附上由上次的代码增添而成的源代码,运行时只需将一张连接好的二维码图片与cpp文件放在一起然后运行即可。
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;
struct p
{
int x;
int y;
int z;
p() {}
p(int xx, int yy, int zz)
:x(xx), y(yy), z(zz) {}
friend p operator + (const p &a, const p &b);
friend p operator - (const p &a, const p &b);
friend ostream& operator << (ostream& output, const p &a)
{
output << a.x << ' ' << a.y << ' ' << a.z;
return output;
}
friend p getf(const p &a, const p &b, const p &c);
p operator * (int a)
{
return p(x*a, y*a, z*a);
}
};
p operator + (const p &a, const p &b)
{
return p(a.x + b.x, a.y + b.y, a.z + b.z);
}
p operator - (const p &a, const p &b)
{
return p(a.x - b.x, a.y - b.y, a.z - b.z);
}
p getf(const p &a, const p &b, const p &c)
{
p ba = a - b;
p bc = c - b;
return p(bc.y*ba.z - ba.y*bc.z, bc.z*ba.x - bc.x*ba.z, bc.x*ba.y - ba.x*bc.y);//bc X ba
}
int getz(int a)
{
return a>0 ? a : (-a);
}
void inat(const p &a, int c, int k, int judge, ostream& output)//先加长(竖着、向下)
{
if (getz(judge) == 1)
{
output << " facet normal " << getf(a, p(a.x, a.y, a.z - c), p(a.x, a.y + k, a.z))*judge << endl;
output << " outer loop" << endl;
output << " vertex " << a << endl;
output << " vertex " << p(a.x, a.y, a.z - c) << endl;
output << " vertex " << p(a.x, a.y + k, a.z) << endl;
output << " endloop" << endl;
output << " endfacet" << endl;
output << " facet normal " << getf(p(a.x, a.y + k, a.z), p(a.x, a.y, a.z - c), p(a.x, a.y + k, a.z - c))*judge << endl;
output << " outer loop" << endl;
output << " vertex " << p(a.x, a.y + k, a.z) << endl;
output << " vertex " << p(a.x, a.y, a.z - c) << endl;
output << " vertex " << p(a.x, a.y + k, a.z - c) << endl;
output << " endloop" << endl;
output << " endfacet" << endl;
}
else if (getz(judge) == 2)
{
output << " facet normal " << getf(a, p(a.x, a.y, a.z - c), p(a.x + k, a.y, a.z))*(judge / 2) << endl;
output << " outer loop" << endl;
output << " vertex " << a << endl;
output << " vertex " << p(a.x, a.y, a.z - c) << endl;
output << " vertex " << p(a.x + k, a.y, a.z) << endl;
output << " endloop" << endl;
output << " endfacet" << endl;
output << " facet normal " << getf(p(a.x + k, a.y, a.z), p(a.x, a.y, a.z - c), p(a.x + k, a.y, a.z - c))*(judge / 2) << endl;
output << " outer loop" << endl;
output << " vertex " << p(a.x + k, a.y, a.z) << endl;
output << " vertex " << p(a.x, a.y, a.z - c) << endl;
output << " vertex " << p(a.x + k, a.y, a.z - c) << endl;
output << " endloop" << endl;
output << " endfacet" << endl;
}
else if (getz(judge) == 3)
{
output << " facet normal " << getf(a, p(a.x + c, a.y, a.z), p(a.x, a.y + k, a.z))*(judge / 3) << endl;
output << " outer loop" << endl;
output << " vertex " << a << endl;
output << " vertex " << p(a.x + c, a.y, a.z) << endl;
output << " vertex " << p(a.x, a.y + k, a.z) << endl;
output << " endloop" << endl;
output << " endfacet" << endl;
output << " facet normal " << getf(p(a.x, a.y + k, a.z), p(a.x + c, a.y, a.z), p(a.x + c, a.y + k, a.z))*(judge / 3) << endl;
output << " outer loop" << endl;
output << " vertex " << p(a.x, a.y + k, a.z) << endl;
output << " vertex " << p(a.x + c, a.y, a.z) << endl;
output << " vertex " << p(a.x + c, a.y + k, a.z) << endl;
output << " endloop" << endl;
output << " endfacet" << endl;
}
else return;
}
void writein(const p &a, int c, int k, ostream& output)
{
inat(a, c, k, 2, output);
inat(a, k, k, 3, output);
inat(a, c, k, 1, output);
inat(p(a.x, a.y, a.z - c), k, k, -3, output);
inat(p(a.x + k, a.y, a.z), c, k, -1, output);
inat(p(a.x, a.y + k, a.z), c, k, -2, output);
}
int main()
{
ofstream output("test.stl", ios::out);
if (!output)
{
cerr << "open error!" << endl;
exit(1);
}
output << "solid aname" << endl;
Mat image = imread("C:\\Users\\89299\\Desktop\\ANYWAY\\WEB\\2\\the2\\3.png", CV_LOAD_IMAGE_GRAYSCALE);
for (int k = 0;k<image.rows;k++)
{
uchar* data = image.ptr<uchar>(k);
for (int i = 0;i<image.cols;i++)
{
if (data[i]!=0)
writein(p(k, i, 0), 10, 1, output);
}
}
output << "endsolid aname";
output.close();
return 0;
}