圖像處理距離變換算法


距離

定義

  滿足以下函數條件
  D(p,q)>=0,當且僅當p=q時D(p,q)=0;
        D(p,q)=D(q,p)
  D(p,r)<=D(p,q)+D(q,r)

歐式距離

  D[(i,j),(k,h)]=((i-k)^2+(j-h)^2)^(1/2);

城市街區距離

  只允許橫向以及縱向的移動
  D[(i,j),(k,h)]=|i-k|+|j-h|;

棋盤距離

  允許橫向、縱向以及對角線上的移動
  D[(i,j),(k,h)]=max{|i-k|,|j-h|}

算法實現

步驟

  1.按照一種距離度量D,D是D4或D8,對大小為M*N的圖像的一個子集S計算距離變換,建立一個M*N的數組F並作初始化:子集S中元素置為0,
    其他置為無窮。
  2.按行遍歷圖像,從上到下,從左到右。對於上方和左面的鄰接像素設F(p)=min[F(p),D(p,q)+F(q)]。
  3.按行遍歷圖像,從下到上,從右到左。對於下方和右面的鄰接像素設F(p)=min[F(p),D(p,q)+F(q)]。
  4.數組F中得到的是子集S的斜切。

具體函數

初始化函數
  void DistanceTransformD4(vector<vector<int>> &src, vector<vector<int>> &f)
  {
      int cols = src[0].size();
      int rows = src.size();

      //初始化
      for (int i = 0; i < rows; ++i)
      	for (int j = 0; j < cols; ++j)
      		if (src[i][j] == 1)
      		      f[i][j] = 0;
      		else
      		      f[i][j] = INT_MAX - 2;//簡單的防止溢出
      //按行遍歷圖像,從上到下,從左到右
      for (int i = 0; i < rows; ++i)
      	for (int j = 0; j < cols; ++j)
      		D4AL(i, j, rows, cols, f);
  
      //按行遍歷圖像,從下到上,從右到左
      for (int i = rows - 1; i >= 0; --i)
      	for (int j = cols - 1; j >= 0; --j)
	      	D4BR(i, j, rows, cols, f);
  }
左變換函數
  void D4AL(int i,int j, int rows, int cols, vector<vector<int>> &f)
  {
      //上
      if (InArea(i - 1, j, rows, cols))
      	      f[i][j] = min(f[i][j], 1 + f[i - 1][j]);
      //左上
      if (InArea(i - 1, j - 1, rows, cols))
	      f[i][j] = min(f[i][j], 2 + f[i - 1][j - 1]);
      //左
      if (InArea(i, j - 1, rows, cols))
	      f[i][j] = min(f[i][j], 1 + f[i][j - 1]);
      //左下
      if (InArea(i + 1, j - 1, rows, cols))
	      f[i][j] = min(f[i][j], 2 + f[i + 1][j - 1]);
  }
右變換函數
  void D4BR(int i, int j, int rows, int cols, vector<vector<int>> &f)
  {
      //下
      if (InArea(i + 1, j, rows, cols))
	      f[i][j] = min(f[i][j], 1 + f[i + 1][j]);
      //右下
      if (InArea(i + 1, j + 1, rows, cols))
	      f[i][j] = min(f[i][j], 2 + f[i + 1][j + 1]);
      //右
      if (InArea(i, j + 1, rows, cols))
	      f[i][j] = min(f[i][j], 1 + f[i][j + 1]);
      //右上
      if (InArea(i - 1, j + 1, rows, cols))
	      f[i][j] = min(f[i][j], 2 + f[i - 1][j + 1]);
  }
判斷是否出界函數
  bool InArea(int i, int j, int rows, int cols)
  {
        if (i<0 || i>=rows)
              return false;
        if (j<0 || j>=cols)
              return false;
        return true;
  }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM