视线语音鼠标 7 人脸检测-形态学运算

腐蚀,膨胀为基础,有开运算,闭运算两种。

我用的样本是5*5的,腐蚀(膨胀)说白了就是只要这个点是0(1),周围5*5的就都是0(1)。

做两次形态学运算。

先腐蚀,后膨胀。

然后再先膨胀,后腐蚀。用以去除噪声。

最后用floodfill做连通块,并根据矩形的大小及长宽比进行判定。

至此,我们简单的人脸检测完毕。

public void Cal(int[,] Seg, out int[,] Seg1, out int l, out int r, out int u, out int d) { int iWidth = Seg.GetLength(0); int iHeight = Seg.GetLength(1); Seg1 = new int[iWidth, iHeight]; //第一次先腐蚀,后膨胀 for (int i = 0; i < iWidth; i++) for (int j = 0; j < iHeight; j++) Seg1[i, j] = Seg[i, j]; for (int i = 0; i < iWidth; i++) for (int j = 0; j < iHeight; j++) if (Seg[i, j] == 0) { for (int x = -2; x <= 2; x++) for (int y = -2; y <= 2; y++) { if (x == 0 && y == 0) continue; int tx = i + x; int ty = j + y; if (0 <= tx && tx < iWidth && 0 <= ty && ty < iHeight) Seg1[tx, ty] = 0; } } for (int i = 0; i < iWidth; i++) for (int j = 0; j < iHeight; j++) Seg[i, j] = Seg1[i, j]; for (int i = 0; i < iWidth; i++) for (int j = 0; j < iHeight; j++) if (Seg[i, j] == 1) { for (int x = -2; x <= 2; x++) for (int y = -2; y <= 2; y++) { if (x == 0 && y == 0) continue; int tx = i + x; int ty = j + y; if (0 <= tx && tx < iWidth && 0 <= ty && ty < iHeight) Seg1[tx, ty] = 1; } } //第二次先膨胀,后腐蚀 for (int i = 0; i < iWidth; i++) for (int j = 0; j < iHeight; j++) Seg[i, j] = Seg1[i, j]; for (int i = 0; i < iWidth; i++) for (int j = 0; j < iHeight; j++) if (Seg[i, j] == 1) { for (int x = -2; x <= 2; x++) for (int y = -2; y <= 2; y++) { if (x == 0 && y == 0) continue; int tx = i + x; int ty = j + y; if (0 <= tx && tx < iWidth && 0 <= ty && ty < iHeight) Seg1[tx, ty] = 1; } } for (int i = 0; i < iWidth; i++) for (int j = 0; j < iHeight; j++) Seg[i, j] = Seg1[i, j]; for (int i = 0; i < iWidth; i++) for (int j = 0; j < iHeight; j++) { if (Seg[i, j] == 0) { for (int x = -2; x <= 2; x++) for (int y = -2; y <= 2; y++) { if (x == 0 && y == 0) continue; int tx = i + x; int ty = j + y; if (0 <= tx && tx < iWidth && 0 <= ty && ty < iHeight) Seg1[tx, ty] = 0; } } } l = 0;r = 0;u = 0;d = 0; //连通块及判定 bool[,] v = new bool[iWidth, iHeight]; int left, right, up, down; int cnt = 0; for (int i = 0; i < iWidth; i++) for (int j = 0; j < iHeight; j++) { if (!v[i, j] && Seg1[i, j] > 0) { left = 160; right = 0; up = 120; down = 0; floodfill(i, j, ++cnt, ref Seg1, ref v, ref left, ref right, ref up, ref down); int w = right - left; int h = down - up; double ratio = (double)h/(double)w; System.Console.WriteLine(ratio.ToString()); if (h > 30 && w > 20 && ratio > 1.1 && ratio < 1.9) { l = left; r = right; u = up; d = down; break; } } } } int[] dx = {0,1,0,-1}; int[] dy = {1,0,-1,0}; void floodfill(int x, int y, int cnt, ref int[,] Seg1, ref bool[,] v, ref int left, ref int right, ref int up, ref int down) { int iWidth = v.GetLength(0); int iHeight = v.GetLength(1); v[x, y] = true; Seg1[x, y] = cnt; for (int k = 0; k < 4; k++) { int i = x + dx[k]; int j = y + dy[k]; if (i > 0 && i < iWidth && j > 0 && j < iHeight && Seg1[i, j] > 0 && !v[i, j]) { if (left > i) left = i; if (right < i) right = i; if (up > j) up = j; if (down < j) down = j; floodfill(i, j, cnt, ref Seg1, ref v, ref left, ref right, ref up, ref down); } } }

 

你可能感兴趣的:(视线语音鼠标 7 人脸检测-形态学运算)