最近在做一個Motion Detection的課題,在課題中提取的運動物體往往由離散的點組成,如果要用連通分量的計算方法提取每個運動物體的輪廓不太容易,爲此要將由離散點組成的圖像進行膨脹,腐蝕運算。
膨脹 dilation
考慮兩幅二值圖像A,B。它們的前景用黑色,背景用白色。另fA和fB表示各自前景點的集合。定義膨脹運算爲:dilation(A,B) = {a+b| a∈A,b∈B}。比如:
A = {(2,8),(3,6),(4,4),(5,6),(6,4),(7,6),(8,8)}
B = {(0,0),(0,1)}
dilation(A,B) = {(2,8),(2,9),(3,6),(3,7),(4,4),(4,5),(5,6),(5,7),(6,4),(6,5),(7,6),(7,7),(8,8),(8,9)}
腐蝕 erosion
同樣考慮兩幅圖像A,B。定義腐蝕運算爲: erosion(A,B) = {a|(a+b)∈A, a∈A,b∈B}
膨脹腐蝕運算的性質
•交換律 dilation(A,B) = dilation(B,A)
•結合律 dilation(dilation(A,B),C) = dilation(A,dilation(B,C))
•並集 dilation(A,B∪C) = dilation(A,B)∪dilation(A,C)
•增長性 if A blongs to B then dilation(A,K) blongs to dilation(B,K)
C++ 實現
這裏 buf 相當於 A,model相當於B 計算dilation(buf,model)
void ShapeOper::dilation(unsigned char* buf, int width, int height, vector<point> model)
{
int i,j,k;
point P;
unsigned char* temp = new unsigned char[width*height];
memcpy(temp,buf,width*height);
for(i=0;i<height;i++){
for(j=0;j<width;j++){
if(temp[(i*width+j)] < 10){
for(k=0;k<model.size();k++){
P.x = i + model[k].x; //Dilation Operation 求取並集
P.y = j + model[k].y;
if(P.x>=0 && P.x<width && P.y>=0 && P.y<height){
buf[(P.x*width+P.y)] = 0;
}
}
}
}
}
if(temp!=NULL){
delete[] temp;
}
}
計算erosion(buf,model)
void ShapeOper::erosion(unsigned char* buf, int width, int height, vector<point> model)
{
int i,j,k;
point P;
unsigned char* temp = new unsigned char[width*height];
memcpy(temp,buf,width*height);
bool is_point = true;
for(i=0;i<height;i++){
for(j=0;j<width;j++){
if(temp[(i*width+j)] < 10){
is_point = true;
for(k=0;k<model.size();k++){
P.x = i + model[k].x;
P.y = j + model[k].y;
if(P.x>=0 && P.x<width && P.y>=0 && P.y<height){
if(temp[(P.x*width+P.y)] > 10){
is_point = false;
//cout<<"other"<<endl;
break;
}
}
}
if(is_point){
buf[(i*width+j)] = 0;
}
}
}
}
if(temp!=NULL){
delete[] temp;
}
}
本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/xlvector/archive/2006/01/26/588828.aspx