/// <summary> /// Deform snake in the given external force field with pressure force added /// </summary> /// <param name="x">轮廓-X</param> /// <param name="y">轮廓-Y</param> /// <param name="alpha">elasticity parameter</param> /// <param name="beta">rigidity parameter</param> /// <param name="gamma">viscosity parameter</param> /// <param name="kappa">external force weight</param> /// <param name="kappap">pressure force weight</param> /// <param name="fx">external force field (x)</param> /// <param name="fy">external force field (y)</param> /// <param name="ITER"></param> public void SnakeDeform2(ref NcvVector x, ref NcvVector y, double alpha, double beta, double gamma, double kappa, double kappap, double[] fx, double[] fy, int ITER) { int n = x.n; NcvVector vecAlpha = alpha * NcvVector.Ones(n); NcvVector vecBeta = beta * NcvVector.Ones(n); // produce the five diagnal vectors NcvVector alpham1 = NcvVector.cat(vecAlpha.sub(1, n - 1), vecAlpha.sub(0, 1)); NcvVector alphap1 = NcvVector.cat(vecAlpha.sub(n - 1, 1), vecAlpha.sub(0, n - 1)); NcvVector betam1 = NcvVector.cat(vecBeta.sub(1, n - 1), vecBeta.sub(0, 1)); NcvVector betap1 = NcvVector.cat(vecBeta.sub(n - 1, 1), vecBeta.sub(0, n - 1)); NcvVector a = betam1; NcvVector b = -vecAlpha - 2 * vecBeta - 2 * betam1; NcvVector c = vecAlpha + alphap1 + betam1 + 4 * vecBeta + betap1; NcvVector d = -alphap1 - 2 * vecBeta - 2 * betap1; NcvVector e = betap1; // generate the parameters matrix NcvMatrix A = NcvMatrix.diag(a.sub(0, n - 2), -2) + NcvMatrix.diag(a.sub(n - 2, 2), n - 2); A = A + NcvMatrix.diag(b.sub(0, n - 1), -1) + NcvMatrix.diag(b.sub(n - 1, 1), n - 1); A = A + NcvMatrix.diag(c); A = A + NcvMatrix.diag(d.sub(0, n - 1), 1) + NcvMatrix.diag(d.sub(n - 1, 1), -(n - 1)); A = A + NcvMatrix.diag(e.sub(0, n - 2), 2) + NcvMatrix.diag(e.sub(n - 2, 2), -(n - 2)); NcvMatrix invAI = NcvMatrix.inv(A + gamma * NcvMatrix.diag(NcvVector.Ones(n))); for (int count = 0; count < ITER; count++) { NcvVector vfx = NcvVector.interp2(fx, m_Cols, m_Rows, x, y, "*linear"); NcvVector vfy = NcvVector.interp2(fy, m_Cols, m_Rows, x, y, "*linear"); // adding the pressure force NcvVector xp = NcvVector.cat(x.sub(1, n - 1), x.sub(0, 1)); NcvVector yp = NcvVector.cat(y.sub(1, n - 1), y.sub(0, 1)); NcvVector xm = NcvVector.cat(x.sub(n - 1, 1), x.sub(0, n - 1)); NcvVector ym = NcvVector.cat(y.sub(n - 1, 1), y.sub(0, n - 1)); NcvVector qx = xp - xm; NcvVector qy = yp - ym; NcvVector pmag = NcvVector.Sqrt(NcvVector.DotProduct(qx, qx) + NcvVector.DotProduct(qy, qy)); NcvVector px = NcvVector.DotDivide(qy, pmag); NcvVector py = NcvVector.DotDivide(-qx, pmag); // deform snake x = invAI * (gamma * x + kappa * vfx + kappap * px); y = invAI * (gamma * y + kappa * vfy + kappap * py); } }
////////////////////////////////////////////////////////// // DT apply Eucledian distance transform // D = dt(B) compute the Eucledian distance transform of B // B must be a binary map. // NOTE: this is not an efficient way to implement distance transform. // If one is interested in using DT, one may want to implement its // own DT. private static double[,] dt(NcvMatrix B) { //[i,j] = find(B); int m = B.Cols; int n = B.Rows; for (int x = 0; x < n; x++) { for (int y = 0; y < m; y++) { //dx = i-x; //dy = j-y; //dmag = sqrt(dx.*dx+dy.*dy); //D(x,y) = min(dmag); } } return(null); }
public void InitGVF() { NcvMatrix f = new NcvMatrix(m_Cols, m_Rows); u = new NcvMatrix(m_Cols, m_Rows); v = new NcvMatrix(m_Cols, m_Rows); Console.WriteLine(" Compute edge map ..."); for (int y = 0; y < m_Rows; y++) { for (int x = 0; x < m_Cols; x++) { f[x, y] = 1 - mat[x][y] / 255.0; } } //Logger.Info("f=" + f.ToString()); Console.WriteLine(" Compute GVF ..."); GvfSnakeUtility.GVFC(m_Rows, m_Cols, f, ref u, ref v, 0.2, 80); //Logger.Info("u=" + u.ToString()); //Logger.Info("v=" + v.ToString()); Console.WriteLine(" Nomalizing the GVF external force ..."); px = new double[m_Cols * m_Rows]; py = new double[m_Cols * m_Rows]; mag = new NcvMatrix(m_Cols, m_Rows); for (int y = 0; y < m_Rows; y++) { for (int x = 0; x < m_Cols; x++) { int i = x * m_Rows + y; mag[x, y] = System.Math.Sqrt(u[x, y] * u[x, y] + v[x, y] * v[x, y]); px[i] = u[x, y] / (mag[x, y] + 1e-10); py[i] = v[x, y] / (mag[x, y] + 1e-10); } } //Logger.Info("px=" + px.ToString()); //Logger.Info("px=" + px.ToString()); }
public static Bitmap SharpenMore(Bitmap bmp) { int width, height; int[][] mat, filtered; Bitmap newBmp; ImageConvert.Bitmap2Mat(bmp, out mat, out width, out height); Convolution conv = new Convolution(); conv.Calculate(mat, ConvKernel.Laplacian_8, out filtered); NcvMatrix.MatSubtract(mat, filtered); GrayScaleImageLib.Normalize(mat); ImageConvert.Mat2Bitmap(mat, width, height, out newBmp); return(newBmp); }
/// <summary> /// foamliu, 2009/02/02, 彩色图片旋转. /// </summary> /// <param name="bmp"></param> /// <param name="alpha">旋转角度(弧度)</param> /// <param name="bi">bilinear interpolation (双线性插值)</param> /// <returns></returns> public static Bitmap Rotate(Bitmap bmp, double alpha, bool bi) { int width, height; int[][][] img, newImg; Bitmap newBmp; ImageConvert.Bitmap2MatColor(bmp, out img, out width, out height); newImg = Util.BuildMatIntColor(width, height); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { if (!bi) { double[] input = new double[] { y, x, 1 }; double[] output = NcvMatrix.RotateInvert(input, alpha); int oldY = (int)Math.Round(output[0]); int oldX = (int)Math.Round(output[1]); if (Util.InRect(oldX, oldY, width, height)) { // RGB newImg[0][x][y] = img[0][oldX][oldY]; newImg[1][x][y] = img[1][oldX][oldY]; newImg[2][x][y] = img[2][oldX][oldY]; } } else { // p00 ------------- p01 // | | // p10 ------------- p11 // // 双线性插值需要更长的计算时间 (原来的5倍以上) // double[] input = new double[] { y, x, 1 }; double[] output = NcvMatrix.RotateInvert(input, alpha); double newY = output[0]; double newX = output[1]; int p00Y = (int)Math.Floor(newY); int p00X = (int)Math.Floor(newX); int p01Y = (int)Math.Floor(newY); int p01X = (int)Math.Ceiling(newX); int p10Y = (int)Math.Ceiling(newY); int p10X = (int)Math.Floor(newX); int p11Y = (int)Math.Ceiling(newY); int p11X = (int)Math.Ceiling(newX); if (Util.InRect(p00X, p00Y, width, height) && Util.InRect(p01X, p01Y, width, height) && Util.InRect(p10X, p10Y, width, height) && Util.InRect(p11X, p11Y, width, height)) { double a = newY - p00Y; double b = newX - p00X; for (int c = 0; c < 3; c++) { int g00 = img[c][p00X][p00Y]; int g01 = img[c][p01X][p01Y]; int g10 = img[c][p10X][p10Y]; int g11 = img[c][p11X][p11Y]; double g = b * (a * g11 + (1 - a) * g01) + (1 - b) * (a * g01 + (1 - a) * g00); newImg[c][x][y] = (byte)Math.Round(g); } } } } } ImageConvert.Mat2BitmapColor(newImg, width, height, out newBmp); return newBmp; }
public static NcvMatrix BoundMirrorExpand(NcvMatrix A) { return(new NcvMatrix(BoundMirrorExpand(A.Data, A.cols(), A.rows()))); }
private static double[,] Xconv2(NcvMatrix I, NcvMatrix M) { throw new NotImplementedException(); }