Code Planet

为了发现更大的世界


  • 首页

  • 关于

  • 标签

  • 分类

  • 归档

hexo技巧

发表于 2019-03-05 | 更新于 2019-03-22 | 分类于 misc

1.多终端同步
2.markdown公式渲染

参考:
[1].https://cloud.tencent.com/developer/article/1046404
[2].https://www.jianshu.com/p/7ab21c7f0674

轮廓追踪算法

发表于 2019-02-28 | 分类于 cpp

1. Contour Tracing Algorithms

  • Square Tracing Algorithm
  • Moore-Neighbor Tracing
  • Radial Sweep
  • Theo Pavlidis’ Algorithm

2. Square Tracing Algorithm

  • 扫描得到起始点
  • 当前为黑色点,左转
  • 当前点位白色点,右转
  • 循环直到回到起始点

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    注意:左转和右转是针对当前循环的位置
    -------------
    | | 1 | |
    -------------
    | 2 | x | 0 |
    -------------
    | | 3 | |
    -------------

    如果当前点位置为x,前向点位置为0时:
    left = 3; right = 1

    如果当前点位置为x,前向点位置为3时:
    left = 2; right = 0
  • 无法追踪斜线,改进:终止条件改为访问起始点多次

  • 通过4邻域而非8领域追踪边界
阅读全文 »

Catch2单元测试框架

发表于 2019-02-28 | 分类于 cpp

简介

Catch2是一个header-only测试框架。

使用说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#define CATCH_CONFIG_MAIN  // 宏定义指明main()函数
#include "catch.hpp"

// 测试用例
TEST_CASE( "vectors can be sized and resized", "[vector]" )
{
std::vector<int> v( 5 );

REQUIRE( v.size() == 5 );
REQUIRE( v.capacity() >= 5 );
// 执行每一个SECTION,都会重新开始执行
SECTION( "resizing bigger changes size and capacity" )
{
v.resize( 10 );

REQUIRE( v.size() == 10 );
REQUIRE( v.capacity() >= 10 );
}
// 执行下面的SECTION时,v.size()=5
SECTION( "resizing smaller changes size but not capacity" )
{
v.resize( 0 );

REQUIRE( v.size() == 0 );
REQUIRE( v.capacity() >= 5 );
}
SECTION( "reserving bigger changes capacity but not size" )
{
v.reserve( 10 );

REQUIRE( v.size() == 5 );
REQUIRE( v.capacity() >= 10 );
}
SECTION( "reserving smaller does not change size or capacity" )
{
v.reserve( 0 );

REQUIRE( v.size() == 5 );
REQUIRE( v.capacity() >= 5 );
}
}
阅读全文 »

vtk多个窗口交互问题

发表于 2019-02-28 | 分类于 cpp

vtk多个窗口进行交互,每个窗口需要有单独的vtkRenderWindowInteractor。
在render的时候,执行vtkRenderWindowInteractor::Start之后,主线程会被阻塞。
所以以下方式进行渲染是错误的。

1
2
3
4
5
6
7
8
9
10
void Render(int i)
{
....
interactor->Start();
}

for(int i=0;i<N;i++)
{
Render(i);
}

阅读全文 »

vtk录制avi解决方案

发表于 2019-02-28 | 分类于 cpp

vtk中使用vtkWindowToImageFilter和vtkAVIWriter来实现render window内容的录制。但是在录制过程中需要自行Modify vtkWindowToImageFilter数据以及vtkAVIWriter的writer方法。
自然而然的想法是使用Timer来定时执行。通过指定帧率,可以计算出采样帧的时间间隔。
方案一:
对interactor创建timer callbak,在callback中写render window帧。此种方案有个问题,当鼠标进行交互时,会block timer的callback。
方案二:
对render window创建render event的callback,在callback中计时,超出interval时间,则进行写帧。

二值图像距离图生成算法

发表于 2019-02-28 | 分类于 cpp

算法主要步骤

初始化

  • 将图像分为内部点和非内部点(内部点本身为1且4领域皆为1)
  • 初始化距离图像,内部点值为INF,非内部点为0

更新距离

这里写图片描述

  • 由上到下,由左至右迭代计算,伪代码如下:

    1
    2
    3
    4
    5
    6
    7
    def forward_conv(image):
    for i in range(hight):
    for j in range(width):
    for pixel in Neighbour:
    dist = template[pixel]+dist[pixel]
    find the minimun dist
    dist[i][j] = min(dist[i][j],dist)
  • 后向更新距离图

阅读全文 »

Qt部署qwindows.dll错误问题

发表于 2019-02-28 | 分类于 cpp

问题描述

1
This application failed to start because it could not find or load the Qt platform plugin "windows".

解决

1.使用depends.exe查看添加必要的dll
2.添加这两个dll(depends程序并未指明)
libGLESv2.dll
libEGL.dll
3.添加icudt.dll或者qt目录下ic*.dll的三个dll

参考

[1] https://stackoverflow.com/questions/18368826/deploying-qt-c-application-from-visual-studio-qwindows-dll-error/18377863#18377863

invalid-comparator问题

发表于 2019-02-28 | 分类于 cpp

std::set使用自定义key时,需要指定comparator,具体做法如下:

1
2
3
4
5
6
7
8
9
10
struct cmpByStringLength 
{
bool operator()(const std::string& a, const std::string& b) const
{
return a.length() < b.length();
}
};

// ...
std::map<std::string, std::string, cmpByStringLength> myMap;

使用时,正常插入没问题,查找时遇到invalid comparator问题。
原因是comparator不符合规定。

comparator需要时strict weak ordering,需要注意的是,comparator(x,x)必须返回false。

参考:
[1].https://stackoverflow.com/questions/9648100/using-own-comparator-operator-for-map-giving-error-in-case-if-key-not-found
[2].https://stackoverflow.com/questions/32263560/errorinvalid-comparator-when-sorting-using-custom-comparison-function

vtkPolydata中取点的坑

发表于 2019-02-28 | 分类于 cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
for (int i = 0; i < lines->GetNumberOfCells(); i++)
{
// 获取一条centerline
vtkIdType nbCellPoints;
vtkIdType* points;
lines->GetNextCell(nbCellPoints, points);

// 迭代该条centerline,获取小线段
for (int j = 0; j < nbCellPoints-1; j++)
{
vtkIdType pid1 = points[j];
vtkIdType pid2 = points[j + 1];

double* p1 = polydata->GetPoints()->GetPoint(pid1);
double* p2 = polydata->GetPoints()->GetPoint(pid1);

cout << "P1 : " << pid1 << " " << p1[0] / spacing[0] << "," << p1[1] / spacing[1] << "," << p1[2] / spacing[2] << endl;
cout << "P2 : " << pid2 << " " << p2[0] / spacing[0] << "," << p2[1] / spacing[1] << "," << p2[2] / spacing[2] << endl;
}
}

输出结果:

1
2
3
4
5
6
7
8
9
10
11
12
P1 : 131 111,177,121
P2 : 130 111,177,121
P1 : 130 112,178,120
P2 : 129 112,178,120
P1 : 129 112,178,119
P2 : 128 112,178,119
P1 : 128 112,177,118
P2 : 127 112,177,118
P1 : 127 112,176,117
P2 : 126 112,176,117
P1 : 126 111,175,116
...

发现每次输出P1跟P2坐标相同,好久没发现问题所在。追踪到源码,发现这么一段warning,细想一下,这样设计业很好理解。

1
2
3
4
5
6
7
8
9
10
11
// Description:
// Return a pointer to a double point x[3] for a specific id.
// WARNING: Just don't use this error-prone method, the returned pointer
// and its values are only valid as long as another method invocation is not
// performed. Prefer GetPoint() with the return value in argument.
double *GetPoint(vtkIdType id) { return this->Data->GetTuple(id); }

// Description:
// Copy point components into user provided array v[3] for specified
// id.
void GetPoint(vtkIdType id, double x[3]) { this->Data->GetTuple(id,x); }

更新程序使用

1
2
3
4
double p1[3];
double p2[3];
polydata->GetPoints()->GetPoint(pid1, p1);
polydata->GetPoints()->GetPoint(pid2, p2);

目标达成。

ITK spacing的问题

发表于 2019-02-28 | 分类于 cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
double spacing[3];
spacing[0] = reader->GetOutput()->GetSpacing()[0];
spacing[1] = reader->GetOutput()->GetSpacing()[1];
spacing[2] = reader->GetOutput()->GetSpacing()[2];
int dims[3];
dims[0] = reader->GetOutput()->GetBufferedRegion().GetSize()[0];
dims[1] = reader->GetOutput()->GetBufferedRegion().GetSize()[1];
dims[2] = reader->GetOutput()->GetBufferedRegion().GetSize()[2];


typedef itk::JoinSeriesImageFilter<Image2DType, InputImageType> JoinSeriesFilterType;
JoinSeriesFilterType::Pointer joinFilter = JoinSeriesFilterType::New();
for (int i = 0; i < dims[2]; i++)
{
// 提取
Image2DType::Pointer slice = GetSlice(i, output);

joinFilter->SetInput(i, slice);
}
joinFilter->Update();

以上代码会导致reader->GetOutput()和joinFilter->GetOutput()数据的spacing信息不一致。

JoinSeriesImageFilter会将z轴方向的spacing固定为1。

123…12
Lu Xiaohua

Lu Xiaohua

116 日志
33 分类
86 标签
GitHub E-Mail
© 2019 Lu Xiaohua
由 Hexo 强力驱动 v3.8.0
|
主题 – NexT.Muse v7.0.0