为什么会有这么一个操作呢?
是因为有些时候在三维上可能很难处理,但是在二维上却是很简单的事情,比如提取线性特征啊什么的,这些opencv都有很成熟的算法,直接调用就可以了(我这个憨坨坨刚开始准备直接在三维上面找直线)。这些代码呢是在很久之前写的,因为要放弃那个程序了(版本太低了,写的太差了),但是里面的代码我觉得还是可以记录一下。
首先是点云转为高程差影像(里面的ccPointCloud是cloudcompare带的),gridsize就是你的像素大小
typedef QVector
IplImage* Point2Img(ccPointCloud *theCloud, double gridSize,double dh, const char *str)
{
//将点云投影到XOY平面
CCVector3 _min,_max;
theCloud->getBoundingBox(_min,_max);
long npt = theCloud->size();
float len_X = _max.x - _min.x;
float len_Y = _max.y - _min.y;
int _col=((int)(len_X/gridSize)+1);
int _row=((int)(len_Y/gridSize)+1);
_col = ( _col * 8 + 31 ) / 32 * 4;//一定要有此步骤,不然图像是变形的
LinePtsList *childs = new LinePtsList[_row*_col];//存储格网的所有点
LinePtsList *child_b;
int xi,yi;
for (long i =0 ; i < npt ;i++)
{
const CCVector3 *pt= theCloud->getPoint(i);
xi = (int)((pt->x - _min[0])/gridSize);
yi = (int)((pt->y - _min[1])/gridSize);
child_b = childs+xi +yi * _col;//记录每个格网的所有点
CCVector3 pt_add = *pt;
child_b->push_back(pt_add);
}
char *lpData=new char[_row*_col];
for(int i=0;i<_col;i++)
for(int j=0;j<_row;j++)
{
child_b = childs+i +j * _col;
if(child_b->size()>0)
{
CCVector3 range1,range2;
getBBofCCVector3list(child_b,&range1,&range2);
if(range2.z-range1.z
else
lpData[i+(_row-j-1)*_col]=(range2.z)/_max.z*255;
}
else
lpData[i+(_row-j-1)*_col]=0;
}
//转成影像
CvSize _size;
_size.width=_col;
_size.height=_row;
IplImage* img = cvCreateImage( _size, IPL_DEPTH_8U, 1 );
img->imageData = lpData; //Arr为二维数组名
//文件保存
cvSaveImage( str, img );//显示图像
delete[]lpData;
delete[]childs;
return img;
}
高程差影像的结果就是这样子的哈,你看,是不是好明显的。
然后呢,是对影像进行处理了,可以通过hough变换提取直线,举个栗子哈,是用的opencv里面的
std::vector
{
//一个是待处理的图像
const char *str_process="D:\\Point2Img.jpg";
Point2Img(theCloud, gridSize,dh,str_process);
//一个是输出的结果图像
const char *str_out="D:\\Point2Img_out.jpg";
Point2Img(theCloud, gridSize,0,str_out);
cv::Mat image_process = cv::imread(str_process);
cv::Mat image_out = cv::imread(str_out);
cv::Mat contours;
cv::cvtColor(image_process, contours, cv::COLOR_BGR2GRAY);
cv::bitwise_not(contours, contours);
cv::Canny(image_process, contours, 100, 200);
cv::namedWindow("Canny");
cv::imshow("Canny",contours);
LineFinder finder;
// Set probabilistic Hough parameters
finder.setLineLengthAndGap(100/gridSize, 50/gridSize);//(100, 50)
finder.setMinVote(100/gridSize);
// Detect lines and draw them
std::vector
finder.drawDetectedLines(image_process, cv::Scalar(0, 0, 255));
//UVLines (image_process);
cv::namedWindow("Detected Lines with HoughP of image process");
cv::imshow("Detected Lines with HoughP of image process",image_process);
std::vector
cv::namedWindow("Detected Lines with HoughP of image out");
cv::imshow("Detected Lines with HoughP of image out",image_out);
imwrite("D:\\HoughLIneImg.jpg",image_out);//image_out
return lines_merge;//lines_merge
}
运行结果:
这个就比较简单了哈
应该后面应该不会再去做电力线相关的研究了,所以一些非核心的代码可以放出来,但是一些比较重要的代码还是要有知识产权意识的,欢迎大家多交流哈,反正我已经从一个坑跳进了另一个坑了
有人问get什么什么box函数,贴在下面
void getBBofCCVector3list(QVector
{
if (pts->size()< 0) return;
left_down->x = right_up->x = pts->front().x;
left_down->y = right_up->y = pts->front().y;
left_down->z = right_up->z = pts->front().z;
CCVector3 *pt_now = NULL;
for (int i = 0; i< pts->size(); i++)
{
pt_now = &pts->data()[(i)];
if (pt_now->x < left_down->x) left_down->x = pt_now->x;
if (pt_now->y < left_down->y) left_down->y = pt_now->y;
if (pt_now->z < left_down->z) left_down->z = pt_now->z;
if (pt_now->x > right_up->x) right_up->x = pt_now->x;
if (pt_now->y > right_up->y) right_up->y = pt_now->y;
if (pt_now->z > right_up->z) right_up->z = pt_now->z;
}
}