误差可视化小结

误差可视化小结

问题描述

在做水印工作的时候,需要衡量原模型与水印模型之间的误差。为了更加直观的看出误差的大小,可以将误差进行可视化。下图是可视化误差的一个例子,其中左边的模型为原始模型A,右边第二行的模型是某个算法计算出的原模型的近似模型B,右边第三行的模型是一个有色的模型,通过颜色表示出模型A、B之间的误差,颜色条显示不同颜色与误差大小的关系。

在水印工作中,也许要对原始模型和水印模型的误差进行衡量,误差可简单计算为两个模型上对应点之间的欧氏距离。在计算误差之前,首先要确保两个模型已经对齐(最简单的处理可以将两个模型的中点放置在一起),代码如下:

//将两个模型的中心移到一起
    //将原始中心读取出来
    double *RCenter = new double[6];

    char center_name[100];
    ifstream centerfile;
    sprintf(center_name, "D:\\code\\GeometryProcessing-1\\Txt\\Offset\\Center.txt");
    centerfile.open(center_name,ios_base::in );
    if (centerfile)
    {
        // read into memory
        centerfile.seekg (0, centerfile.end);
        int length = centerfile.tellg();
        centerfile.seekg (0, centerfile.beg);

        char *buffer = new char[length];
        centerfile.read(buffer, length);
        centerfile.close();

        // parse into array
        std::istringstream iss(buffer);
        int i = 0;
        while ( i < 6)
        {
            iss >> RCenter[i++];
        }
        delete [] buffer;
        // print or use it.
    }
    centerfile.close();

    double currEntityCenter[3]; //** store the center of current entity‘s bounding box *//
    double firstMeshCenter[3];
    entity_meshA->get_bb_center(firstMeshCenter);

    for (int i = 0; i<2 ; ++i)
    {
        PGMeshEntity* meshEntity = (PGMeshEntity*)meshList[i];
        Mesh* mesh = meshEntity->get_mesh();
        Mesh::ConstVertexIter cvIt = mesh->vertices_begin();
        Mesh::ConstVertexIter cvIt_end = mesh->vertices_end();
        meshEntity->get_bb_center(currEntityCenter);

        double offset[3] = {0,0,0};
        offset[0] =currEntityCenter[0] - RCenter[0];
        offset[1]= currEntityCenter[1] - RCenter[1];
        offset[2]= currEntityCenter[2] - RCenter[2];

        RCenter+=3;
        //** update the leftmost point for the next entity *//
        //** adjust the position of all points of current entity *//
        for ( ; cvIt != cvIt_end; ++cvIt )
        {
            OpenMesh::Vec3d tmpPoint = mesh->point(cvIt);
            tmpPoint[0] -= offset[0];
            tmpPoint[1] -= offset[1];
            tmpPoint[2] -= offset[2];
            mesh->set_point( cvIt.handle(), tmpPoint ); //** modify core mesh D.S. embedded in PGMeshEntity D.S., updating the corresponding render in PGMeshEntity D.S. is needed *//
        }
        //** update the center point of PGMeshEntity instance bounding box *//
        meshEntity->cal_bounding_box();
        meshEntity->update_rendering();
        mesh->update_face_normals();
    }

误差计算

上文中已经说过,误差可以简单计算为两个模型对应点之间的欧氏距离。可视化误差实际上就是给模型B(或A)着色,用颜色来表示误差。具体做法是,声明一个向量ErrorB,用来存放模型B的每个点距离模型A的对应点的距离,然后设置一个colorMap,根据距离,选取colorMap中的颜色,作为B中点的颜色,最后绘制出来。误差计算代码如下:

void SequenceWaterMark::error_Map()
{
    BaseEntity * entity_meshA;
    BaseEntity * entity_meshB;
    entity_meshA = meshList[0];
    entity_meshB = meshList[1];

    PolygonMesh::Mesh * _meshA = ((PolygonMesh::PGMeshEntity *) entity_meshA)->get_mesh();
    PolygonMesh::Mesh * _meshB = ((PolygonMesh::PGMeshEntity *) entity_meshB)->get_mesh();

    //可视化的量
    vector<double> ErrorB;

    //用来存放每个点的三维坐标
    VectorXd ACoor(3);
    VectorXd BCoor(3);

    int ia = 0;
    for ( auto va_it = _meshA->vertices_begin();va_it != _meshA->vertices_end();++va_it, ia++ )
    {
        auto t_p = _meshA->point(va_it.handle());

        ACoor[0] = t_p[0];
        ACoor[1] = t_p[1];
        ACoor[2] = t_p[2];

        int ib = 0;
        double dis = 0.0;
        for ( auto vb_it = _meshB->vertices_begin();vb_it != _meshB->vertices_end();++vb_it, ib++  )
        {
            auto t_pb = _meshB->point(vb_it.handle());

            if ( ia == ib )
            {
                BCoor[0] = t_pb[0];
                BCoor[1] = t_pb[1];
                BCoor[2] = t_pb[2];

                dis = (ACoor - BCoor).norm();
                ErrorB.push_back( dis );
                break;
            }

        }
    }

    vector<double>::iterator max_it;
    max_it = max_element( ErrorB.begin(), ErrorB.end() );
    double maxD = *max_it;

    vector<double>::iterator min_it;
    min_it = min_element( ErrorB.begin(), ErrorB.end() );
    double minD = *min_it;

    Mesh::Color CL;
    int v = 0;
    for (auto vit = _meshB->vertices_begin();vit != _meshB->vertices_end();++vit, v++)
    {
        ErrorB[v] = 100.0f * ( ErrorB[v] - minD )/( maxD - minD );
        double clampV = ErrorB[v]< 99.0f ? ErrorB[v] : 99.0f;
        clampV = clampV > 0.0f ? clampV : 0.0f;
        int colorPercent = (int)clampV;
        unsigned char* colorPtr = ErrorColorMap + colorPercent * 3;
        CL.values_[0] = colorPtr[0];
        CL.values_[1] = colorPtr[1];
        CL.values_[2] = colorPtr[2];
        _meshB->set_color(vit.handle(), CL);//动态显示
    }
    _meshB->update_face_normals();
    entity_meshB->update_rendering();

最后为了便于查看,将第二个模型的位置稍微偏移一下

    //为了显示方便,将第二帧偏移一下
    PGMeshEntity* meshEntity = (PGMeshEntity*)meshList[1];
    Mesh* mesh = meshEntity->get_mesh();
    Mesh::ConstVertexIter cvIt = mesh->vertices_begin();
    Mesh::ConstVertexIter cvIt_end = mesh->vertices_end();
    meshEntity->get_bb_center(currEntityCenter);

    double radius = meshEntity->get_bb_radius();

    double offset[3] = {0,0,0};
    offset[0] =currEntityCenter[0] + radius;
    offset[1]= currEntityCenter[1];
    offset[2]= currEntityCenter[2];

    //** update the leftmost point for the next entity *//
    //** adjust the position of all points of current entity *//
    for ( ; cvIt != cvIt_end; ++cvIt )
    {
        OpenMesh::Vec3d tmpPoint = mesh->point(cvIt);
        tmpPoint[0] += offset[0];
        tmpPoint[1] += offset[1];
        tmpPoint[2] += offset[2];
        mesh->set_point( cvIt.handle(), tmpPoint ); //** modify core mesh D.S. embedded in PGMeshEntity D.S., updating the corresponding render in PGMeshEntity D.S. is needed *//
    }
    //** update the center point of PGMeshEntity instance bounding box *//
    meshEntity->cal_bounding_box();
    meshEntity->update_rendering();
    mesh->update_face_normals();
}

我们用一个简单的模型来验证上述代码

下图为输入的两个模型,左边为模型A,右边为模型B

下图为执行结果

用matlab绘制颜色条

现在已经得到了误差图,但是我们仍然不知道颜色与误差之间的关系,换句话说,只有上面的执行结果,我们并不了解深蓝色对应的误差到底是大还是小,因此需要将我们用来表示误差的颜色映射到一个颜色条上。

1.首先在matlab中输入一个矩阵MAP,表示要绘制的颜色条包含的RGB值

2.将MAP的每个值除以255,即AMAP = MAP/255

3.将AMAP传入COLORMAP函数中,即执行COLORMAP(AMAP)

4.绘制结果,即执行figure;colorbar;

结果如下:

时间: 2024-10-10 18:35:24

误差可视化小结的相关文章

最近做的项目的数据处理及可视化小结

使用pandas进行数据处理,主要有对某列数据事先进行提取,提取其中的identifier.用到的操作就是df['column'] = df['column'].apply(). 对数据处理完之后用到的就是matplotlib package,这时需要使用 command ipython --pylab打开matplotlib GUI后端,然后就可以使用绘图功能了. 这次处理主要是将数据处理成散点图和热图. 散点图(scatter map)是使用plt.scatter(x,y)来将点描绘到图上.

scikit-learn Adaboost类库使用小结

在集成学习之Adaboost算法原理小结中,我们对Adaboost的算法原理做了一个总结.这里我们就从实用的角度对scikit-learn中Adaboost类库的使用做一个小结,重点对调参的注意事项做一个总结. 1. Adaboost类库概述 scikit-learn中Adaboost类库比较直接,就是AdaBoostClassifier和AdaBoostRegressor两个,从名字就可以看出AdaBoostClassifier用于分类,AdaBoostRegressor用于回归. AdaBo

数据降维方法小结

原文:http://blog.csdn.net/yujianmin1990/article/details/48223001 数据的形式是多种多样的,维度也是各不相同的,当实际问题中遇到很高的维度时,如何给他降到较低的维度上?前文提到进行属性选择,当然这是一种很好的方法,这里另外提供一种从高维特征空间向低纬特征空间映射的思路. 数据降维的目的 数据降维,直观地好处是维度降低了,便于计算和可视化,其更深层次的意义在于有效信息的提取综合及无用信息的摈弃. 数据降维的方法 主要的方法是线性映射和非线性

【数据科学】Python数据可视化概述

注:很早之前就打算专门写一篇与Python数据可视化相关的博客,对一些基本概念和常用技巧做一个小结.今天终于有时间来完成这个计划了! 0. Python中常用的可视化工具 Python在数据科学中的地位,不仅仅是因为numpy, scipy, pandas, scikit-learn这些高效易用.接口统一的科学计算包,其强大的数据可视化工具也是重要组成部分.在Python中,使用的最多的数据可视化工具是matplotlib,除此之外还有很多其他可选的可视化工具包,主要包括以下几大类: matpl

逻辑回归原理小结

逻辑回归是一个分类算法,它可以处理二元分类以及多元分类.虽然它名字里面有"回归"两个字,却不是一个回归算法.那为什么有"回归"这个误导性的词呢?个人认为,虽然逻辑回归是分类模型,但是它的原理里面却残留着回归模型的影子,本文对逻辑回归原理做一个总结. 1. 从线性回归到逻辑回归 我们知道,线性回归的模型是求出输出特征向量Y和输入样本矩阵X之间的线性关系系数\(\theta\),满足\(\mathbf{Y = X\theta}\).此时我们的Y是连续的,所以是回归模型.

MogileFS学习小结

大纲: 一.关于MogileFS 二.常见分布式文件系统 三.MogileFS基本原理 四.MogileFS的实现 一.关于MogileFS 当下我们处在一个互联网飞速发展的信息社会,在海量并发连接的驱动下每天所产生的数据量必然以几何方式增长,随着信息连接方式日益多样化,数据存储的结构也随着发生了变化.在这样的压力下使得人们不得不重新审视大量数据的存储所带来的挑战,例如:数据采集.数据存储.数据搜索.数据共享.数据传输.数据分析.数据可视化等一系列问题. 传统存储在面对海量数据存储表现出的力不从

跟风舞烟学大数据可视化-Echarts从入门到上手实战

跟风舞烟学大数据可视化-Echarts从入门到上手实战 课程观看地址:http://www.xuetuwuyou.com/course/180 课程出自学途无忧网:http://www.xuetuwuyou.com 课程讲师:风舞烟 课时数:三个模块,共70课时   一.课程特色: 1.最全的Echarts课程讲解     70学时课时量,360度全方位,无死角的课程设计,让你通透Echarts可视化技术 2.最适合小白学员学习的课程,没有之一     只要你了解一点基本的Html,CSS,Ja

Tableau商业智能与可视化应用实战

跟风舞烟学数据分析 - Tableau商业智能与可视化应用实战 课程观看地址:http://www.xuetuwuyou.com/course/179 课程出自学途无忧网:http://www.xuetuwuyou.com 讲师:风舞烟老师 课时数:118课时 讲课模式:理论-->案例-->练习-->项目 小数据用Excel,大数据用Tableau!Tableau相比于专业的SPSS与SAS等 ,入门简单且功能强大;相比于各种品牌的大型IT平台,它易于实施与部署,通过拖.拉.点击同t步操

集成学习之Adaboost算法原理小结

在集成学习原理小结中,我们讲到了集成学习按照个体学习器之间是否存在依赖关系可以分为两类,第一个是个体学习器之间存在强依赖关系,另一类是个体学习器之间不存在强依赖关系.前者的代表算法就是是boosting系列算法.在boosting系列算法中, Adaboost是最著名的算法之一.Adaboost既可以用作分类,也可以用作回归.本文就对Adaboost算法做一个总结. 1. 回顾boosting算法的基本原理 在集成学习原理小结中,我们已经讲到了boosting算法系列的基本思想,如下图: 从图中