定义
链码用于表示由顺次连接的具有指定长度和方向的直线断组成的边界线。典型的表示方法是根据链 斜率不同、有4链码或8链码。每一段(相邻两顶点的连线)的方向是用数字编号方法进行编码。从起点开始,沿边界编码,至起点被重新碰到,结束一个对象的编码。
举例
4链码:0-0-3-3-3-2-2-2-1-1-0-1
疑问
(1)由于起点的不同,造成编码的不同怎么办?
方法:自然数最小归一化
解释:如果链码表达的边界是封闭的,故链码是可循环的,如何按位平移得到的链码都是一样的。但是如果选取的起点不同,那么得到的链码也会有所不同。这时候我们就要将它归一化。原理就是把我们得到的链码看成是一个自然数,将链码循环写下去,选取构成的自然数最小的那组链码。这个就是归一化链码。当然自然数最大归一化也可。
10103322
01033221 -- 构成的自然数最小 √
10332210
03322101
33221010
32210103
22101033
21010332
10103322 -- end
代码实现:(待完善)
/*
* if a > b return true, else return false;
*/
bool compare_chain(vector<int> a, vector<int> b)
{
if (a.size() != b.size()) {
return false;
}
if (a.size() == 0) {
return true;
}
for(int i = 0; i < a.size(); ++i) {
if (a[i] > b[i]) {
return true;
}
if (a[i] < b[i]) {
return false;
}
}
return false;
}
vector<int> chain_code_normalization(vector<int> src_chain)
{
int chine_len = src_chain.size();
vector<int> nor_chain;
vector<int> temp;
temp.insert(temp.begin(), src_chain.begin(), src_chain.end());
temp.insert(temp.begin() + chine_len, src_chain.begin(), src_chain.end());
vector<int> a,b;
a.assign(temp.begin(), temp.begin() + chine_len);
for(int i = 1; i < src_chain.size(); i++) {
b.assign(temp.begin() + i, temp.begin() + chine_len + i);
if (compare_chain(a, b)) {
a.assign(b.begin(), b.end());
}
}
nor_chain = a;
return nor_chain;
}
(2) 由于角度的不同,造成编码的不同怎么办?
循环差分取:chain_code[i+1] - chain_code[i] + 模(4)) % 模(4)